Код: Выделить всё
;Порт A (ЦАП)
.equ CS = 1 ;Линия CS ЦАП. Работа микросхемы разрешена при лог.0 на этой линии
.equ CLK = 4 ;Линия CLK ЦАП. Линия тактирования последовательного интерфейса ЦАП
.equ SDI = 5 ;Линия SDI ЦАП. Линия ввода данных в ЦАП.
.equ CLRS = 6 ;Линия CLRS ЦАП. При лог.0 на линии ЦАП сбрасывается (на его выходе появляется сигнал, соответствующий коду 0h)
.equ LOAD = 7 ;Линия LOAD ЦАП. Активный в нуле строб записи в регистр данных ЦАП
;Порт B (Кнопки, ЖКИ-индикатор)
.equ SELECT=0 ;Кнопка "Выбор"
.equ RIGHT=1 ;Кнопка "Вправо"
.equ UP=2 ;Кнопка "Вверх"
.equ RS=3 ;Линия выбора (0 - инструкции, 1 - данные) типа обмена с LCD \
.equ Estr=4 ;Разрешение выполнения любого цикла обмена (0 - обмен запрещен, 1 - обмен разрешен) __\ Линии управления ЖКИ-индикатором
.equ LEFT=5 ;Кнопка "Влево"
.equ ESC=6 ;Кнопка "Отмена"
.equ DOWN=7 ;Кнопка "Вниз"
;Порт С (АЦП)
.equ SCLK = 0 ;Линия SCLK АЦП. Линия тактирования последовательного интерфейса АЦП (интерфейс аналогичен SPI)
.equ RES = 1 ;Линия RESET АЦП. При лог.0 на линии АЦП сбрасывается.
.equ DRDY = 2 ;Линия DRDY АЦП. После завершения преобразования линия DRDY сбрасывается (на линии лог.0).
.equ DOUT = 3 ;Линия DOUT АЦП. Линия вывода данных из АЦП.
.equ DIN = 4 ;Линия DIN АЦП. Линия ввода данных в АЦП.
.equ RELE = 5 ;Линия управления выходом. При лог.1 на линии на выходных клеммах прибора появляется ток, при лог.0 на линии RELE
;выходная клемма "+" отключается от источника тока посредством размыкания контакта реле К1
;Порт D (Переключатели режимов работы, ЖКИ-индикатор)
.equ S1=2 ;Переключатели
.equ S2=1 ;режимов работы прибора
;Старший ниббл порта D - информационные биты D4-D7 при обмене с ЖКИ-индикатором.
.equ MaxMode = 0x0B ;Максимальное кол-во режимов в программе
.equ MaxImpl = 0x10 ;Максимальное кол-во импульсов в режиме
;Определения имен регистров и адресов переменных
.equ CurntL=0x98 ;Мл.байт значения тока (в единицах измерения АЦП), которое нужно поддерживать
.equ CurntH=0x99 ;Ст.байт значения тока (в единицах измерения АЦП), которое нужно поддерживать
.equ DACL=0x9A ;Мл.байт уставки ЦАП для заданного значения тока
.equ DACH=0x9B ;Ст.байт уставки ЦАП для заданного значения тока
.equ Level=0x9C ;Уставка значения тока в расчетных единицах Уставка= (Зад.знач - 38)/2 ;
; где Зад.знач - значение тока в миллиамперах (дискретами через 0,5 мА)
;Такми образом, при задании тока от -19 до +19 мА уставка изменяется от 0 до 76
.CSEG
.org 00
jmp RESET ; Reset Handler
jmp EXT_INT0 ; IRQ0 Handler
jmp EXT_INT1 ; IRQ1 Handler
jmp TM2_COMP ; Timer2 Compare Handler
jmp TM2_OVF ; Timer2 Overflow Handler
jmp TM1_CAPT ; Timer1 Capture Handler
jmp TM1_COMPA ; Timer1 CompareA Handler
jmp TM1_COMPB ; Timer1 CompareB Handler
jmp TM1_OVF ; Timer1 Overflow Handler
jmp TM0_OVF ; Timer0 Overflow Handler
jmp SPI_STC ; SPI Transfer Complete Handler
jmp USRT_RXC ; USART RX Complete Handler
jmp USRT_UDR ; UDR Empty Handler
jmp USRT_TXC ; USART TX Complete Handler
jmp ADC_conv ; ADC Conversion Complete Handler
jmp EE_RDY ; EEPROM Ready Handler
jmp ANA_COMP ; Analog Comparator Handler
jmp TWSI ; Two-wire Serial Interface Handler
jmp EXT_INT2 ; IRQ2 Handler
jmp TM0_COMP ; Timer0 Compare Handler
jmp SPM_RDY ; Store Program Memory Ready Handler
EXT_INT0: ; IRQ0 Handler
EXT_INT1: ; IRQ1 Handler
TM2_COMP: ; Timer2 Compare Handler
TM2_OVF: ; Timer2 Overflow Handler
TM1_CAPT: ; Timer1 Capture Handler
TM1_COMPA: ; Timer1 CompareA Handler
TM1_COMPB: ; Timer1 CompareB Handler
;TM1_OVF: ; Timer1 Overflow Handler
TM0_OVF: ; Timer0 Overflow Handler
SPI_STC: ; SPI Transfer Complete Handler
USRT_RXC: ; USART RX Complete Handler
USRT_UDR: ; UDR Empty Handler
USRT_TXC: ; USART TX Complete Handler
ADC_conv: ; ADC Conversion Complete Handler
EE_RDY: ; EEPROM Ready Handler
ANA_COMP: ; Analog Comparator Handler
TWSI: ; Two-wire Serial Interface Handler
EXT_INT2: ; IRQ2 Handler
TM0_COMP: ; Timer0 Compare Handler
SPM_RDY: ; Store Program Memory Ready Handler
reti
;Обработчик прерывания по переполнению таймера 1, вызывается каждую секунду
TM1_OVF: push R16 ;
push R17 ;
push ZL ;
push ZH ;
push YL ;
push YH ;
push XL ;
push XH ;
push RL ;
push RH ;
push R19 ;
push R1 ;
push R0 ;
push R18 ;
in R16,SREG ;
push R16 ;
ldi R17,$C2 ;1 сек
ldi R16,$F7 ;
out TCNT1H,R17 ;Переинициализировать таймер 1
out TCNT1L,R16 ;на переполнение через 1 секунду
lds XL,LongImpL ;Занести в рег.пару Х кол-во секунд, оставшихся
lds XH,LongImpH ;до завершения текущего импульса
sbiw XL,1 ;Декремент кол-ва оставшихся секунд
breq TM1_2 ;Если кол-во оставшихся секунд равно нулю (импульс завершен), то переход на метку TM1_2
sts LongImpL,XL ;Иначе сохранить в ячейках LongImpL и LongImpH
sts LongImpH,XH ;новое значение кол-ва оставшихся секунд
jmp TM1_END ;Переход на выход из программы
;Текущий импульс завершен
TM1_2: lds ZL,AdrModeL ;Занести в рег.пару Z адрес первого байта информации о текущем режиме
lds ZH,AdrModeH ;
ld R16,Z+ ;Занести в рег.R16 кол-во импульсов в текущем цикле, в рег.паре Z теперь адрес байта кол-ва повторов цикла в режиме
lds R17,NumImpl ;Занести в рег.R17 порядковый номер импульса, выполняющегося в данный момент
inc R17 ;Инкремент номера импульса, выполняющегося в данный момент для проверки, последний ли это импульс в цикле
cp R17,R16 ;Если после инкремента номер импульса меньше кол-ва импульсов в текущем цикле, то это не последний импульс цикла
brlo TM1_4 ;Если R17 < R16, то завершенный импульс не последний в цикле, переход на метку TM1_4
jmp TM1_6 ;Иначе завершенный импульс последний в цикле, переход на метку TM1_6
;Завершенный импульс не последний в цикле
TM1_4: sts NumImpl,R17 ;Сохранить в ячейке NumImpl новое значение порядкового номера импульса, выполняющегося в данный момент
adiw ZL,1 ;Прибавить к адресу кол-ва повторов циклов текущего режима для перехода к адресу информации о первом импульсе
ldi R16,3 ;Занести в рег.R16 длину информации об одном импульсе
mul R17,R16 ;Умножить длину информации об одном импульсе на порядковый номер текущего импульса для рассчета смещения адреса
add ZL,R0 ;Прибавить к адресу первого байта информации о текущем режиме смещение адреса для расчета адреса первого
adc ZH,R1 ;байта информации о текущем импульсе
ld R16,Z+ ;Занести в рег.R16 значение тока текущего импульса в расчетных единицах (уставку тока для текущего импульса)
sts Level,R16 ;Сохранить новое значение уставки тока в ячейке Level
ld R16,Z+ ;Занести в рег.R16 значение мл.байта длины текущего импульса в секундах
sts LongImpL,R16 ;
ld R16,Z+ ;Занести в рег.R16 значение ст.байта длины текущего импульса в секундах
sts LongImpH,R16 ;
call SET_CUR ;Переход на подпрограмму установки тока текущего импульса (выполняется за 17,5 мкс)
jmp TM1_END ;Переход на выход из программы
;Завершенный импульс последний в цикле, проверить кол-во повторов цикла в текущем режиме
TM1_6: ld R16,Z ;Занести в рег.R16 общее кол-во повторений циклов в текущем режиме
lds R17,RepCycl ;Занести в рег.R17 кол-во выполненных повторений циклов в текущем режиме
inc R17 ;Инкремент кол-ва выполненных повторений циклов в текущем режиме
cp R17,R16 ;Если после инкремента кол-во выполненных повторов меньше общего кол-ва повторов, то режим не завершен
brlo TM1_8 ;Если R17 < R16, то текущий цикл не последний в режиме, переход на метку TM1_8
jmp TM1_10 ;Иначе это последний повтор цикла в текущем режиме
;Кол-во повторов цикла текущего режима не исчерпано, начать повтор цикла заново
TM1_8: sts RepCycl,R17 ;Сохранить в ячейке RepCycl новое кол-во выполненных повторов цикла в текущем режиме
clr R17 ;Обнулить рег.R17 для обнуления порядкового номера выполняемого импульса после перехода на метку TM1_4
jmp TM1_4 ;Перейти на метку TM1_4 для возврата на начало цикла и генерации первого импульса
;Выполнены все повторы цикла в текущем режиме, проверить не последний ли это режим программы
TM1_10: lds R17,NumMode ;Занести в рег.R17 порядковый номер текущего режима
inc R17 ;Инкремент порядкового номера текущего режима
lds R16,TPC ;Занести в рег.R17 кол-во режимов в программе
cp R17,R16 ;Сравнить инкрементированный порядковый номер текущего режима с общим кол-вом режимов программы
brlo TM1_12 ;Если номер текущего режима меньше общего кол-ва режимов, то это не последний режим программы, переход на TM1_12
jmp TM1_14 ;Иначе завершенный режим последний в программе, переход на метку TM1_14
;Завершенный режим не последний в программе, перейти на запуск генерации по следующему режиму
TM1_12: sts NumMode,R17 ;Сохранить в ячейке NumMode порядковый номер следующего режима
lds ZL,AdrModeL ;Занести в рег.пару Z адрес первого байта информации о текущем режиме
lds ZH,AdrModeH ;
ld R17,Z ;Занести в рег.R17 кол-во импульсов в цикле текущего режима
adiw ZL,2 ;Переход к адресу начала информации о первом импульсе цикла текущего режима
ldi R16,3 ;Занести в рег.R16 длину информации об одном импульсе (3 байта)
mul R17,R16 ;Умножить длину информации об одном импульсе на кол-во импульсов в цикле для рассчета смещения адреса,
add ZL,R0 ;Теперь в рег.паре Z адрес первого байта информации о следующем режиме,
adc ZH,R1 ;который становится теперь текущим режимом
sts AdrModeL,ZL ;Занести в ячейки AdrModeL и AdrModeH начальный адрес нового
sts AdrModeH,ZH ;текущего режима
clr R17 ;Обнулить рег.R17 для обнуления порядкового номера выполняемого импульса после перехода на метку TM1_4
sts RepCycl,R17 ;Обнулить значение кол-ва выполненных повторов цикла в текущем режиме в ячейке RepCycl
sts NumImpl,R17 ;Обнулить значение порядкового номера импульса, выполняющегося в данный момент в ячейке NumImpl
adiw ZL,1 ;В рег.паре Z теперь адрес байта кол-ва повторов цикла в следующем режиме, ставшем теперь текущим
jmp TM1_4 ;Переход на метку TM1_4 для генерации первого импульса нового текущего режима