Страница 1 из 1

Буфер клавиатуры на WinAVR

Добавлено: Ср авг 19, 2009 09:46:13
geniusbsd
Как организовать буфер клавиатуры 4х4 на Winavr
Пробовал так

Код: Выделить всё

unsigned char buf[];
void input_code()
{

for(int i=0;i<4;i++)
{
Key=ScanKeyb();
 if(Key!=KeyOld) {KeyOld=Key;

switch(Key)
 {case 0x0B:buf[i]="0";LcdStr(FONT_1X,"0");LcdUpdate();break;
  case 0x0C:buf[i]="1";LcdStr(FONT_1X,"1");LcdUpdate();break;
  case 0x08:buf[i]="2";LcdStr(FONT_1X,"2");LcdUpdate();break;
  case 0x04:buf[i]="3";LcdStr(FONT_1X,"3");LcdUpdate();break;
  case 0x0D:buf[i]="4"; LcdStr(FONT_1X,"4");LcdUpdate();break; 
  case 0x09:buf[i]="5"; LcdStr(FONT_1X,"5");LcdUpdate();break;
  case 0x05:buf[i]="6";LcdStr(FONT_1X,"6");LcdUpdate();break; 
  case 0x0E: buf[i]="7";LcdStr(FONT_1X,"7");LcdUpdate();break;
  case 0x0A: buf[i]="8";LcdStr(FONT_1X,"8");LcdUpdate();break;
  case 0x06: buf[i]="9";LcdStr(FONT_1X,"9");LcdUpdate();break;
  case 0x0F:LcdStr(FONT_1X,buf);LcdUpdate();break;
  case 0x07:LcdClear();LcdUpdate();break;}	
}
 else Key=0XFF;i=i--;
}
Но не получается. В чем моя ошибка

Добавлено: Ср авг 19, 2009 10:40:57
ARV
вопрос, как обычно, задан непонятно, будем гадать.

если под "буффером" подразумевается промежуточное хранение кодов введенных клавиш, то логика должна быть совсем не такая - процессы должны быть асинхронными, т.е. заносятся коды в буфер отдельно (по таймеру или по прерываниям, например), а извлекаются - отдельно (например, в основном цикле).

если подразумевается что-то иное - то тогда огласите, что именно.

Добавлено: Чт авг 20, 2009 08:22:03
geniusbsd
Например такая задача . ввод четырех значного пароля.

буфер теребуетя для хранения нажатых клавиш. и дальнейшего сравнения с переменной хранящей установленный пароль.

Добавлено: Чт авг 20, 2009 11:27:36
Student_X
... обычно под клавиатуру используют кольцевой буфер, т.е. определяют размер под него и хранят указатель на первый (голова) и последний (хвост) элементы. Посмотри как это было сделано в DOS на PC - прерывание биоса int 0x16 кажется....

Добавлено: Чт авг 20, 2009 13:59:31
BerZerK-ku
Ну во-первых, на сколько я знаю в одиночные апострофы ('1') заключают символ, а в кавычки строку ("1"). Но если ваш компилятор не выдает ошибку, то может и все нормально.
Ну и сам алгоритм непонятен, вернее он построен так что программа и не будет работать :)
Рассмотрим ситуацию:
Пусть вы нажали на кнопку '1'. При первом проходе цикла Key='1'; Key!=KeyOld -> KeyOld='1'; switch('1') { buf[0]='1' }.
Идем дальше, уверенности в том что кнопка уже отпущена нет, поэтому возможна такая ситуация: Key='1'; Key==KeyOld -> Key=0xff; i--; И т.д. Вероятность того что после отпускания кнопки i==1 всего лишь 50%.

Добавлено: Чт авг 20, 2009 17:56:50
geniusbsd
А как вы предлогаете организовать
Можно пример кода

Добавлено: Пт авг 21, 2009 06:19:44
BerZerK-ku
Ну например так:

Код: Выделить всё

Key=ScanKeyb();
if (Key!=KeyOld){
	KeyOld=Key;
	if (i<4){
		switch(Key){
			case 0x0B:buf[i++]="0";LcdStr(FONT_1X,"0");LcdUpdate();break;
			case 0x0C:buf[i++]="1";LcdStr(FONT_1X,"1");LcdUpdate();break;
			case 0x08:buf[i++]="2";LcdStr(FONT_1X,"2");LcdUpdate();break;
			case 0x04:buf[i++]="3";LcdStr(FONT_1X,"3");LcdUpdate();break;
			case 0x0D:buf[i++]="4";LcdStr(FONT_1X,"4");LcdUpdate();break;
			case 0x09:buf[i++]="5";LcdStr(FONT_1X,"5");LcdUpdate();break;
			case 0x05:buf[i++]="6";LcdStr(FONT_1X,"6");LcdUpdate();break;
			case 0x0E:buf[i++]="7";LcdStr(FONT_1X,"7");LcdUpdate();break;
			case 0x0A:buf[i++]="8";LcdStr(FONT_1X,"8");LcdUpdate();break;
			case 0x06:buf[i++]="9";LcdStr(FONT_1X,"9");LcdUpdate();break;		
		}  
	}
	switch(Key){
		case 0x0F:LcdStr(FONT_1X,buf);LcdUpdate();break;
		case 0x07:LcdClear();LcdUpdate();break; 
	}	
}

