maomaomao007 发表于 2011-9-22 10:06:51

移植马潮老师的键扫函数,却没有效果,请大家帮忙找找

最近在看马潮老师:< AVR单片机嵌入式系统原理与应用实践>一书,我将其中的矩阵键盘扫描函数按照马老师的方法,移植到AT89S52芯片,写了个键测试函数,用以测试新做的键盘和液晶板,可是没有效果,程序贴出来了,自己水平有限,找了数天找不出原因,拜请大侠帮小弟找找.(注:我想硬件电路应没错,因为其它的键扫都有效果)
#define U8 unsigned char
#define U16 unsigned int
#define NULL 0
#define KEY_INPORT P1

键扫程序:/*-------------------在此定义扫描函数的全局变量---------------------------*/
static U8 data sg_keyState = 0;//按键状态,状态0,1,2
static U8 data sg_lineScan; //行扫描
static U8 data sg_keyCol;        //变量用以读取列值
U8 data g_keyValue = 255;        //扫描得到的键值




/*-------------------在此定义键扫函数---------------------------*/
//===============================================================
//        Name   : uchar ScanKeyboard()
//Fuction:        4*4矩阵键盘键扫描函数,返回键值
//        备注:    按键释放才返回键值,否则,返回255(即没有键按下的键值)
//===============================================================
#define KEY_ORIGIN 0x0f
U8 ScanKeyboard()
{
        static U8 data s_keyReturn = 255;//无键按下//版本1.1
        U8 data i = 0;
        switch (sg_keyState)
        {
                case 0 :                                //零状态
                {
                        KEY_INPORT = KEY_ORIGIN; //发P1原始状态00001111
                        sg_keyCol = KEY_INPORT & 0x0f; //读回列值
                        if (sg_keyCol != KEY_ORIGIN) //有键按下
                        {
                               sg_keyState++;        //转状态1
                          sg_lineScan = 0x80;//行扫描开始,行线要依次输出低电平,因为keil中移位运算符是补零,所以取0x80= 10000000,取反为01111111
                                KEY_INPORT = ~sg_lineScan;          // P1=0x07,(01111111)        行线依次输出低电平
                                for (i = 0; i < 5; i++)                //逐行扫描,即使行线依次输出低电平
                                {
                                        sg_keyCol = KEY_INPORT & 0x0f;//读回列值,其有按键按下,则连接按键的那根列线通过按键被行线低电平拉低
                                        if (sg_keyCol == KEY_ORIGIN) //没扫描到按键,继续扫描
                                        {
                                               sg_lineScan >>= 1; ////右移,左端补零,而不是补1,所以,行扫描要取反初值本应是0x7f,不得不取反为0x80
                                                KEY_INPORT = ~sg_lineScan;
                                        }
                                        else {sg_lineScan = KEY_INPORT & 0xf0; break;}        //扫描到按键,保存按键列信息在keyCol        ,行信息在lineScan
                                }
                        }
                        break; //无按键按下,返回
                }
                case 1 :
                {
                       if (KEY_INPORT == (sg_lineScan | sg_keyCol))// 仍是同一按键
                        {
                                switch (sg_lineScan | sg_keyCol) // 行码与列码合成键码(XXXX0000 | 0000XXXX) = XXXXXXXX
                                { //switch002
                                        case 0x77 :
                                                s_keyReturn = 0;       //0键
                                                break;
                                        case 0x7b :
                                                s_keyReturn = 1;       //1键
                                                break;
                                        case 0x7d :
                                                s_keyReturn = 2;       //2键
                                                break;
                                        case 0x7e :
                                                s_keyReturn = 3;       //3键
                                                break;
                                        case 0xb7 :
                                                s_keyReturn = 4;       //4键
                                                break;
                                        case 0xbb :
                                                s_keyReturn = 5;    //5键
                                                break;
                                        case 0xbd :
                                                s_keyReturn = 6;       //6键
                                                break;
                                        case 0xbe :
                                                s_keyReturn = 7;       //7键
                                                break;
                                        case 0xd7 :
                                                s_keyReturn = 8;       //8键
                                                break;
                                        case 0xdb :
                                                s_keyReturn = 9;       //9键
                                                break;
                                        case 0xdd :
                                                s_keyReturn = 10;       //a键
                                                break;
                                        case 0xde :
                                                s_keyReturn = 11;       //b键
                                                break;
                                        case 0xe7:
                                                s_keyReturn = 12;       //c键
                                                break;
                                        case 0xeb :
                                                s_keyReturn = 13;       //d键
                                                break;
                                        case 0xed:
                                                s_keyReturn = 14;       //e键
                                                break;
                                        case 0xee:
                                                s_keyReturn = 15;       //f键
                                                break;
                                        default :break;
                                }//end of switch002
                                sg_keyState++;//转状态2
                                       
                        }
                        else
                        {
                                sg_keyState = 0;//两次按键不同,返回状态1
                        }
                        break;

                }
                case 2 :
                        KEY_INPORT = KEY_ORIGIN;//发按键端口原始状态
                        KEY_INPORT = KEY_ORIGIN;//再发一次按键端口原始状态
                        if ((KEY_INPORT & 0x0f) == KEY_ORIGIN)//读列线,
                        {       
                                sg_keyState = 0;       //按键已释放,转0状态
                                   return s_keyReturn;               //版本1.1添加语句
                        }
                        break;
                       
        }//switch
        return 255;               
}


别外附上硬件连接图:
http://cache.amobbs.com/bbs_upload782111/files_46/ourdev_678525TF0MSB.JPG
(原文件名:未命名2.JPG)

w71057178 发表于 2011-9-22 11:16:56

51是要上拉电阻的。

maomaomao007 发表于 2011-9-22 16:50:30

回复【1楼】w71057178 熊猫
51是要上拉电阻的。
-----------------------------------------------------------------------

接了上拉电阻的,,图形只传了部分

sbk100 发表于 2011-9-22 20:41:18

把s_keyReturn前面的static去掉
页: [1]
查看完整版本: 移植马潮老师的键扫函数,却没有效果,请大家帮忙找找