本帖最后由 不亦心 于 2010-8-6 19:04 编辑
虽然22L有匠人的大作了,但是俺还是得把原理图更新上来,崩溃了
如果这次还错,那我真的对自己无语了
配合这图,再更新一下程序
加上组合键的话还可以有别的按键,如S2+S6=S19
#include<avr/io.h>
#define SET_BIT(add,bitn) (add |= (1<<bitn))//位置1
#define CLR_BIT(add,bitn) (add &= ~(1<<bitn)) // 位清0
#define GET_BIT(add,bitn) (add & (1<<bitn))//获取位端口电平
static volatile unsigned char Key_count = 2,Key=0,num,nkey,q=0,d=0;//扫描次数,记录按键情况,按键编码,按键备份
const unsigned char Key_tab[64] = //按键映射表
{
19,0,0,0,0,0,2,0,0,0,0,0,0,0,0,18,//0-f
0,0,0,0,0,0,0,0,4,0,0,14,0,0,3,10,//10-1f
0,6,0,0,0,0,0,1,0,0,0,0,0,15,0,11,//20-2f
0,0,0,17,0,0,13,8,0,5,0,9,16,12,7,0//30-3f
};
void Key_IO_init(void)
{
DDRA = 0xf8;//PA0,PA1,PA2设为输入,高阻
PORTA = 0xff;
}
unsigned char Key_scan()
{
if(Key_count==3) Key_count = 0;
Key_count++;
switch(Key_count)
{
case 1:
if(GET_BIT(PINA,PINA1)) SET_BIT(Key,0);//Key.flag0 = 1;
if(GET_BIT(PINA,PINA2)) SET_BIT(Key,1);//Key.flag1 = 1;
CLR_BIT(DDRA,DDA0);
SET_BIT(PORTA,PA0);//PA0输入,高阻
CLR_BIT(PORTA,PA1);
SET_BIT(DDRA,DDA1);//PA1输出0
break;
case 2:
if(GET_BIT(PINA,PINA2)) SET_BIT(Key,2);//Key.flag2 = 1;
if(GET_BIT(PINA,PINA0)) SET_BIT(Key,3);//Key.flag3 = 1;
CLR_BIT(DDRA,DDA1);
SET_BIT(PORTA,PA1);//PA1输入,高阻
CLR_BIT(PORTA,PA2);
SET_BIT(DDRA,DDA2);//PA2输出0
break;
default ://case 0:
if(GET_BIT(PINA,PINA0)) SET_BIT(Key,4);//Key.flag4 = 1;
if(GET_BIT(PINA,PINA1)) SET_BIT(Key,5);//Key.flag5 = 1;
CLR_BIT(DDRA,DDA2);
SET_BIT(PORTA,PA2);//PA2输入,高阻
CLR_BIT(PORTA,PA0);
SET_BIT(DDRA,DDA0);//PA0输出0
if(Key == 0x3f)
{
Key = 0;
q = 0;//防止连续按两次按键误当成一次按键而不应答
num = 0xff;//无按键标志
}
else
{
if((nkey == Key)&&(q != Key)) //判断此处键值是否与上次扫描键值一样消抖,&&并且消除一次按键多次响应
{
num = Key_tab[Key];
q = nkey;
Key_count = 2;//防止一次按键多次响应,因为一个按键的扫描要扫描3次才能更改num
Key = 0xff;
}
else
{
num = 0xff;
nkey = Key;
Key = 0;
}
}
}
return(num);
} |