找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1803|回复: 11
打印 上一主题 下一主题
收起左侧

哪位大神可以帮忙求解?单片机矩阵键盘程序问题

[复制链接]
跳转到指定楼层
楼主
ID:798494 发表于 2020-8-5 14:06 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
        最近刚刚开始学单片机,看的是郭天祥师傅的视频教程。但是买的开发板是普中科技的。所以写了一个矩阵按键的程序。但是出错了。求各位大神解答。谢谢了?问题故障是:按键按下一个之后,八个数码管会显示对应的数字。但是第二次按下别的按键。就没有反应了。(附件为开发板的原理图)        以下是本人写的程序:
#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char

sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
uchar num;

uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};

void delay(uint z);
void ruixiang(uchar num);
void keykey();

void keykey()
{
        uchar temp,key;
        P1=0x7f;
        temp=P1;
        temp=temp&0x0f;
        if(temp!=0x0f)
        {
                delay(10);
                temp=P1;
                temp=temp&0x0f;
                if(temp!=0x0f)
                {
                        switch(temp)
                        {
                                case 0x77:key=0;break;
                                case 0x7b:key=1;break;
                                case 0x7d:key=2;break;
                                case 0x7e:key=3;break;
                        }
                        while(temp!=temp&0x0f)
                        {
                                temp=P1;
                                temp=temp&0x0f;        
                        }        
                        ruixiang(key);
                }
        }
        P1=0xbf;
        temp=P1;
        temp=temp&0x0f;
        if(temp!=0x0f)
        {
                delay(10);
                temp=P1;
                temp=temp&0x0f;
                if(temp!=0x0f)
                {
                        switch(temp)
                        {
                                case 0xb7:key=4;break;
                                case 0xbb:key=5;break;
                                case 0xbd:key=6;break;
                                case 0xbe:key=7;break;
                        }
                        while(temp!=temp&0x0f)
                        {
                                temp=P1;
                                temp=temp&0x0f;        
                        }        
                        ruixiang(key);
                }
        }
        P1=0xdf;
        temp=P1;
        temp=temp&0x0f;
        if(temp!=0x0f)
        {
                delay(10);
                temp=P1;
                temp=temp&0x0f;
                if(temp!=0x0f)
                {
                        switch(temp)
                        {
                                case 0xd7:key=8;break;
                                case 0xdb:key=9;break;
                                case 0xdd:key=10;break;
                                case 0xde:key=11;break;
                        }
                        while(temp!=temp&0x0f)
                        {
                                temp=P1;
                                temp=temp&0x0f;        
                        }        
                        ruixiang(key);
                }
        }
        P1=0xef;
        temp=P1;
        temp=temp&0x0f;
        if(temp!=0x0f)
        {
                delay(10);
                temp=P1;
                temp=temp&0x0f;
                if(temp!=0x0f)
                {
                        switch(temp)
                        {
                                case 0xe7:key=12;break;
                                case 0xeb:key=13;break;
                                case 0xed:key=14;break;
                                case 0xee:key=15;break;
                        }
                        while(temp!=temp&0x0f)
                        {
                                temp=P1;
                                temp=temp&0x0f;        
                        }        
                        ruixiang(key);
                }
        }
}

void ruixiang(uchar num)
{                                                                                                                                                           
        while(1)
        {
                LSA=0;LSB=0;LSC=0;
                P0=table[num];
                delay(1);
                P0=0x00;
                LSA=1;LSB=0;LSC=0;
                P0=table[num];
                delay(1);
                P0=0x00;
                LSA=0;LSB=1;LSC=0;
                P0=table[num];
                delay(1);
                P0=0x00;
                LSA=1;LSB=1;LSC=0;
                P0=table[num];
                delay(1);
                P0=0x00;
                LSA=0;LSB=0;LSC=1;
                P0=table[num];
                delay(1);
                P0=0x00;
                LSA=1;LSB=0;LSC=1;
                P0=table[num];
                delay(1);
                P0=0x00;
                LSA=0;LSB=1;LSC=1;
                P0=table[num];
                delay(1);
                P0=0x00;
                LSA=1;LSB=1;LSC=1;
                P0=table[num];
                delay(1);
                P0=0x00;
        }
}

void delay(uint z)
{
        uint a,b;
        for(a=z;a>0;a--)
                for(b=110;b>0;b--);
}

void mian()
{
        while(1)
        {
                keykey();
        }        
}




A2开发板原理图.pdf

