Микропроцессорная техника. Микроконтроллер в двухпозиционном регуляторе
INCLUDE MACROS80.ASM
;
======================================================================
;
----------------------------------------------------------------------
; Константы:
;
----------------------------------------------------------------------
;
; Адреса запуска программ в ОЗУ и ПЗУ
CONST:
RAM_BASE EQU 04000h ; Адрес запуска в ОЗУ
ROM_BASE EQU 0F800h ; Адрес запуска
в ПЗУ
IO_BASE EQU 0C8h ; Адрес
програмируемого интерфейса
CT_BASE EQU 074h ; Адрес таймера
;
----------------------------------------------------------------------
; Программируемый интерфейс IO
;
----------------------------------------------------------------------
; Режимы работы программируемого интерфейса
- биты байта состояния
IOSB_SETMODE EQU 10000000b
; IO STATUS BITS
IOSB_SETCBITS EQU 00000000b
IOSB_AMODE0 EQU 00000000b
IOSB_AMODE1 EQU 00100000b
IOSB_AMODE2 EQU 01000000b
IOSB_A70IN EQU 00010000b
IOSB_A70OUT EQU 00000000b
IOSB_C74IN EQU 00001000b
IOSB_C74OUT EQU 00000000b
IOSB_BMODE0 EQU 00000000b
IOSB_BMODE1 EQU 00000100b
IOSB_B70IN EQU 00000010b
IOSB_B70OUT EQU 00000000b
IOSB_C30IN EQU 00000001b
IOSB_C30OUT EQU 00000000b
; Адреса портов программируемого интерфейса
(IO)
IO_MODE_PORT EQU IO_BASE+03h ; Порт
программирования IO
IO_C_PORT EQU IO_BASE+02h
; Порт C
IO_B_PORT EQU IO_BASE+01h ; Порт
B
IO_A_PORT EQU IO_BASE+00h ; Порт
A
; Константы для работы с IO
IO_MODE =
IOSB_SETMODE+IOSB_AMODE0+IOSB_A70IN+IOSB_C74IN+IOSB_BMODE0
IO_MODE = IO_MODE+IOSB_B70OUT+IOSB_C30OUT
;
----------------------------------------------------------------------
; Таймер CT:
; ----------------------------------------------------------------------
; Режимы работы таймеров - биты байта
состояния
CTSB_TIMER0 EQU 00000000b
; CT STATUS BITS
CTSB_TIMER1 EQU 01000000b
CTSB_TIMER2 EQU 10000000b
CTSB_STOP EQU 00000000b
CTSB_LOWBYTE EQU 00010000b
CTSB_HIGHBYTE EQU 00100000b
CTSB_TWOBYTES EQU 00110000b
CTSB_MODE0 EQU 00000000b
CTSB_MODE1 EQU 00000010b
CTSB_MODE2 EQU 00000100b
CTSB_MODE3 EQU 00000110b
CTSB_MODE4 EQU 00001000b
CTSB_MODE5 EQU 00001010b
CTSB_BINCODE EQU 00000000b
CTSB_BINDECCODE EQU 00000001b
; Адреса портов таймера (CT)
CT_MODE_PORT EQU CT_BASE+03h
; Порт программирования
CT
CT_TIMER2_PORT EQU CT_BASE+02h ; Таймер
2
CT_TIMER1_PORT EQU CT_BASE+01h ; Таймер
1
CT_TIMER0_PORT EQU CT_BASE+00h ; Таймер
0
; Константы для работы с таймерами
TIMER_MODE_PORT EQU CT_MODE_PORT
TIMER_STATE_PORT EQU IO_C_PORT
TIMER0_FREQUENCY EQU 1000 ; Задание
основного тактирования по T0, Гц
TIMER0_DELAY EQU 2000000 /
TIMER0_FREQUENCY
TIMER0_MODE = CTSB_TIMER0+CTSB_TWOBYTES+CTSB_MODE2+CTSB_BINDECCODE
TIMER2_MODE =
CTSB_TIMER2+CTSB_TWOBYTES+CTSB_MODE0+CTSB_BINCODE
;
----------------------------------------------------------------------
; Прочие константы
;
----------------------------------------------------------------------
; Константы для работы с нагревателем
HEATER_MODE_PORT EQU IO_C_PORT
HEATER_STATE_PORT EQU IO_A_PORT
HEATER_ON EQU 1
HEATER_OFF EQU 0
; ======================================================================
;
----------------------------------------------------------------------
; ОСНОВНАЯ ПРОГРАММА
;
----------------------------------------------------------------------
; См. входные параметры подпрограмм
ORG RAM_BASE ; Эта программа
находится в ОЗУ
mvi a,IO_MODE ; Инициализация
контроллера ввода-вывода
out IO_MODE_PORT
xra a ; Очистка
аккумулятора
call Restart_Timer ; Запуск таймера 0
; === Работа на участке 1 (dT=-50C,
dt=5сек)
mvi a,200 ;
Начальная температура
mvi b,TIMER0_FREQUENCY * 5 SHR
4 ; Время регулировки
5 секунд
mvi c,TIMER0_FREQUENCY * 5 AND 0FFh
mvi d,TIMER0_FREQUENCY * 5 / 50 SHR 4 ; Время изменения T
mvi e,TIMER0_FREQUENCY * 5 / 50 AND 0FFh ; на 1 градус
mvi h,-1 ;
Уменьшать температуру
call reg
; === Работа на участке 2 (dT=0,
dt=5сек)
mvi a,150 ;
Начальная температура
mvi b,TIMER0_FREQUENCY * 5 SHR
4 ; Время регулировки
5 секунд
mvi c,TIMER0_FREQUENCY * 5 AND 0FFh
mvi d,0FFh ;
Время изменения температуры
mvi
e,0FFh ; велико (T = const)
mvi h,0 ;
температура постоянна
call reg
; === Работа на участке 3 (dT=-100C,
dt=2сек)
mvi a,150 ;
Начальная температура
mvi b,TIMER0_FREQUENCY * 2 SHR 4 ;
Время регулировки 2 секунды
mvi c,TIMER0_FREQUENCY * 2 AND
0FFh
mvi d,TIMER0_FREQUENCY * 2 / 100 SHR
4 ; Время изменения температуры
mvi e,TIMER0_FREQUENCY * 2 /
100 AND 0FFh ; на 1 градус
mvi h,-1 ;
Уменьшать температуру
call reg
; === Отключение нагревателя
call Off_Heater
; === Завершение программы
hlt
;
----------------------------------------------------------------------
; Подпрограммы для работы с нагревателем
;
----------------------------------------------------------------------
;
; On_Heater и Off_Heater: включить и
выключить нагреватель соответственно
; ВХОД: НЕТ
; ВЫХОД: НЕТ
; РЕГИСТРЫ: НЕ ИЗМЕНЯЕТ
; ФЛАГИ: НЕ ИЗМЕНЯЕТ
On_Heater:
push b
mov b,a
mvi a,HEATER_MODE_PORT
out HEATER_ON
mov a,b
pop b
ret
Off_Heater:
push b
mov b,a
mvi a,HEATER_MODE_PORT
out HEATER_OFF
mov a,b
ret
;
; Heater_Control: подпрограмма поддержки
заданной температуры. Если
; температура больше или равна заданной,
выключает нагреватель,
; иначе включает.
; ВХОД: a - заданная температура
; ВЫХОД: если нагреватель включен CF=1,
иначе CF=0
; РЕГИСТРЫ: НЕ ИЗМЕНЯЕТ
; ФЛАГИ: CF
Heater_Control:
push b
mov b,a
in HEATER_STATE_PORT
cmp b
jnc Temperature_Is_Normal
call On_Heater
jmp Exit_Heater_Control
Temperature_Is_Normal:
call Off_Heater
Exit_Heater_Control:
mov a,b
pop b
ret
;
----------------------------------------------------------------------
; Подпрограммы для работы с таймерами
;
----------------------------------------------------------------------
;
; Restart_Timer - запуск таймера на отсчёт
N отрезков.
; ВХОД: a - номер таймера
; b,c - число отрезков для отсчёта
для таймеров 1 или 2
; ВЫХОД: НЕТ
; РЕГИСТРЫ: НЕ ИЗМЕНЯЕТ
; ФЛАГИ: НЕ ИЗМЕНЯЕТ
Restart_Timer:
push psw
jnz IsTimer1
mvi a,TIMER0_MODE ; Инициализация таймера 0
out TIMER_MODE_PORT
mvi a,TIMER0_DELAY AND 0FFh ; Ввод
младнего байта величины задержки
out CT_TIMER0_PORT
mvi a,TIMER0_DELAY SHR 4 ; Ввод старшего байта
out CT_TIMER0_PORT
jmp Exit_Restart_Timer
IsTimer1:
dcr a
jnz IsTimer2
mvi a,TIMER1_MODE
out TIMER_MODE_PORT
mov a,c
out CT_TIMER1_PORT
mov a,b
out CT_TIMER1_PORT
jmp Exit_Restart_Timer
IsTimer2:
dcr a
jnz Exit_Restart_Timer
mvi a,TIMER2_MODE
out TIMER_MODE_PORT
mov a,c
out CT_TIMER2_PORT
mov a,b
out CT_TIMER2_PORT
Exit_Restart_Timer:
pop psw
ret
; Check_Timers - проверить, не было ли
срабатывания таймера
; ВХОД: НЕТ
; ВЫХОД: если сработал таймер 1, установит
бит 1 аккумулятора,
; если таймер 2 - бит 2 (т.е. 1 -
таймер 1, 2 - таймер 2)
; кроме того, если таймер сработал,
установит флаг CF
; ФЛАГИ: CF
Check_Timers:
stc
push b
push psw
in TIMER_STATE_PORT
ani 11000000b
jnz TimeOut
pop psw
pop b
cmc
ret
TimeOut:
rlc ; Rotate bits to positions 0 and 1
rlc
mov b,a
pop psw
mov a,b
pop b
ret
;
----------------------------------------------------------------------
; Подпрограмма регулирования температуры
;
----------------------------------------------------------------------
;
; Reg: регулирование температуры
; ВХОД: a - начальная температура
; b,c - тактов таймера 0 до окончания
регулирования
; d,e - тактов таймера 0 до изменения
уставки по T
; h - направление изменения T -
+1, -1 или 0
; ВЫХОД: НЕТ
; РЕГИСТРЫ: НЕ ИЗМЕНЯЕТ
; ФЛАГИ: НЕ ИЗМЕНЯЕТ
Reg:
push b ; Сохранить все
основные регистры
push d
push h
push psw
push psw ; Запустить таймер
2 на счёт времени
mvi a,2 ; регистры b,c уже
установлены, см. ВХОД
call Restart_Timer
pop psw
push d ; Регистровую пару
(d,e) поместить в (b,c)
pop b
mov d,a ; Store temperature in d
T_Changed:
mvi a,1 ; Таймер
1...
call Restart_Timer ; ... запустить на
подсчёт времени до новой уставки
Reg_Next:
mov a,d ; Восстановим
уставку T
call Heater_Control ; Подрегулируем
температуру
call Check_Timers ; Проверим, не
сработал ли таймер
jnc Reg_Next
cpi 1
jnc Exit_Reg ; Если сработал
таймер 2 (ВРЕМЯ) - на выход
mov a,d
add h ; Иначе изменим
уставку по температуре,
mov d,a ; сохраним её
jmp T_Changed ; и перезапустим
подсчёт времени уставки
Exit_Reg:
pop psw ; restore general registers
pop h
pop d
pop b
ret
ENDALL