В этой статье описана простейшая программа для самодельной матричной клавиатуры, позволяющая реализовать следующие функции: опрос клавиатуры и пересылка скан-кодов нажатых клавиш (если такие были) на компьютер по интерфейсу RS-232.
Программа написана для контроллера PIC16F628A и работает следующим образом:
В цикле происходит сканирование клавиатуры, состояние сохраняется в два байта (каждой кнопке соответствует один бит). У нас 9 кнопок, поэтому один байт используется целиком (все 8 бит), а во втором байте используется только младший бит. Время опроса клавиатуры составляет 30 мкс, период опроса — от 40 мкс до 4 мс (в зависимости от того, были ли во время опроса нажаты какие-нибудь клавиши и, если да, то сколько).
Если во время опроса были нажаты какие-нибудь кнопки, то скан-коды, соответствующие этим кнопкам, передаются на компьютер по USART (через преобразователь уровней RS232-TTL).
Скан-коды для каждой клавиши назначаются (программируются) при прошивке контроллера и хранятся в EEPROM.
Алгоритм:
list p = 16f628a __config 03F30h ;*** Переменные ****************************************** CBLOCK 0x20 ; Начальный адрес блока пользовательской памяти Adr ; адрес для чтения EEPROM Schet ; счетчик считанных байт Kbyte1 ; 1-й байт состояния Kbyte2 ; 2-й байт состояния ENDC ;**** Константы / Адреса регистров ************************ Baudrate equ .12 ; скорость 19200 ;--------------------------------------------------------- STATUS equ 03h ; Регистр выбора банка PORTA equ 05h ; Порт А PORTB equ 06h ; Порт В TRISA equ 05h ; Конфигурация порта А (банк 1) TRISB equ 06h ; Конфигурация порта В (банк 1) CMCON equ 1Fh ; Управление компараторами OPT equ 01h ; Регистр OPTION - управление подтяг-ми резисторами ;--- Регистры передатчика и приемника--------------------- TXREG equ 19h ; буфер передатчика RCREG equ 1Ah ; буфер приемника PIR1 equ 0Ch ; регистр флагов передатчика PIE1 equ 0Ch ; разрешение/запрет прерываний передатчика (1-й банк) TXSTA equ 18h ; конфигурация передатчика (1-й банк) RCSTA equ 18h ; конфигурация приемника SPBRG equ 19h ; настройка скорости ;--- Регистры для косвенной адресации и EEPROM ----------------------- FSR equ 04h ; регистр адреса при косвенной адресации INDF equ 0h ; регистр косвенной адресации EEADR equ 1Bh ; адрес EEPROM (банк 1) EECON1 equ 1Ch ; управляющий регистр для работы c EEPROM (банк 1) EEDATA equ 1Ah ; регистр данных из/в EEPROM (банк 1) ;********************************************************* org 0 ;*** Настройка портов ************************************ start movlw .7 movwf CMCON ; выкл-ть компаратор movlw .194 ; .194 = 11000010 (RA7,RA6,RA1=1) movwf PORTA ; инициализация защелок порта А clrf PORTB ; инициализация защелок порта В bsf STATUS,5 ; Перейти в 1-й банк clrf TRISA ; Записать конф-ю порта A в регистр TrisA movlw .230 ; .230=11100110 (чтобы работал UART надo TRISB[2,1]=1) movwf TRISB ; Скопировать конф-ю порта B из W в регистр TrisB bcf OPT,7 ; Включить подтягивающие резисторы bcf STATUS,5 ; Перейти в 0-й банк ;*** Настройка приемо-передатчика ************************ bsf STATUS,5 ; перейти в первый банк movlw Baudrate ; загрузить устанавливаемую скорость в аккумулятор movwf SPBRG ; установить скорость movlw b'00100100' ; 8-разрядные данные, включить передачу, movwf TXSTA ; высокоскоростной асинхронный режим bcf PIE1, 4 ; запретить прерывания от передатчика USART (TXIE=0) bcf PIE1, 5 ; запретить прерывания от приемника USART (RCIE=0) bcf STATUS,5 ; перейти в нулевой банк movlw b'10000000' ; 8-разрядные данные, выключить прием, movwf RCSTA ; включить модуль USART ;*** Загрузка кодов клавиш из EEPROM в ОЗУ *************** movlw .9 movwf Schet ; загружаем скан-коды для 9 клавиш movlw 25h ; считанные данные сохраняем начиная с этого адреса movwf FSR ; адрес для косвенной адресации movlw .0 ; начинаем читать EEPROM movwf Adr ; с адреса 0 zagruzka bsf STATUS,5 ; перейти в первый банк movwf EEADR ; загружаем из аккумулятора адрес для чтения из EEPROM bsf EECON1,0 ; чтение movf EEDATA,0 ; запись прочитанного байта в аккумулятор bcf STATUS,5 ; Перейти в 0-й банк movwf INDF ; сохраняем считанный байт по адресу, записанному в FSR incf FSR,1 ; увеличиваем адрес ОЗУ incf Adr,1 ; увеличиваем адрес EEPROM movf Adr,0 ; загружаем адрес EEPROM в аккумулятор decfsz Schet,1 ; если считали все байты - следующ.команда пропуск-ся goto zagruzka ;*** Основная часть программы **************************** prog clrf Kbyte1 clrf Kbyte2 call scan ; сканирование movf Kbyte1,0 iorwf Kbyte2,0 ; если были нажатия клавиш, то результат не 0 btfss STATUS,2 ; если флаг Z = 1, то пропускаем след-ю команду call flow goto prog ;********************************************************* ;---------- Сканирование --------------------------------- scan bcf PORTA,1 ; проверяем первый столбец nop btfss PORTB,6 ; проверяем К1 bsf Kbyte1,0 btfss PORTB,5 ; проверяем К4 bsf Kbyte1,3 btfss PORTB,7 ; проверяем К7 bsf Kbyte1,6 bsf PORTA,1 ; отключаем первый столбец nop bcf PORTA,7 ; проверяем второй столбец nop btfss PORTB,6 ; проверяем К2 bsf Kbyte1,1 btfss PORTB,5 ; проверяем К5 bsf Kbyte1,4 btfss PORTB,7 ; проверяем К8 bsf Kbyte1,7 bsf PORTA,7 ; отключаем второй столбец nop bcf PORTA,6 ; проверяем третий столбец nop btfss PORTB,6 ; проверяем К3 bsf Kbyte1,2 btfss PORTB,5 ; проверяем К6 bsf Kbyte1,5 btfss PORTB,7 ; проверяем К9 bsf Kbyte2,0 bsf PORTA,6 return ;---------- Передача одного скан-кода ------------------- transmit movf INDF,0 ; загружаем в аккумулятор скан-код по адресу FSR movwf TXREG ; помещаем это значение на передачу bsf STATUS,5 ; в первый банк per btfss TXSTA,1 ; если 1-й бит TXSTA = 1, - передача заверш. (TSR пуст) goto per bcf STATUS,5 ; нулевой банк return ;--------- Передача скан-кодов -------------------------- flow movlw 25h movwf FSR btfsc Kbyte1,0 ; проверяем - была ли нажата клавиша 1 call transmit ; если да, то посылаем её скан-код incf FSR,1 btfsc Kbyte1,1 ; проверяем - была ли нажата клавиша 2 call transmit incf FSR,1 btfsc Kbyte1,2 ; проверяем - была ли нажата клавиша 3 call transmit incf FSR,1 btfsc Kbyte1,3 ; проверяем - была ли нажата клавиша 4 call transmit incf FSR,1 btfsc Kbyte1,4 ; проверяем - была ли нажата клавиша 5 call transmit incf FSR,1 btfsc Kbyte1,5 ; проверяем - была ли нажата клавиша 6 call transmit incf FSR,1 btfsc Kbyte1,6 ; проверяем - была ли нажата клавиша 7 call transmit incf FSR,1 btfsc Kbyte1,7 ; проверяем - была ли нажата клавиша 8 call transmit incf FSR,1 btfsc Kbyte2,0 ; проверяем - была ли нажата клавиша 9 call transmit return ;********************************************************* org 2100h ; EEPROM память de 31h, 32h, 33h, 34h, 35h, 36h, 37h, 38h, 39h ; коды клавиш: "1", "2", "3", "4", "5", "6", "7", "8", "9" end |