227.86 KB, 下载次数: 5

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:807712 发表于 2020-8-5 14:24 | 只看该作者
普中内有视频与代码,为何不先看看再说呢?
回复

使用道具 举报

板凳
ID:332444 发表于 2020-8-5 14:26 | 只看该作者
若函数实现写在void mian()之后则要在void mian()之前写原形函数,若函数实现写在void mian()之前则不需要写函数原形;学这样的矩阵代码看着都眼花,理解起来也好似显得不易;不如学其他的矩阵代码既简洁又容易理解,可参https://blog.csdn.net/xianfajushi/article/details/80884859
回复

使用道具 举报

地板
ID:332444 发表于 2020-8-5 14:35 | 只看该作者
回复

使用道具 举报

5#
ID:798494 发表于 2020-8-5 15:14 | 只看该作者
塞北江南 发表于 2020-8-5 14:24
普中内有视频与代码,为何不先看看再说呢?

普中的视频代码我都看过了。他们的是矩阵按键扫描逻辑我也看懂了。但是我想弄一个就是基于郭天祥那边的程序格式。另外因为两个开发板线路不同,所以也想试试自己写一个逻辑跟普中教程不一样的程序。
回复

使用道具 举报

6#
ID:798494 发表于 2020-8-5 15:36 | 只看该作者
xianfajushi 发表于 2020-8-5 14:26
若函数实现写在void mian()之后则要在void mian()之前写原形函数,若函数实现写在void mian()之前则不需要 ...

感谢老板们的支持!
回复

使用道具 举报

7#
ID:213173 发表于 2020-8-5 20:48 | 只看该作者
楼主这个程序根本就不可能运行!首先是主函数名写错void mian(),正确写法是void main(),其次是显示函数体是死循环while(1),被按键函数执行一次就出不来。不论是郭天祥的还是普中的示例矩阵键盘扫描函数只是为说明一个基本原理,实战中不宜采用。给你一个适用于你的开发板的 4*4矩阵键盘示例参考,有详细注释,不难理解。
  1. #include <reg52.h>
  2. #define uint unsigned int
  3. #define uchar unsigned char
  4. /*
  5. sbit LSA=P2^2;
  6. sbit LSB=P2^3;
  7. sbit LSC=P2^4;
  8. */
  9. uchar KeyValue;                //键值变量
  10. uchar num=0;                //数码管位计数变量
  11. bit   sign=0;                //按键标志位变量
  12. uchar count=0;                //消抖计数变量       
  13. uchar code table[]={//0~15共阴数码管段码数组
  14.         0x3f,0x06,0x5b,0x4f,
  15.         0x66,0x6d,0x7d,0x07,
  16.         0x7f,0x6f,0x77,0x7c,
  17.         0x39,0x5e,0x79,0x71};
  18. uchar data dis_buf[8]={0,0,0,0,0,0,0,0};//缓存数组
  19. void keyscan();
  20. void display();
  21. void delay(uint z);

  22. void keyscan()                                        //矩阵按键扫描程序
  23. {
  24.         P1=0xf0;                                        //赋值P1 1111 0000
  25.         if(P1!=0xf0)                                //检测有按键按下
  26.         {
  27.                 if((++count>=10)&&(sign==0))//消抖计数10ms与判断按键状态
  28.                 {                       
  29.                         sign=1;                        //按键状态标志置1
  30.                         switch(P1)
  31.                         {
  32.                                 case(0Xe0):KeyValue = 0;break;
  33.                                 case(0Xd0):KeyValue = 1;break;
  34.                                 case(0Xb0):KeyValue = 2;break;
  35.                                 case(0X70):KeyValue = 3;break;
  36.                         }
  37.                         P1=0x0f;                        //赋值P1 0000 1111
  38.                         switch(P1)
  39.                         {
  40.                                 case(0X0e):KeyValue+= 1;break;
  41.                                 case(0X0d):KeyValue+= 5;break;
  42.                                 case(0X0b):KeyValue+= 9;break;
  43.                                 case(0X07):KeyValue+=13;break;
  44.                         }
  45.                 }
  46.         }
  47.         else                                                //键抬起
  48.         {
  49.                 sign=0;                                //按键状态标志清0
  50.                 count=0;                                //消抖计数清0
  51.         }
  52. }

  53. void display()        //数码管显示程序
  54. {                                                                                                                                         
  55.         dis_buf[0]=table[KeyValue%10];//分解键值个位
  56.         dis_buf[1]=table[KeyValue/10];//分解键值十位
  57. //        dis_buf[2]=
  58. //        dis_buf[3]=
  59. //        dis_buf[4]=
  60. //        dis_buf[5]=
  61. //        dis_buf[6]=
  62. //        dis_buf[7]=

  63.         P0=0x00;                //段码消隐
  64.         P2&=0xe3;                //位码清0
  65.         P0=dis_buf[num];//送段码
  66.         P2|=num<<2;                //送位码
  67.         num++;                        //位计数
  68.         num%=8;
  69. }

  70. void delay(uint z)
  71. {
  72.         uint a,b;
  73.         for(a=z;a>0;a--)
  74.                 for(b=110;b>0;b--);
  75. }

  76. void main()
  77. {
  78.         while(1)
  79.         {
  80.                 keyscan();
  81.                 display();
  82.                 delay(1);//控制主循环周期约1ms
  83.         }        
  84. }

