- #include<reg51.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define GPIO_DIG P0
- #define GPIO_KEY P1
-
- uchar code DIG_CODE[17]=
- {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
- 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
- //数码管的显示码
- uchar KeyValue;
- //用来存放读取到的按下的键值
- void Delay10ms();
- //延时10ms
- void KeyDown();
- //按键函数
- void main(void)
- {
- while(1)
- {
- KeyDown();
- GPIO_DIG=~DIG_CODE[KeyValue];
- //数码管显示按键值
- }
- }
- void KeyDown(void)
- {
- char a=0;
- GPIO_KEY=0x0f;//P1高四位低电平0000,低四位高电平1111
- if(GPIO_KEY!=0x0f)//读取按键是否按下
- {
- Delay10ms();//延时10ms消抖
- if(GPIO_KEY!=0x0f)//再次检测键盘是否按下
- {
- GPIO_KEY=0x0f;//测试列 00001111
- switch(GPIO_KEY)
- {
- case(0x07): KeyValue=0;break;//00000111,第一列有按键按下
- case(0x0b): KeyValue=1;break;//00001011,第二列有按键按下
- case(0x0d): KeyValue=2;break;//00001101,第三列有按键按下
- case(0x0e): KeyValue=3;break;//00001110,第四列有按键按下
- }
- GPIO_KEY=0xf0;//测试行 11110000
- switch(GPIO_KEY)
- {
- case(0x70): KeyValue=KeyValue;break;//01110000,第一行有按键按下
- case(0xb0): KeyValue=KeyValue+4;break;//10110000,第二行有按键按下
- case(0xd0): KeyValue=KeyValue+8;break;//11010000,第三行有按键按下
- case(0xe0): KeyValue=KeyValue+12;break;//11100000,第四行有按键按下
- }//得到相应的键值
- while((a<50)&&(GPIO_KEY!=0xf0))//按键松手检测
- {
- Delay10ms();
- a++;
- }
- }
- }
- }
- void Delay10ms(void) //误差 0us
- {
- uchar a,b,c;
- for(c=1;c>0;c--)
- for(b=38;b>0;b--)
- for(a=130;a>0;a--);
- }
- /*逐行扫描:高四位轮流输出低电平来对矩阵键盘
- 进行逐行扫描,当低四位接收到的数据不全为1时
- 说明有按键按下,然后通过接收到的数据是哪一
- 位为0来判断哪一个按键被按下*/
- /*行列扫描:我们可以通过高四位全部输出低电平,
- 低四位输出高电平。当接收到的数据,低四位不全为高电平时,
- 说明有按键按下,然后通过接收的数据值,判断是哪一列有
- 按键按下,然后再反过来,高四位输出高电平,第四位输出低电平,
- 然后根据接收到的高四位的值判断是哪一行有按键按下,这样就能够
- 确定是哪一个按键按下了。*/
复制代码 |