Добавлено: Пт авг 21, 2009 07:55:04
geniusbsd
Получается точно такой же результат как у меня и был изначально
buf[]="1234" после нажатия 4 клавиш в буфере вот такое значение "/234"

Добавлено: Пт авг 21, 2009 09:38:03
Student_X
... во Сишники "жарят" постой опрос клавиатуры "раздули" байт на 300, да еще не работает :)

... делал когда-то девайс с динамической индикацией, ну и клавиатура там тоже была - если надо могу поискать исходник (.. правда он на 51 ассемблере)

Добавлено: Пт авг 21, 2009 11:07:11
BerZerK-ku
geniusbsd писал(а):Получается точно такой же результат как у меня и был изначально
buf[]="1234" после нажатия 4 клавиш в буфере вот такое значение "/234"
Ну по приведенному выше коду положить в буфер '/' это что-то из ряда фантастики. А что будет если нажать четыре единицы: "/111" или "////"?
Да и лучше бы выложить проект целиком.
Student_X писал(а): ... во Сишники "жарят" постой опрос клавиатуры "раздули" байт на 300, да еще не работает Smile

... делал когда-то девайс с динамической индикацией, ну и клавиатура там тоже была - если надо могу поискать исходник (.. правда он на 51 ассемблере)
Динамическая индикация + опрос клавиатуры да еще и на ассемблере? Да вы просто бог программирования.

Добавлено: Пн авг 24, 2009 00:24:23
geniusbsd
все разобрался...

Код: Выделить всё

unsigned char keyscan()
{
	unsigned char key=11;	//если кнопка не нажата возвращаем 11
	TCCR1B = 0;
	PORTA=0xE0;	_delay_us(2);
	if(bit_is_clear(PINA,0)){key='1';}
	if(bit_is_clear(PINA,1)){key='4';}
	if(bit_is_clear(PINA,2)){key='7';}
	if(bit_is_clear(PINA,3)){key=10;}        	// *
	PORTA=0xB0;	_delay_us(2);
	if(bit_is_clear(PINA,0)){key='3';}
	if(bit_is_clear(PINA,1)){key='6';}
	if(bit_is_clear(PINA,2)){key='9';}
	if(bit_is_clear(PINA,3)){key=12;}
	PORTA=0xD0;	_delay_us(2);
	if(bit_is_clear(PINA,0)){key='2';}
	if(bit_is_clear(PINA,1)){key='5';}
	if(bit_is_clear(PINA,2)){key='8';}
	if(bit_is_clear(PINA,3)){key='0';}        	// #
	PORTA=0xFF;
	return key;
}

void getkey()
{
//	unsigned char a=0,b=0;
	static unsigned char n,oldkey;
	a=keyscan();
	_delay_ms(10);
	b=keyscan();
	n++; //количество сканирований клавы
	if(a==b)
	{	
    if(a==10 || a==12)	//если * или #
    {{LcdClear();
	LcdUpdate();
    	c=0;}	//счетчик буфера=0
		for(unsigned char i=0;i<4;i++) //очищаем буфер
    	{bufer[i]=0;}
    }
    else if(c<4>10){oldkey=0;n=0;}	//кнопка перестаёт быть старой после 10 сканирований клавы
	}
}


void timers_init(void)
{
 
    TCNT0 = 0x01;
	TCCR0 = (1<<CS02) | (1<<CS00);
	TIMSK = (1<<TOIE0>3)
   {
      i=0;
      getkey();
}
}

и проблема оказалась не с буфером, а кодировкой выводимой на гафический лсд

Добавлено: Пн авг 24, 2009 05:39:54
ibiza11
BerZerK-ku писал(а):Динамическая индикация + опрос клавиатуры да еще и на ассемблере? Да вы просто бог программирования.
ухахахахаха! :))) :))) :))) а что тут сложного то?

Добавлено: Пн авг 24, 2009 10:26:32
Student_X
... дык наоборот проще - совмещаешь сканирование с перебором знакоместа ... а тут "нахаляву" раздают "божественный статус" :)))

Добавлено: Пн авг 24, 2009 12:25:45
BerZerK-ku
Student_X писал(а):... дык наоборот проще - совмещаешь сканирование с перебором знакоместа ... а тут "нахаляву" раздают "божественный статус" :)))
Мда... какой первый пост, такой и последующий. Если человек предлагает асм исходник, на вопрос по Си коду, то он и в божественность свою поверит.