打印

求助4×4键盘扫描简单程序,运行不起来。

[复制链接]
4254|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主

电路图,
想做个简单的键盘输入数字1-9,在LED上显示对应的值。
//4×4键盘。P1口接7segLED,p3口接键盘,导入下面code无法显示,大家帮忙修改一下。谢谢了
#include <REGX52.H>
const unsigned char code seg7code[16] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d,
                                                                                 0x7d, 0x07, 0x7f, 0x6f, 0x77,
                                                                                 0x7c, 0x39, 0x5e, 0x79, 0x71};
const unsigned char code KeyTable[16] = {0xee, 0xde, 0xbe, 0x7e,   //0,1,2,3
                                                                                 0xed, 0xdd, 0xbd, 0x7d,   //4,5,6,7
                                                                             0xeb, 0xdb, 0xbb, 0x7b,   //8,9,A,B
                                                                                 0xe7, 0xd7, 0xb7, 0x77};  //C,D,E,F

unsigned char keyscan(void);
void delay(unsigned int);

void main(void)
{
        unsigned char i;
        unsigned char key;
        P1 = 0;
        while(1)
        {
                key = keyscan();
                i = 0;
                while(key != KeyTable[i++]);//查表,找到对应的i,然后显示输出
                P1 = seg7code[--i];
        }                       
}

unsigned char keyscan(void)        //行列反转扫描法
{
        unsigned char row_val, col_val;        //定义行,列
        P3 = 0x0f;
        col_val = P3 & 0x0f;
        if(col_val != 0x0f)
        {
                delay(100);
                if(col_val != 0x0f)
                {
                        col_val = P3 & 0x0f;
                        P3 = col_val | 0xf0;
                        row_val = P3 & 0xf0;
                        return (col_val | row_val);//组合行列键值。
                }
        }
        return 0xff;
}

void delay(unsigned int n)
{
        while(n--);
}

相关帖子

沙发
FDLock| | 2009-9-2 23:53 | 只看该作者
>  key = keyscan();
>  i = 0;
>  while(key != KeyTable[i++]);//查表,找到对应的i,然后显示输出

keyscan扫描到没有按键时返回0xFF,而在整个KeyTable表中都没有0xFF,则上面的查表将会出错(甚至死循环)。

使用特权

评论回复
板凳
soler_z|  楼主 | 2009-9-3 00:52 | 只看该作者
谢谢,明白了,那我的代码可以继续写下去了。

使用特权

评论回复
地板
soler_z|  楼主 | 2009-9-4 01:56 | 只看该作者
#include <REGX52.H>

#define KeybufSize 16 //键盘缓存大小

unsigned char KeyBuf[KeybufSize]; //键盘缓存数组,先进先出
unsigned char KeybufWp = 0;        //缓存写键值
unsigned char KeybufRp = 0;        //缓存读键值

unsigned char keyHit(void);        //函数判断是否有键按下
unsigned char keyGet(void);         //函数取键值
void keyPut(unsigned char ucKeyVal); //

const unsigned char code seg7code[] ={0x3f, 0x06, 0x5b, 0x4f,
                                        0x66, 0x6d,0x7d, 0x07,
                                        0x7f, 0x6f, 0x77,0x7c,
                                        0x39, 0x5e, 0x79, 0x71,0x00};  //seg7 com cathod
unsigned char keyScan(void); //键盘扫描,行列反转法

/*******************************************************************
p1口接7段LED,p2接键盘输入,p2.0~2.3接KEYPAD-SMALLCALC的行a,b,c,d脚
p2.4~2.7接4个列脚 ,单片机AT89C51,晶振频率12MHz
********************************************************************/
void main(void)
{
   
    TMOD = (TMOD & 0XF0) | 0X01; //定时器0,工作方式1
    EA = 1;                                                 //开中断允许
    ET0 = 1;
    TH0 = (-20000)>>8;                         //定时器0计时20ms
    TL0 = -20000;
    TR0 = 1;
    while(1)
    {
        if(keyHit() != 0)         //有键按下,输出显示。
            P1 = seg7code[keyGet()];
    }                        
}

/***********************************************************
利用T0内部中断来扫描键盘,20ms扫描一次,如有键按下,扫描键盘,
并存键盘缓存,如果按键松开,再判断有没有键按下。
************************************************************/
void timer0intr(void) interrupt 1
{
    static unsigned char sts = 0;
    TH0 = (-20000)>>8;
    TL0 = -20000;
        P2_0 = 1;         
    switch(sts)
    {
        case 0: if(keyScan() != 0)   //判断有无键按下,有则转入状态1
                    sts = 1;break;
        case 1: if(keyScan() == 0)        //如果按错,转回状态0
                    sts = 0;
                else
                {
                    sts = 2;
                    keyPut(keyScan());  //确认有键按下,转入状态2,并把键号写入缓存
                }
                break;
        case 2: if(keyScan() == 0)
                    sts = 3; break;         //判断按键松开,转入状态3
        case 3: if(keyScan() != 0)
                    sts = 2;
                else
                    sts = 0;         //确认按键已经松开,会状态0,否则回状态2,重新判断
                break;
    }  
}

/***********************************************************
                                 行列反转键盘扫描
************************************************************/

unsigned char keyScan( void ) //返回0表示无按键,或无效按键,其它值为按键编码值   
{
        code unsigned char keyCode[16]=   
        //0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF   
        { 0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   2,   0,   3,   4,   0 };   
         unsigned char x, y, retVal;   
         P1=0x0f;    //低四位输入,高四位输出0   
         x=P1&0x0f;   //P1输入后,清高四位,作为X值   
         P1=0xf0;    //高四位输入,低四位输出0   
         y=(P1 >> 4) & 0x0f; //P1输入后移位到低四位,并清高四位,作为Y值   
         retVal = keyCode[x]*4 + keyCode[y]; //根据本公式倒算按键编码   
         if( retVal==0 ) return(0);
        else return( retVal-4 );     
}   

unsigned char keyHit(void)  //判断是否有键按下。
{
     if(KeybufWp == KeybufRp)
        return 0;
    else return 1;
}

unsigned char keyGet(void)         //读取键值
{
    unsigned char retVal;//暂存读出键值
    while(!keyHit());
    retVal = KeyBuf[KeybufRp];
    if(++KeybufRp >= KeybufSize)
        KeybufRp = 0;
    return retVal;
}

void keyPut(unsigned char ucKeyVal)
{
     KeyBuf[KeybufWp] = ucKeyVal;//键值存入数组
    if(++KeybufWp >= KeybufSize)
        KeybufWp = 0;
}
哎,问题又来了,突然发现按下键盘之后显示的值完全不对,并且只能按一个键,
并且再也无法输入,不知道是哪的问题,大家帮忙看看吧。谢谢了。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

13

帖子

0

粉丝