Запрос на прерывание по сигналу аварийного датчика. Прерывания от сигнала аварийного датчика включают на пульте управления аварийную сигнализацию (звуковая 500 Гц) и обеспечивают выдачу в область связи с ПК сигналов дискретных датчиков x1, …, x4, среднего значения Тср (задача 1.5), значения констант K и Q, значение датчиков L1, L2 (см. 1.7). После выполнения указанных действий требуется контроллер перевести в ждущий режим.
Алгоритм реализации:
Прерывание по сигналу отказа источника питания:
. Импульсы длительностью 30 мкс реализуются программным образом.
. Переход в ждущий режим.
Прерывание по сигналу аварийного датчика:
. Запускается таймер управляющий звуковой сигнализацией
(прерывания таймера более приоритетные чем прерывание по сигналу аварийного датчика).
. Осуществляется передача в последовательный канал связи информации о состоянии системы.
. Переход в ждущий режим.
Код на ASM:
$mod812_Ext0:
; Прерывание по сигналу отказа источника питания
setb Y6R7, #14_set0:R7, pause_set0Y6R7, #14_clr:R7, pause_clrY6R7, #14_set1:R7, pause_set1Y6Wait_Regim_Timer0:.4_Port_Value_Ext1:H, #0f8hL, #030h,#0f8h,#030h_Wait:, iE1_Wait_Infowait_regim_Timer1:, it1_next0
; 1 насос работает, (PTime1+3), #01h(PTime1+3), A_next0, (PTime1+2), #01h(PTime1+2), A_next0, (PTime1+1), #01h(PTime1+1), A_next0, (PTime1+0), #01h(PTime1+0), A_next0:, it1_next1
; 2 насос
работает,
(PTime2+3), #01h(PTime2+3), A_next1, (PTime2+2), #01h(PTime2+2), A_next1,
(PTime2+1), #01h(PTime2+1), A_next1, (PTime2+0), #01h(PTime2+0),
A_next1:_Timer2:, Port_tmp_Port_Value_regim:wait_regim
Рисунок 17.
Временная оценка: 129мкс
9. Алгоритм гибкого управления объектом
Данный алгоритм должен обеспечить закон гибкого управления по состоянию объекта. Требуется разработать алгоритм и программу управления насосной станцией осушительной системы, состоящей из двух насосных агрегатов Р1 и Р2 и двух датчиков контроля уровня воды. Насосы работают по следующему закону управления объектом:
датчик L1 - при L1=0 насосы не включаются, а при L1=1 включается насос, имеющий меньшее количество наработанных часов;
датчик L2 - данный датчик срабатывает при дальнейшем повышении уровня воды, при L2=1 включается второй насос и начинают работать уже оба насоса. При L2=0, т.е. понижении уровня воды, один из насосов выключается и продолжает работать насос с меньшим количеством наработанных часов, т.е. требуется обеспечить подсчет и сравнение времени работы насосов. Когда уровень воды понизится и L1=0, то последний работающий насос также выключается.
Время работы насосов подсчитывается с помощью таймера. Таймер установлен на максимально длительное время. По прерываниИ для работающего насоса на единицу увеличивается наработанное время.
Алгоритм реализации:
Рисунок 18.
Пример кода на ASM:
$mod812, n_Proverka, n_P2
; Насосы отключены, n_State0_Exit_State0:1, n_Exit
; Выбор насоса для включения
movA, (PTime1+3), (PTime2+3), n_select0, (PTime1+2), (PTime2+2), n_select0, (PTime1+1), (PTime2+1), n_select0, (PTime1+0), (PTime2+0), n_select0
n_select0:_onP10; 2 насос отработал меньше -> включение
jmpn_Exit
n_onP10:; 1 насос отработал меньше -> включение
jmpn_Exit_Proverka:, n_P1
; Работают оба насоса
jbL1,n_State1
clrPump1_Exit_State1:
jbL2, n_Exit
; Выбор насоса для отключения
movA, (PTime1+3), (PTime2+3), n_select1, (PTime1+2), (PTime2+2), n_select1, (PTime1+1), (PTime2+1), n_select1, (PTime1+0), (PTime2+0), n_select1
n_select1:_onP11; 1 насос отработал больше -> выключение
jmpn_Exit
jmpn_Exit
n_P1:
; Работает 1 насос
jbL1, n_State2_Exit_State2:, n_Exit_Exit
n_P2:
; Работает 2 насос
jbL1,
n_State3_Exit_State3:, n_Exit_Exit_Exit:
Рисунок 19.
Временная оценка: 327мкс
10. Таблица портов и адресов
|
Порт/адрес |
Функция |
|
P0.0 |
key_line_1 |
|
P0.1 |
key_line_2 |
|
P0.2 |
key_line_3 |
|
P0.3 |
key_line_4 |
|
P0.4 |
X1 |
|
P0.5 |
X2 |
|
P0.6 |
X3 |
|
P0.7 |
X4 |
|
P1.0 |
U1 |
|
P1.1 |
U2 |
|
P1.2 |
T1 |
|
P1.3 |
T2 |
|
P1.4 |
T3 |
|
P1.5 |
L1 |
|
P1.6 |
L2 |
|
P1.7 |
u_motor_sensor |
|
P2.0 |
key_column_1 |
|
P2.1 |
key_column_2 |
|
P2.2 |
key_column_3 |
|
P2.3 |
key_column_4 |
|
P2.4 |
key_column_5 |
|
P2.5 |
Out_data |
|
P2.6 |
Out_sh |
|
P2.7 |
Out_st |
|
P3.0 |
- |
|
P3.1 |
- |
|
P3.2 |
INT0 |
|
P3.3 |
INT1 |
|
P3.4 |
DSR |
|
P3.5 |
DTR |
|
P3.6 |
Y6 |
|
P3.7 |
Y2 |
|
0x20 |
key_old |
|
0x21 |
key_old |
|
0x22 |
key_old |
|
0x23 |
key_old |
|
0x24 |
K_tmp |
|
0x25 |
Port |
|
0x26 |
Port_tmp |
|
0x27 |
Flags |
|
0x30 |
K |
|
0x31 |
Q |
|
0x32 |
Tmin |
|
0x33 |
Tmax |
|
0x34 |
Tm (массив) |
|
0x35 |
Tm |
|
0x36 |
Tm |
|
0x37 |
Tsr |
|
0x38 |
Nu1 |
|
0x39 |
Nu2 |
|
0x40 |
PTime1 - 4 байта |
|
0x44 |
Ptime2 - 4 байта |
11. Временная оценка
Время выполнения отдельных частей кода
|
Подпрограмма |
Время |
|
Подготовка, инициализация |
27 мкс |
|
Чтение клавиатуры |
45 мкс |
|
Выполнение символа с клавиатуры |
8 мкс |
|
Запуск АЦП |
41 мкс |
|
Обработка датчиков ДД |
18 мкс |
|
Обработка аналоговых датчиков |
33 мкс |
|
Управление двигателем |
14 мкс |
|
Обработка значений температуры |
39 мкс |
|
Всего |
225 мкс |
. Исходный текст программы
$mod812
;============ Распределение портов ============
; P0.0 - key_line_1
; P0.1 - key_line_2
; P0.2 - key_line_3
; P0.3 - key_line_4_linedataP0
; P0.4 - X1bitP0.4
; P0.5 - X2bitP0.5
; P0.6 - X3bitP0.6
; P0.7 - X4bitP0.7
; P1.0 - U1 (Analog in)
; P1.1 - U2 (Analog in)
; P1.2 - T1 (Analog in)
; P1.3 - T2 (Analog in)
; P1.4 - T3 (Analog in)
; P1.5 - L1bitP1.5
; P1.6 - L2bitP1.6
; P1.7 - u_motor_sensor_usensorbitP1.7
; P2.0 - key_column_1
; P2.1 - key_column_2
; P2.2 - key_column_3
; P2.3 - key_column_4
; P2.4 - key_column_5_portdataP2
; P2.5 - Out_data_databitP2.5
; P2.6 - Out_sh_shbitP2.6
; P2.7 - Out_st_stbitP2.7
; P3.0 -
; P3.1 -
; P3.2 - INT0
; P3.3 - INT1
; P3.4 - DSR.4
; P3.5 - DTR.5
; P3.6 - Y6bitP3.6
; P3.7 - Y2bitP3.7
;======== Распределение адресов памяти ========_olddata20h ; Занимает адреса 20h-23h
M_start_key_pressbit22h.3_stop_key_pressbit22h.4_key_pressbit23h.4_tmpdata24hh_tmpdata26hbitPort_tmp.0bitPort_tmp.1bitPort_tmp.2bitPort_tmp.3_tmp.4bitPort_tmp.5bitPort_tmp.6_controlbit Port_tmp.727h
FBusyPortbitFlags.0
; Технологические константы и переменныеh
Qdata31h
Tmindata32hhh; Массив из 3-х элементов (адреса 34h-36h)
Tsrdata37hdata38hdata39hdata40h; Занимает 4 байта (40h - 43h)data44h; Занимает 4 байта (44h - 47h) Init
;======== Вектора обработка прерываний ========03hint_Ext0
org 0bhint_Timer013hint_Ext11bhint_Timer12bhint_Timer250h
;========== Начальная инициализация ===========:
; Setup stack pointerSP, #0c0h
; Init Pins_line, #0ffh; P0_port, #1fh; P2, #00h,#00h
; Enable Interrupt,#8fh
; Init Ext0, Ext1, #05h
; Init ADC, #44h ;#7ch
; Init Timer, #11h.6
; Init Uart:
============Обработка информации с дискретных датчиков==============
mov A, P0A
jc d_Set
rlc A
jnc d_Clr
rlc A
jc d_Clr
rlc A
jc d_Clr
d_Set:
setb Y1
movPort, Port_tmp
callSend_Port_Value, Port_tmp
; Запуск таймера, #11000100B, #00000001B.4
jmp d_Exit
d_Clr:
clrY1
d_Exit:
===============Обработка информации с аналоговых датчиков===============
movADCCON2, #10h
callAdc_Wait, A; Значение с первого датчика
movADCCON2, #11h
callAdc_Wait, A; Значение со второго датчика
; Реализация функции min (Nu1, Nu2 + K)
clrC, K, A, Nu1_Nu1, R0; Nu2 + K < Nu1_Next_Nu1:CA, Nu1; Nu1 < Nu2 + K
a_Next:
; Сравнение min значения с Q
subbA, Q_Q
; Q < min
; Запуск таймера, #11101100b, #01110100b.4_Exit_Q:
; Q > minY2wait_20us_20us:
a_Exit:
=======Управление технологическим параметром в заданных пределах==============
movADCCON2, #12h
callAdc_Wait(Tm+0), A; Значение температуры с первого датчика
movADCCON2, #13h
callAdc_Wait(Tm+1), A; Значение температуры со второго датчика
movADCCON2, #14h
callAdc_Wait(Tm+2), A; Значение температуры с третьего датчика
; Инициализация регистров используемых в цикле, #03h
movR1, #Tm
movR2, #00h
; Цикл обработки массива из 3 элементов (нахождение среднего арифметического)
t_Loop:, @R1, #03h, R2, A0, t_Loop, A; Занесение полученного значения в память
; Сравнение средней температуры с граничными значениями, Tmin_Low; Температура ниже нормы
clrC
movA, Tsr
subbA, Tmax_Hi; Температура выше нормы; Выключили охладитель; Выключили нагреватель
jmpt_Exit
t_Low:; Выключили охладитель; Включили нагреватель
jmpt_Exit
t_Hi:; Включили охладитель; Выключили нагреватель_Exit:
===========Управление пуском - остановом электродвигателя=============== _usensor, m_Stop ; Нет питания-> остановка_stop_key_press,m_Stop ; Нажата кнопка остановки-> остановка_start_key_press,m_Exit ; Кнопка пуска отпущена -> состояние
не изменяется
; Запуск двигателя_control
jmpm_Exit
m_Stop:
; Остановка двигателя_control_Exit:
===============Алгоритм гибкого управления объектом====================
jbPump1, n_Proverka, n_P2
; Насосы отключены, n_State0_Exit_State0:
jnbL1, n_Exit
; Выбор насоса для включения
movA, (PTime1+3), (PTime2+3), n_select0, (PTime1+2), (PTime2+2), n_select0, (PTime1+1), (PTime2+1), n_select0, (PTime1+0), (PTime2+0), n_select0
n_select0:_onP10; 2 насос отработал меньше -> включение
jmpn_Exit
n_onP10:; 1 насос отработал меньше -> включение
jmpn_Exit_Proverka:, n_P1
; Работают оба насоса
jbL1,n_State1
clrPump1_Exit_State1:
jbL2, n_Exit
; Выбор насоса для отключения
movA, (PTime1+3), (PTime2+3), n_select1, (PTime1+2), (PTime2+2), n_select1, (PTime1+1), (PTime2+1), n_select1, (PTime1+0), (PTime2+0), n_select1
n_select1:_onP11; 1 насос отработал больше -> выключение
jmpn_Exit
n_onP11:; 2 насос отработал меньше -> выключение
jmpn_Exit
n_P1:
; Работает 1 насос
jbL1, n_State2_Exit_State2:, n_Exit_Exit
n_P2:
; Работает 2 насос
jbL1, n_State3_Exit_State3:, n_Exit_Exit
n_Exit:
;========================= Отправка порта =========================
movPort, Port_tmp, p_Exit_Port_Value_Exit:
;========================= Цикл остановки =========================
l_wait:
callUart_Process_Process; Опрос/Обработка клавиатурыstop_key_press, l_wait
jmp Main
; Ожидание получения значения с АЦП
Adc_Wait:_Adc:, ADCCON3A_Adc, ADCDATAH, #0fh, A, ADCDATAL, #0f0h, R0
; Отсылка значения порта на сдвиговый регистр
Send_Port_Value:, Port_data, C_sh_sh_data, C_sh_sh_data, C_sh_sh_data, C_sh_sh_data, C_sh_sh_data, C_sh_sh_data, C_sh_sh_data, C_sh_sh_st_st
; Режим ожидания_Regim:Wait_Regim
===================Обработчики прерываний============================
int_Ext0:
; Прерывание по сигналу отказа источника питания
setb Y6R7, #14_set0:R7, pause_set0Y6R7, #14_clr:R7, pause_clrY6R7, #14_set1:R7, pause_set1Y6Wait_Regim_Timer0:.4_Port_Value_Ext1:H, #0f8hL, #030h,#0f8h,#030h_Wait:, iE1_Wait_Infowait_regim_Timer1:, it1_next0
; 1 насос работает, (PTime1+3), #01h(PTime1+3), A_next0, (PTime1+2), #01h(PTime1+2), A_next0, (PTime1+1), #01h(PTime1+1), A_next0, (PTime1+0), #01h(PTime1+0), A_next0:, it1_next1
; 2 насос работает, (PTime2+3), #01h(PTime2+3), A_next1, (PTime2+2), #01h(PTime2+2), A_next1, (PTime2+1), #01h(PTime2+1), A_next1, (PTime2+0), #01h(PTime2+0), A_next1:_Timer2:, Port_tmp_Port_Value
=====================Функция опроса/обработки клавиатуры==================
Key_Process:
mov A, K_tmp
; Опрос/Обработка 1 линии
xrlkey_line, #01h, key_port.0, not_k1(key_old+0).0, not_k1
; Нажата клавиша 1, #0f0h, #01h_k1:.1, not_k2(key_old+0).1, not_k2
; Нажата клавиша 2, #0f0h, #02h_k2:.2, not_k3(key_old+0).2, not_k3
; Нажата клавиша 3, #0f0h, #03h_k3:.3, not_kC(key_old+0).3, not_kC
; Нажата клавиша C, #0f0h, #0ch_kC:.4, not_kD(key_old+0).4, not_kD
; Нажата клавиша D, #0f0h, #0dh_kD:_old+0, B
; Опрос/Обработка 2 линии
xrlkey_line, #03h, key_port.0, not_k4(key_old+1).0, not_k4
; Нажата клавиша 4, #0f0h, #04h_k4:.1, not_k5(key_old+1).1, not_k5
; Нажата клавиша 5, #0f0h, #05h_k5:.2, not_k6(key_old+1).2, not_k6
; Нажата клавиша 6, #0f0h, #06h_k6:.3, not_kE(key_old+1).3, not_kE
; Нажата клавиша E, #0f0h, #0eh_kE:.4, not_kF(key_old+1).4, not_kF
; Нажата клавиша F, #0f0h, #0Fh_kF:_old+1, B
; Опрос/Обработка 3 линии
xrlkey_line, #06h, key_port.0, not_k7(key_old+2).0, not_k7
; Нажата клавиша 7, #0f0h, #07h_k7:.1, not_k8(key_old+2).1, not_k8
; Нажата клавиша 8, #0f0h, #08h_k8:.2, not_k9(key_old+2).2, not_k9
; Нажата клавиша 9, #0f0h, #09h_k9:
movkey_old+2, B
; Опрос/Обработка 4 линии
xrlkey_line, #0ch, key_port.0, not_kA(key_old+3).0, not_kA
; Нажата клавиша A, #0f0h, #0ah_kA:.1, not_k0(key_old+3).1, not_k0
; Нажата клавиша 0, #0f0h, #00h_k0:.2, not_kB(key_old+3).2, not_kB
; Нажата клавиша B, #0f0h, #0bh_kB:.3, not_kI(key_old+3).3, not_kI
; Нажата клавиша I, A_kI:_old+3, B_line, #08hK_tmp, A
end