值得注意的是:蓝桥杯给的板子上键盘的第一列和第二列不是由 P37和P36控制的,分别是P44 和P42控制的
分别判断P3的前4位和后四位确定按下了哪个键,其中P44和P42要分开讨论
矩阵键盘
单片机源程序如下:
- //#include "reg52.h" //定义51单片机特殊功能寄存器
- //#include "absacc.h"
- //
- //unsigned char temp;
- //unsigned char value;
- //void delay()
- //{
- // unsigned char i, j;
- //
- // i = 108;
- // j = 145;
- // do
- // {
- // while (--j);
- // } while (--i);
- //}
- //
- //void keydown()
- //{
- // P3 = 0x0f;
- // delay();
- // temp = P3;
- // if(temp != 0x0f)
- // {
- // switch(temp)
- // {
- // case 0x0e: value = 1;break;
- // case 0x0d: value = 5;break;
- // case 0x0b: value = 9;break;
- // case 0x07: value = 13;break;
- // }
- // }
- // P3 = 0xf0;
- // delay();
- // temp = P3;
- // if(temp != 0xf0)
- // {
- // switch(temp)
- // {
- // case 0xe0: value += 3;break;
- // case 0xd0: value += 2;break;
- // case 0xb0: value += 1;break;
- // case 0x70: value += 0;break;
- // }
- // }
- // while(P3 != 0xf0);
- //}
- //
- //int number(int x)
- //{
- // switch(x)
- // {
- // case 0:return 0xC0;break;
- // case 1:return 0xF9;break;
- // case 2:return 0xA4;break;
- // case 3:return 0xB0;break;
- // case 4:return 0x99;break;
- // case 5:return 0x92;break;
- // case 6:return 0x82;break;
- // case 7:return 0xF8;break;
- // case 8:return 0x80;break;
- // case 9:return 0x90;break;
- // default :return 0xF3;break;
- // }
- //}
- //
- //void main()
- //{
- // while(1)
- // {
- // keydown();
- // P2 = ((P2&0x1f)|0xE0);
- // P0 = 0xff;
- // P2 &= 0x1f;
- //
- // P2 = ((P2&0x1f)|0xC0);
- // P0 = 0x80;
- // P2 &= 0x1f;
- //
- // P2 = ((P2&0x1f)|0xE0);
- // P0 = number(value);
- // P2 &= 0x1f;
- // }
- //}
- #include "reg52.h" //定义51单片机特殊功能寄存器
- #include "absacc.h"
- sfr AUXR = 0x8E;
- sfr P4 = 0xC0; //P4
- sbit P42 = P4^2;
- sbit P44 = P4^4;
- // 0 1 2 3 4 5 6 7 8 9 熄灭
- code unsigned char tab[] = { 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xFF};
- unsigned char dspbuf[8] = {10,10,10,10,10,10,10,10}; //显示缓冲区
- unsigned char dspcom = 0;
- bit key_re;
- unsigned char key_press;
- unsigned char key_value;
- bit key_flag = 0;
- unsigned char intr = 0;
- unsigned char read_keyboard(void);
- void display();
- //主函数
- void main(void)
- {
- unsigned char key_temp = 0xff;
-
- AUXR |= 0x80; //1T模式,IAP15F2K61S2单片机特殊功能寄存器
-
- TMOD &= 0xF0;
- TL0 = 0xCD;
- TH0 = 0xD4;
- TF0 = 0;
- TR0 = 1;
- ET0 = 1;
- EA = 1;
-
- while(1)
- {
- if(key_flag)
- {
- key_flag = 0;
- key_temp = read_keyboard();
- if(key_temp != 0xFF){
- dspbuf[7] = key_temp%10;
- dspbuf[6] = key_temp/10;
- }
- }
-
- }
- }
- //定时器中断服务函数
- void isr_timer_0(void) interrupt 1 //默认中断优先级 1
- {
- display();
- if(++intr == 10) //1ms执行一次
- {
- intr = 0;
- key_flag = 1; //10ms按键扫描标志位置1
- }
- }
- //读取矩阵键盘键值:转接板中使用P42和P44代替8051引脚
- //顺序中的P36和P37引脚
- unsigned char read_keyboard(void)
- {
- static unsigned char col;
-
- P3 = 0xf0; P42 = 1; P44 = 1;
- if((P3 != 0xf0)||(P42 != 0)||(P44 != 0)) //有按键按下
- key_press++;
- else
- key_press = 0; //抖动
-
- if(key_press == 3)
- {
- key_press = 0;
- key_re = 1;
-
- if(P44 == 0) col = 1;
- if(P42 == 0) col = 2;
- if((P3 & 0x20) == 0) col = 3;
- if((P3 & 0x10) == 0) col = 4;
-
- P3 = 0x0F; P42 = 0; P44 = 0;
- if((P3&0x01) == 0) key_value = (col-1);
- if((P3&0x02) == 0) key_value = (col+3);
- if((P3&0x04) == 0) key_value = (col+7);
- if((P3&0x08) == 0) key_value = (col+11);
- }
-
- //连续三次检测到按键被按下,并且该按键已经释放
- P3 = 0x0f; P42 = 0; P44 = 0;
-
- if(((key_re == 1) && (P3 == 0x0f))&&(P42 == 0)&&(P44 == 0))
- {
- key_re = 0;
- return key_value;
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
矩阵键盘.rar
(27.03 KB, 下载次数: 35)
|