Здравствуйте, помогите пожалуйста, - это программа работы микроконтроллера с матричной клавиатурой 4х4.
Свою программу я не могу написать, поскольку, чтоб написать свою мне нужно разобрать эту, иначе не выйдет. Я выделил жирным шрифтом те фрагменты программы, которые меня интересует.
1)Насколько я понял результат чтения клавиш сохраняется в row_data, а потом пересохраняется в keys
А потом далее есть условие if (k=keys) keys=0; верно ли что там одно =, а не два == и почему?
2)Не могли бы кто - нибудь коротко описать алгоритм, который тут происходит?
Насколько я понял берутся 4 ножки микроконтроллера(7,6,5,4) чтоб они были выходами столбцов и постепенно переходим от 7 к 4, чтоб считать с них данные, узнав этим на какой строке нажата кнопка.
Но мне не понятно это условие if (column==(LAST_COLUMN>>1)) возьмем значения которые там будут при самом первом прерывании if(64==8), то получается что условие не выполнилось пропускаем все скобки и опускаемся к KEYOUT=~column; и всё, а где тогда считывание показаний будет?
Надеюсь на вашу помощь, чтоб вы коротко описали какой же по настоящему тут алгоритм
#asm
.equ __lcd_port=0x15
#endasm
#include <lcd.h>
#include <stdio.h>
#include <delay.h>
#include <mega16.h>
// quartz crystal frequency [Hz]
#define F_XTAL 3686400L
// PIND0..3 will be row inputs
#define KEYIN PIND
// PORTD4..7 will be column outputs
#define KEYOUT PORTD
// used for TIMER0 count initialization
#define INIT_TIMER0 TCNT0=0x100L-F_XTAL/64L/500L
#define FIRST_COLUMN 0x80
#define LAST_COLUMN 0x10
typedef unsigned char byte;
// store here every key state as a bit,
// bit 0 will be KEY0, bit 1 KEY1,...
unsigned keys;
// LCD display buffer
char buf[33];
// TIMER 0 interrupt at every 2 ms
interrupt [TIM0_OVF] void timer0_int(void)
{
static byte key_pressed_counter=20;
static byte key_released_counter,column=FIRST_COLUMN;
static unsigned row_data,crt_key;
// reinitialize TIMER0
INIT_TIMER0;
row_data<<=4;
// get a group of 4 keys in in row_data
row_data|=~KEYIN&0xf;
column>>=1;
if (column==(LAST_COLUMN>>1))
{//(1)
column=FIRST_COLUMN;
if (row_data==0) goto new_key;
if (key_released_counter) --key_released_counter;
else
{//(2)
if (--key_pressed_counter==9) crt_key=row_data;
else
{//(3)
if (row_data!=crt_key)
{//(4)
new_key:
key_pressed_counter=10;
key_released_counter=0;
goto end_key;
};//(4)
if (!key_pressed_counter)
{//(5)
keys=row_data;
key_released_counter=20;
};//(5)
};//(3)
};//(2)
end_key:;
row_data=0;
};//(1)
// select next column, inputs will be with pull-up
KEYOUT=~column;
}
// test if a key was pressed
unsigned inkey(void)
{
unsigned k;
if (k=keys) keys=0;
return k;
}
void init_keypad(void)
{
DDRD=0xf0;
INIT_TIMER0;
TCCR0=3;
TIMSK=2;
#asm("sei")
}
main() {
unsigned k;
init_keypad();
lcd_init(20);
lcd_putsf("CVAVR Keypad");
// read keys and display key code
while (1)
{
lcd_gotoxy(0,1);
if (k=inkey())
{
sprintf(buf,"Key code=%Xh",k);
lcd_puts(buf);
}
else lcd_putsf("NO KEY ");
delay_ms(500);
}
}