复制代码




回复

使用道具 举报

8#
ID:798494 发表于 2020-8-6 09:08 | 只看该作者
wulin 发表于 2020-8-5 20:48
楼主这个程序根本就不可能运行!首先是主函数名写错void mian(),正确写法是void main(),其次是显示函数体 ...

感谢大佬的支持,非常感谢!可否后续继续关注我?可以交学费。嗯嗯还是感谢老板做我的明灯
回复

使用道具 举报

9#
ID:798494 发表于 2020-8-6 14:12 | 只看该作者
wulin 发表于 2020-8-5 20:48
楼主这个程序根本就不可能运行!首先是主函数名写错void mian(),正确写法是void main(),其次是显示函数体 ...

你好 !您能帮帮我指出那个地方有问题吗?
然后能不能跟我讲一下哪儿改一下  可以让这个程序跑起来
回复

使用道具 举报

10#
ID:462827 发表于 2020-8-6 19:43 | 只看该作者
你这个矩阵按键扫描和数码管显示的函数都写得太长了吧,至少可以缩短一半以上。
回复

使用道具 举报

11#
ID:213173 发表于 2020-8-7 06:49 | 只看该作者
Judehan 发表于 2020-8-6 14:12
你好 !您能帮帮我指出那个地方有问题吗?
然后能不能跟我讲一下哪儿改一下  可以让这个程序跑起来

