.def Temp=R16 .def Temp1=R17 .def Temp2=R18 .def Temp3=R19 .def Temp4=R20 .def Temp5=R21 .def Temp6=R22 ; флаг фазы .def Temp7=R23 ; счетчик байтов, записываемых в ОЗУ .def Temp8=R24 .def Temp9=R25 .dseg ;оперативка OZU: .byte 40 ; зарезервируем 40 байт в ОЗУ ;****************************************************************************** .cseg .org 0 rjmp RESET ; External Pin, Power-on Reset, Brown-out Reset, and Watchdog Reset .org INT0addr ; = 0x0001 External Interrupt Request 0 rjmp INT_0 .org INT_VECTORS_SIZE ;****************************************************************************** ; старт ;****************************************************************************** reset: ; включение микроконтроллера cli ; глобальный запрет на прерывания ldi Temp,low(RamEnd) ; инициализации стека out SPL,Temp ; ldi Temp,0b00000001 ; настроили порт "В" (0-ввод, 1-вывод) out DDRB,Temp ; 0000000х - "вывод" на светодиод ; ххххххх0 - "ввод" ldi Temp,0b00000000 ; настраиваем порт "D" (0-ввод, 1-вывод) out DDRD,Temp ; 00000000 - весь порт настраиваем на ввод ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ldi R16,(1<Y ;------------------------------------------------------------------------------------------------------------ compare_XY16_2970: cp Temp,YH ; сравниваем старшие части регистров breq xh_eq_yh_2970 ; значения старших регистров равны, нужно сравнить младшие xl и yl ; флаг С - установлен когда XY ret xh_eq_yh_2970: cp Temp1,YL ; сравниваем младшие части регистров ; флаг Z=1 когда X=Y ; флаг С - установлен когда XY ret ;************************************************************************************************************* ; обработка если TCNT1 меньше 2970 ( слишком маленькое значение ) ! x<2970 ;************************************************************************************************************* X_menshe_Y_2970: ; здесь обработка если TCNT1 меньше 2970 rjmp out_1 ; выход ;************************************************************************************************************* ; TCNT1 больше 2970 // теперь проверяем больше или меньше 3300+10%=3630 ( 0xE2E ) ;************************************************************************************************************* X_bolshe_Y_2970: ; здесь обработка если TCNT1 больше 2970 mov Temp,XH ; копируем "Х" mov Temp1,XL ldi YH,0xE ; записываем в регистровую пару "Y" 3300+10%=3630 ( 0xE2E ) ldi YL,0x2E rcall compare_XY16_3630 ; сравниваем... breq X_menshe_Y_3630 ; переход на обработку когда X=Y brcs X_menshe_Y_3630 ; переход на обработку когда XY ;------------------------------------------------------------------------------------------------------------ compare_XY16_3630: cp Temp,YH ; сравниваем старшие части регистров breq xh_eq_yh_3630 ; значения старших регистров равны, нужно сравнить младшие xl и yl ; флаг С - установлен когда XY ret xh_eq_yh_3630: cp Temp1,YL ; сравниваем младшие части регистров ; флаг Z=1 когда X=Y ; флаг С - установлен когда XY ret ;************************************************************************************************************* ; обработка если TCNT1 больше 2970 но меньше 3630 ( попали в диапазон 3300 +/- 10% ) ! x=3300 ;************************************************************************************************************* X_menshe_Y_3630: ; здесь обработка если TCNT1 больше 2970 но меньше 3630 ( попали в диапазон 3300 +/- 10% ) ldi XL, low(OZU) ; младший байт адреса!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1 ldi XH, high(OZU) ; старший байт адреса st X+,0b00000001 ; сохраним в ОЗУ состояние столбца клавы, ; адрес в регстровой паре "X" автоматом увеличится на 1 dec R23 ; уменьшаем на единицу счетчик записываемых в ОЗУ байтов brne out_1 ; если не насчитали 40 байт, то выходим из прерывания rjmp chtenie_ozu ; если насчитали 40, то идем обрабатывать данные ;************************************************************************************************************* ; TCNT1 больше 3630 // сейчас будем проверять больше или меньше 6600-10%=5940 ( 0x1734 ) ;************************************************************************************************************* X_bolshe_Y_3630: ; здесь обработка если TCNT1 больше 3630 mov Temp,XH ; копируем "Х" mov Temp1,XL ldi YH,0x17 ; записываем в регистровую пару "Y" 6600-10%=5940 ( 0x1734 ) ldi YL,0x34 rcall compare_XY16_5940 ; сравниваем... breq X_bolshe_Y_5940 ; переход на обработку когда X=Y brcs X_menshe_Y_5940 ; переход на обработку когда XY ;------------------------------------------------------------------------------------------------------------ compare_XY16_5940: cp Temp,YH ; сравниваем старшие части регистров breq xh_eq_yh_5940 ; значения старших регистров равны, нужно сравнить младшие xl и yl ; флаг С - установлен когда XY ret xh_eq_yh_5940: cp Temp1,YL ; сравниваем младшие части регистров ; флаг Z=1 когда X=Y ; флаг С - установлен когда XY ret ;************************************************************************************************************* ; обработка если TCNT1 больше 3630 но меньше 5940 ( ни то ни сё ) ! 3630Y ;------------------------------------------------------------------------------------------------------------ compare_XY16_7260: cp Temp,YH ; сравниваем старшие части регистров breq xh_eq_yh_7260 ; значения старших регистров равны, нужно сравнить младшие xl и yl ; флаг С - установлен когда XY ret xh_eq_yh_7260: cp Temp1,YL ; сравниваем младшие части регистров ; флаг Z=1 когда X=Y ; флаг С - установлен когда XY ret ;************************************************************************************************************* ; обработка если TCNT1 больше 5940, но меньше 7260 ( попали в диапазон 6600 +/- 10% ) ! x=6600 ;************************************************************************************************************* X_menshe_Y_7260: ldi XL, low(OZU) ; младший байт адреса!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ldi XH, high(OZU) ; старший байт адреса st X+,0b00000000 ; сохраним в ОЗУ ; адрес в регстровой паре "X" автоматом увеличится на 1 dec R23 ; уменьшаем на единицу счетчик записываемых в ОЗУ байтов brne out_1 ; если не насчитали 40 байт, то выходим из прерывания rjmp chtenie_ozu ; если насчитали 40, то идем обрабатывать данные ;************************************************************************************************************* ; обработка если TCNT1 больше 7260 ( слишком большое значение ) ! x>7260 ;************************************************************************************************************* X_bolshe_Y_7260: rjmp out_1 ; выход ;************************************************************************************************************** ; чтение данных из ОЗУ ;************************************************************************************************************** chtenie_ozu: ; тут дальнейшие телодвижения ;************************************************************************************************************** ; Выход из прерывания ;************************************************************************************************************** out_1: pop temp4 ; извлекаем "SREG" //////////////////////////////////////////////////// out SREG, temp4 RETI ; точка выхода из прерывания ;**********************************************************************************************************************