搜索
bottom↓
回复: 3

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

[复制链接]

出0入0汤圆

发表于 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;               
}


别外附上硬件连接图:

(原文件名:未命名2.JPG)

出0入0汤圆

发表于 2011-9-22 11:16:56 | 显示全部楼层
51是要上拉电阻的。

出0入0汤圆

 楼主| 发表于 2011-9-22 16:50:30 | 显示全部楼层
回复【1楼】w71057178 熊猫
51是要上拉电阻的。
-----------------------------------------------------------------------

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

出0入0汤圆

发表于 2011-9-22 20:41:18 | 显示全部楼层
把s_keyReturn前面的static去掉
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-20 12:57

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表