.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 ;оперативка key_buff: .byte 5 ; зарезервируем 5 байт в ОЗУ ;****************************************************************************** .EQU ImpLen=0xCE4 ; длина импульса (165 мкс) .EQU OneLen=0xCE4 ; длина паузы для единицы (165 мкс) .EQU NulLen=0x19C8 ; длина паузы для нуля (330 мкс) ;****************************************************************************** .cseg .org 0 rjmp RESET ; External Pin, Power-on Reset, Brown-out Reset, and Watchdog Reset .org OC1Aaddr ; (=0x0004) Timer/Counter1 Compare Match A rjmp OCR1A_COMP .org INT_VECTORS_SIZE ;****************************************************************************** ;старт ;****************************************************************************** reset: ; включение микроконтроллера cli ; глобальный запрет на прерывания ldi Temp,low(RamEnd) ; инициализации стека out SPL,Temp ; ldi Temp,0b00001111 ; настроили порт "В" (0-ввод, 1-вывод) out DDRB,Temp ; 0000х000 - "вывод" на передатчик (PB3- 15 ножка) ; хххх0000 - "ввод" для чтения строк клавиатуры ; 00000ххх - "вывод" " ???????????????????????????????????????????????????????????????? ldi Temp,0b00001111 ; настраиваем порт "D" (0-ввод, 1-вывод) out DDRD,Temp ; 0000хххх - на вывод столбцов клавы ldi Temp,0b00000000 ; установили тактовый сигнал = CK 0 out TCCR1B,Temp ; таймер выключен!!! sei ; глобальное разрешение прерываний ;******************************************************************************* ; главный цикл ;******************************************************************************* Main_cicle: rcall keyboardread ; вызов подпрограммы чтения клавиатуры [1>] rcall certain_buttons_keyboard ; вызов подпрограммы проверки нажатия [2>] rjmp Main_cicle ; циклимся ;******************************************************************************* ; цикл Чтения клавы и запись данных в ОЗУ ;******************************************************************************* keyboardread: ; метка - опрос клавиатуры ldi Temp,5 ; количество столбцов клавы = пять ldi Temp1,0b00000001 ; первый столбец ; загружаем адрес метки массива (key_buff) находящейся в ОЗУ в регистровую пару X ldi XL, low(key_buff) ; младший байт адреса ldi XH, high(key_buff) ; старший байт адреса keyboardread_loop: ; цикл опроса out PortD,Temp1 ; выводим в порт "Д" значение "Temp1" для выбора столбца клавиатуры in Temp2,PinB ; прочитали состояние столбца st X+,Temp2 ; сохраним в ОЗУ состояние столбца клавы, ; адрес в регстровой паре "X" автоматом увеличится на 1 lsl Temp1 ; сдвинули единичку выбора столбца клавиатуры на 1 ; позицию влево dec temp ; уменьшим счетчик brne keyboardread_loop ; если не все просканировали, то циклимся ret ; возврат в главный цикл [1<] ;****************************************************************************************** ; цикл проверки нажатия клавиатуры ;****************************************************************************************** certain_buttons_keyboard: ldi temp1,5 ; УСТАНОВИМ СЧЕТЧИК столбцов клавы ; загружаем адрес метки (key_buff) находящейся в ОЗУ в регистровую пару "Z" ldi ZL,low (key_buff) ; младший байт адреса ldi ZH,high(key_buff) ; старший байт адреса Certain_button: ld Temp,Z+ ; загрузим данные в регистр из ОЗУ по адресу из регистровой пары "Z", ; и после этого адресс в регистровой паре автоматически увеличится на еденицу andi Temp, 0b11110000 ; где "1" там кнопка, где "0" там кнопок нет - потому сбросим ! (маска) cpi Temp,0b00000000 ; проверяем, нажата ли какая ни будь кнопка? brne inform ; если нажата, то переходим на метку "inform" dec temp1 ; уменьшим счетчик столбцов клавы brne Certain_button ; если не все столбцы, то циклимся metka: ret ; возврат в главный цикл [2<] ;*********************************************************************************************** ; вывод информации о состоянии клавиатуры в порт "Б" ;*********************************************************************************************** inform: ; здесь мы включаем таймер ;+++++++++++++++++++++++++++++++++++ установка вывода OC1A=0 ldi R16,(1<