ブルーブリッジカップ単片機マトリクスキーボード振れ解消(3行コード利用)
3行コード
keycode = ~(keycloumn | keyrow);
key = keycode & (keycode ^ keybefore);
keybefore = keycode;
3行のコードの理解:
一般的に2つ以上のボタンを同時に押すことはなく、以下では異なるボタンを同時に押すことを考慮しない.
keycodeは現在のスキャンで得られたキー符号化であり、キー押下が0でない場合は0であり、keybeforeは前回のスキャンで得られたキー値である.
第1行はキー符号化の反転であり、押下されたキーの行と列のバイナリ値を1とする(例えば、第1行の第2列keycodeを0 x 41とし、高4位は高位から低位まで第1列から第4列に対応し、低4位は低位から高位まで第1行から第4行に対応する).
2行目は手を緩めて振れを検出する.現在と前回スキャン時のキーの状態は4つあり、振れを消すため、状況②(キーを押したばかり)時のみキーコード①:前回は押しておらず、現在は押していない;②:前回は押さなかったが、現在は押されている.③:前回押して、現在押して;④:前回押したが、現在押していない;
異或演算は1,同じ0であり,②と④の2つの場合のみkeycodeとkeybeforeが異なるため,②と④の2つの場合のみkeycode^keybeforeは0ではない.どちらの場合も1つが0の値と1つが0でない値ビットが異なる場合、②と④の両方の場合keycode^keybeforeの値は0でない値(例えば0 x 87^0 x 00=0 x 87)に等しいため、2 keycode^keybefore=keycode(現在のスキャン時にキーコード)のみとなる.また、得られた値はkeycodeと位置付け操作を行う必要があり、場合④keycode=0、および(keybefore^keycode)ビットと結果は0であるが、場合②keycodeは現在の押下キー符号化であり、(keybefore^keycode)も現在の押下キー符号化であるため、keyも現在の押下キー符号化である.以上より、場合2 keyの値が現在キーを押して符号化されている場合のみ、残りの3つの場合key=0となる.
3行目:前回押したキーコードを保存します.
ソースコード
#include
#define uchar unsigned char
code uchar semg[12] = {
0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90,
0xbf, 0xff};
code uchar semg_bit[8] = {
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
uchar semg_temp[8] = {
11, 11, 11, 11, 11, 11, 11, 11};
// ,-1 '-'
code char keymap[4][4] = {
{
0, 1, 2, -1}, {
3, 4, 5, -1}, {
6, 7, 8, -1}, {
9, 10, 11, -1}};
void allinit()
{
P2 = 0x80; P0 = 0xff;
P2 = 0xa0; P0 = 0x00;
P2 = 0xc0; P0 = 0xff;
P2 = 0xe0; P0 = 0xff;
}
void Timer0Init(void) //2 @11.0592MHz
{
AUXR |= 0x80; // 1T
TMOD &= 0xF0; //
TL0 = 0x9A; //
TH0 = 0xA9; //
TF0 = 0; // TF0
TR0 = 1; // 0
EA = 1;
ET0 = 1;
}
void display()
{
uchar i;
P2 = 0xe0; P0 = semg[semg_temp[i]];
P2 = 0xc0; P0 = semg_bit[i];
P2 = 0x00; P0 = 0xff;
i++;
if(i == 8)
i = 0;
}
void fun() interrupt 1
{
display();
}
char keyscan()
{
static uchar keybefore = 100;
char keyvalue = 100;
uchar keyrow = 0, keycloumn = 0, keycode = 0, key = 0, i = 0, j = 0;
P3 = 0x0f; P44 = 0; P42 = 0; P35 = 0;
keyrow = P3 & 0x0f;
P3 = 0xf0; P44 = 1; P42 = 1; P35 = 1;
if(P44 == 0) keycloumn = 0x70;
else if(P42 == 0) keycloumn = 0xb0;
else keycloumn = P3 & 0xf0;
//
keycode = ~(keycloumn | keyrow);
key = keycode & (keycode ^ keybefore);
keybefore = keycode;
if(key)
{
for(i = 0; i < 4; i++)
for(j = 0; j < 4; j++)
if(key == (0x80 >> j | 0x01 << i))
{
keyvalue = keymap[i][j];
break;
}
}
return keyvalue;
}
void menu(char keyvalue)
{
if(keyvalue >= 0 && keyvalue <= 11)
{
if((keyvalue / 10) > 0)
semg_temp[6] = keyvalue / 10;
else
semg_temp[6] = 11;
semg_temp[7] = keyvalue % 10;
}
else if(keyvalue == -1)
{
semg_temp[6] = 11;
semg_temp[7] = 10;
}
else ;
}
void main()
{
allinit();
Timer0Init();
while(1)
{
menu( keyscan() );
}
}