头像-305537

aa32786307ea50da

个人成就

获得 0 次赞

帮助过0人

关于51单片机的矩阵键盘扫描的两种方法的困惑,高手解答~

一般的按键查询法有2种:(1)把键盘程序放在主程序的while(1)循环里不停的查询。  (2)为防漏键,将按键程序放在定时器0的中断服务程序里,约每10ms中断一次;其返回键值赋给一个全局变量key_value,然后在主函数里将根据key_value的值来做出相应的动作!        分析上述两种方法:对于第一种方法,如果主程序特别长且很消耗时间,那么很可能出现按键漏扫的情况,不可靠。第二种情况是每隔段时间就去扫描下按键,理论上和主程序的while(1)循环里代码是否长和消耗时间应该无关,应该是很可靠的一种按键扫描方法!但事实就不是这样,下面请看代码,很简单的哦~//用定时器中断扫描矩阵键盘程序#include <reg52.h>#define s8 signed char#define u8 unsigned char#define u16  unsigned int#define u32  unsigned long int//#define PORT P1//共阳极不带小数点u8 code segment[]  = {0XC0 0XF9 0XA4 0XB0 0X99 0X92 0X82 0XF8                                0X80 0X90 0X88 0X83 0XC6 0XA1 0X86 0X8E};u8 code position[] = {0XFE0XFD0XFB0XF70XEF0XDF0XBF0X7F0X000XFF};u8 key_value = 20u;//u表示无符号整型u16 tmr0_value = 10000u;void rough_delay_1ms(u16);void digitron_static_display(u8 u8); void init_tmr0(void);u8 scan_MatrixKey(void); int main(void){     init_tmr0();//初始化定时器0     while (1)    {        //用7段数码管将矩阵键盘的键值显示出来        digitron_static_display(key_value 8);//8表示位选全开        //此处延时后按键就不灵敏了,注销延时则按键很灵敏        rough_delay_1ms(20);//    }  return 0;}//翻转扫描法u8 scan_MatrixKey(void){    //为了不分散大家注意力,此处的代码就省略了!}//初始化定时器0void init_tmr0(void){ TMOD = 0x01;//设置tmr0为工作方式1 EA = 1;//开总中断 ET0 = 1;//开定时器0中断 TH0 = (65535u - tmr0_value) >> 8;//得到高8位 TL0 = (65536u - tmr0_value) & 0x00ff;//得到低8位 TR0 = 1;//启动定时器0     return;}//注:定时器溢出后若没重装初值就重新从0开始计数(0—65535)//计数到65536就溢出!void tmr0(void) interrupt 1//定时器0中断{       TR0 = 0;//关闭定时器0    //重新给定时器0赋初值    TH0 = (65536u - tmr0_value) >> 8;    TL0 = (65536u - tmr0_value) & 0x00ff;    key_value = scan_MatrixKey();//扫描矩阵键盘    TR0 = 1;//启动定时器0     return;}//数码管静态显示函数(i对应段选,j对应位选)               void digitron_static_display(u8 i u8 j){     if (i>=0 && i<=15u)//过滤除键值以外的数值    {        P0 = segment;        P2 = position[j];    }     return; }void rough_delay_1ms(u16 t)//粗略延时t毫秒{    u16 i;    for (; t>0; --t)    {        for (i=115u; i>0; --i);    }        return;}        现象:注销主程序里的while(1)循环里的延时后,按键非常灵敏,很难出错!但延时20ms后,按 按键 就经常没反应,有时要按好几次才有反应;延时100ms的话,按键几乎就很难有反应了,按半天都没动静!       困惑:理论上,用定时器定期扫描的方法应该和主程 while(1)循环里的代码无关呀,这种异常现象是怎么回事呀?急求高人解答啊!