给你改正main()函数名,去掉显示函数中的死循环 while(1),去掉按键函数中的错误和赘句,把显示函数放在主函数中可以勉强跑起来,但离实用还有很大距离。下面注释掉的部分基本都是错误的或与错误相关。
  1. #include <reg52.h>
  2. #define uint unsigned int
  3. #define uchar unsigned char

  4. sbit LSA=P2^2;
  5. sbit LSB=P2^3;
  6. sbit LSC=P2^4;
  7. uchar num;
  8. uchar key;
  9. uchar code table[]={
  10. 0x3f,0x06,0x5b,0x4f,
  11. 0x66,0x6d,0x7d,0x07,
  12. 0x7f,0x6f,0x77,0x7c,
  13. 0x39,0x5e,0x79,0x71};

  14. void delay(uint z);
  15. void ruixiang(uchar num);
  16. void keykey();

  17. void keykey()
  18. {
  19. //        uchar temp,key;
  20.         uchar temp;
  21.         P1=0x7f;
  22.         temp=P1;
  23. //        temp=temp&0x0f;
  24. //        if(temp!=0x0f)
  25.         if(temp!=0x7f)
  26.         {
  27.                 delay(10);
  28. //                temp=P1;
  29. //                temp=temp&0x0f;
  30. //                if(temp!=0x0f)
  31.                 if(temp!=0x7f)
  32.                 {
  33.                         switch(temp)
  34.                         {
  35.                                 case 0x77:key=0;break;
  36.                                 case 0x7b:key=1;break;
  37.                                 case 0x7d:key=2;break;
  38.                                 case 0x7e:key=3;break;
  39.                         }
  40.                         while(P1!=0x7f);
  41. //                        while(temp!=temp&0x0f)
  42. //                        {
  43. //                                temp=P1;
  44. //                                temp=temp&0x0f;        
  45. //                        }        
  46. //                        ruixiang(key);
  47.                 }
  48.         }
  49.         P1=0xbf;
  50.         temp=P1;
  51. //        temp=temp&0x0f;
  52. //        if(temp!=0x0f)
  53.         if(temp!=0xbf)
  54.         {
  55.                 delay(10);
  56. //                temp=P1;
  57. //                temp=temp&0x0f;
  58. //                if(temp!=0x0f)
  59.                 if(temp!=0xbf)
  60.                 {
  61.                         switch(temp)
  62.                         {
  63.                                 case 0xb7:key=4;break;
  64.                                 case 0xbb:key=5;break;
  65.                                 case 0xbd:key=6;break;
  66.                                 case 0xbe:key=7;break;
  67.                         }
  68.                         while(P1!=0xbf);
  69. //                        while(temp!=temp&0x0f)
  70. //                        {
  71. //                                temp=P1;
  72. //                                temp=temp&0x0f;
  73. //                        }        
  74. //                        ruixiang(key);
  75.                 }
  76.         }
  77.         P1=0xdf;
  78.         temp=P1;
  79. //        temp=temp&0x0f;
  80. //        if(temp!=0x0f)
  81.         if(temp!=0xdf)
  82.         {
  83.                 delay(10);
  84. //                temp=P1;
  85. //                temp=temp&0x0f;
  86. //                if(temp!=0x0f)
  87.                 if(temp!=0xdf)
  88.                 {
  89.                         switch(temp)
  90.                         {
  91.                                 case 0xd7:key=8;break;
  92.                                 case 0xdb:key=9;break;
  93.                                 case 0xdd:key=10;break;
  94.                                 case 0xde:key=11;break;
  95.                         }
  96.                         while(P1!=0xdf);
  97. //                        while(temp!=temp&0x0f)
  98. //                        {
  99. //                                temp=P1;
  100. //                                temp=temp&0x0f;        
  101. //                        }        
  102. //                        ruixiang(key);
  103.                 }
  104.         }
  105.         P1=0xef;
  106.         temp=P1;
  107. //        temp=temp&0x0f;
  108. //        if(temp!=0x0f)
  109.         if(temp!=0xef)
  110.         {
  111.                 delay(10);
  112. //                temp=P1;
  113. //                temp=temp&0x0f;
  114. //                if(temp!=0x0f)
  115.                 if(temp!=0xef)
  116.                 {
  117.                         switch(temp)
  118.                         {
  119.                                 case 0xe7:key=12;break;
  120.                                 case 0xeb:key=13;break;
  121.                                 case 0xed:key=14;break;
  122.                                 case 0xee:key=15;break;
  123.                         }
  124.                         while(P1!=0xef);
  125. //                        while(temp!=temp&0x0f)
  126. //                        {
  127. //                                temp=P1;
  128. //                                temp=temp&0x0f;        
  129. //                        }        
  130. //                        ruixiang(key);
  131.                 }
  132.         }
  133. }

  134. void ruixiang(uchar num)
  135. {
  136. //        while(1)
  137. //        {
  138.         LSA=0;LSB=0;LSC=0;
  139.         P0=table[num];
  140.         delay(1);
  141.         P0=0x00;
  142.         LSA=1;LSB=0;LSC=0;
  143.         P0=table[num];
  144.         delay(1);
  145.         P0=0x00;
  146.         LSA=0;LSB=1;LSC=0;
  147.         P0=table[num];
  148.         delay(1);
  149.         P0=0x00;
  150.         LSA=1;LSB=1;LSC=0;
  151.         P0=table[num];
  152.         delay(1);
  153.         P0=0x00;
  154.         LSA=0;LSB=0;LSC=1;
  155.         P0=table[num];
  156.         delay(1);
  157.         P0=0x00;
  158.         LSA=1;LSB=0;LSC=1;
  159.         P0=table[num];
  160.         delay(1);
  161.         P0=0x00;
  162.         LSA=0;LSB=1;LSC=1;
  163.         P0=table[num];
  164.         delay(1);
  165.         P0=0x00;
  166.         LSA=1;LSB=1;LSC=1;
  167.         P0=table[num];
  168.         delay(1);
  169.         P0=0x00;
  170. //        }
  171. }
  172. void delay(uint z)
  173. {
  174.         uint a,b;
  175.         for(a=z;a>0;a--)
  176.                 for(b=110;b>0;b--);
  177. }
  178. //void mian()
  179. void main()
  180. {
  181.         while(1)
  182.         {
  183.                 keykey();
  184.                 ruixiang(key);
  185.         }        
  186. }

复制代码
回复

使用道具 举报

12#
ID:808700 发表于 2020-8-7 16:34 | 只看该作者
Judehan 发表于 2020-8-6 09:08
感谢大佬的支持,非常感谢!可否后续继续关注我?可以交学费。嗯嗯还是感谢老板做我的明灯

如果需要长期指点的话,可私聊我
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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