找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机4x4键盘的数码管程序 显示异常 现在只有长按才能显示对应的01,02

[复制链接]
跳转到指定楼层
楼主
ID:1068026 发表于 2023-4-2 14:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
请大佬们帮忙看看吧!我想实现4x4键盘,使用数码管显示对应的数字,现在只有长按才能显示对应的01,02,改咋改好,谢谢大佬们的解答了

单片机源程序如下:
  1. #include<reg51.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int   
  4. sbit L1=P1^0;                                                            //定义键盘的4列线
  5. sbit L2=P1^1;
  6. sbit L3=P1^2;
  7. sbit L4=P1^3;
  8. uchar dis[16]={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
  9. void delay_ms(unsigned int n);
  10. uint n;
  11. uchar a;
  12. uchar b;
  13. uchar c;
  14. uchar d;

  15. void main()                                                            //主程序
  16.         {
  17.                 uchar temp;
  18.                 uchar i;
  19.                 while(1)
  20.                 {
  21.                         P1=0xef;                                            //行扫描初值,P1.4=0,P1.5~P1.7=1
  22.                         for(i=0;i<=3;i++)                            //按行扫描,一共4行
  23.                         {
  24.                                 if(L1==0) {
  25.                                     a=i*4+0;
  26.                                     switch (a)
  27.                                     {
  28.                                     case 0:while(1){P3=0x04;P2=dis[a/10%10];delay_ms(1000);P3=0x08;P2=dis[a%10];delay_ms(1000);};break;
  29.                                     case 4:while(1){P3=0x04;P2=dis[a/10%10];delay_ms(1000);P3=0x08;P2=dis[a%10];delay_ms(1000);break;};break;
  30.                                     case 8:while(1){P3=0x04;P2=dis[a/10%10];delay_ms(1000);P3=0x08;P2=dis[a%10];delay_ms(1000);break;};break;
  31.                                     case 12:while(1){P3=0x04;P2=dis[a/10%10];delay_ms(1000);P3=0x08;P2=dis[a%10];delay_ms(1000);break;};break;
  32.                                     }
  33.                                     }        //判断第一列是否有键按下
  34.                                 if(L2==0){
  35.                                     b=i*4+1;
  36.                                     switch (b)
  37.                                     {
  38.                                     case 1:while(1){P3=0x04;P2=dis[b/10%10];delay_ms(1000);P3=0x08;P2=dis[b%10];delay_ms(1000);break;};break;
  39.                                     case 5:while(1){P3=0x04;P2=dis[b/10%10];delay_ms(1000);P3=0x08;P2=dis[b%10];delay_ms(1000);break;};break;
  40.                                     case 9:while(1){P3=0x04;P2=dis[b/10%10];delay_ms(1000);P3=0x08;P2=dis[b%10];delay_ms(1000);break;};break;
  41.                                     case 13:while(1){P3=0x04;P2=dis[b/10%10];delay_ms(1000);P3=0x08;P2=dis[b%10];delay_ms(1000);break;};break;

  42.                                     }
  43.                                     }         //判断第二列是否有键按下
  44.                                 if(L3==0){
  45.                                     c=i*4+2;
  46.                                     switch (c)
  47.                                     {
  48.                                     case 2:while(1){P3=0x04;P2=dis[c/10%10];delay_ms(1000);P3=0x08;P2=dis[c%10];delay_ms(1000);break;};break;
  49.                                     case 6:while(1){P3=0x04;P2=dis[c/10%10];delay_ms(1000);P3=0x08;P2=dis[c%10];delay_ms(1000);break;};break;
  50.                                     case 10:while(1){P3=0x04;P2=dis[c/10%10];delay_ms(1000);P3=0x08;P2=dis[c%10];delay_ms(1000);break;};break;
  51.                                     case 14:while(1){P3=0x04;P2=dis[c/10%10];delay_ms(1000);P3=0x08;P2=dis[c%10];delay_ms(1000);break;};break;
  52.                                     }
  53.                                 }        //判断第三列是否有键按下
  54.                                 if(L4==0){
  55.                                     d=i*4+3;
  56.                                     switch (d)
  57.                                     {
  58.                                     case 3:while(1){P3=0x04;P2=dis[d/10%10];delay_ms(1000);P3=0x08;P2=dis[d%10];delay_ms(1000);break;};break;
  59.                                     case 7:while(1){P3=0x04;P2=dis[d/10%10];delay_ms(1000);P3=0x08;P2=dis[d%10];delay_ms(1000);break;};break;
  60.                                     case 11:while(1){P3=0x04;P2=dis[d/10%10];delay_ms(1000);P3=0x08;P2=dis[d%10];delay_ms(1000);break;};break;
  61.                                     case 15:while(1){P3=0x04;P2=dis[d/10%10];delay_ms(1000);P3=0x08;P2=dis[d%10];delay_ms(1000);break;};break;
  62.                                     }
  63.                                 }         //判断第四列是否有键按下
  64.                                 delay_ms(50);                                //延时
  65.                                 temp=P1;                                        //读入P1口状态
  66.                                 temp=temp|0x0f;                        //使P1.3~P1.0为输入
  67.                                 temp=temp<<1;                        //P1.7~P1.4左移1位,准备下一行扫描
  68.                                 temp=temp|0x0f;                        //移位后,置P1.3~P1.0为1,保证其仍为输入
  69.                                 P1=temp;                                        //行扫描值送P1口,为下一行扫描做准备
  70.                         }
  71.                 }
  72.         }
  73. void delay_ms(unsigned int n)
  74. {
  75. {
  76.     while(n--);
  77. }
  78. }
复制代码


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

使用道具 举报

沙发
ID:332444 发表于 2023-4-3 07:56 | 只看该作者
如果觉得不好用就学别的矩阵扫描方法
回复

使用道具 举报

板凳
ID:59202 发表于 2023-4-3 09:03 | 只看该作者
这程序简直是太酸爽了,是楼主自己写的吗?还是别改了,到网上搜一下别人写的程序,再把编程思想想明白了就会获益良多的
回复

使用道具 举报

地板
ID:161164 发表于 2023-4-3 12:33 | 只看该作者
变量名不要用a,b,c,d!
变量名不要用a,b,c,d!
变量名不要用a,b,c,d!

在群里问了几次都不贴全部代码
现在终于表弄明白那个for是怎么运作的

  1. #include <reg51.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. sbit L1=P1^0;                                                            //定义键盘的4列线
  5. sbit L2=P1^1;
  6. sbit L3=P1^2;
  7. sbit L4=P1^3;
  8. uchar dis[16]= { 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
  9. uchar dispbuf[2] = {0,0};
  10. void delay_ms(unsigned int n);
  11. uint n;
  12. uchar KeyVal;

  13. void main()                                                            //主程序
  14. {
  15.     uchar temp;
  16.     uchar i;
  17.     while(1)
  18.     {
  19.         //******display******************
  20.         P2=0xFF;
  21.         P3=0x04;
  22.         P2=dis[dispbuf[1]];
  23.         delay_ms(1000);
  24.         P2=0xFF;
  25.         P3=0x08;
  26.         P2=dis[dispbuf[0]];
  27.         delay_ms(1000);
  28.         //******display******************

  29.         //******Keypad scan******************
  30.         P1=0xef;                                            //行扫描初值,P1.4=0,P1.5~P1.7=1
  31.         for(i=0; i<=3; i++)                          //按行扫描,一共4行
  32.         {
  33.             if(L1==0)
  34.             {
  35.                 KeyVal=i*4+0;
  36.             }        //判断第一列是否有键按下
  37.             if(L2==0)
  38.             {
  39.                 KeyVal=i*4+1;
  40.             }
  41.             if(L3==0)
  42.             {
  43.                 KeyVal=i*4+2;
  44.             }
  45.             if(L4==0)
  46.             {
  47.                 KeyVal=i*4+3;
  48.             }
  49.             dispbuf[1]=KeyVal/10%10;
  50.             dispbuf[0]=KeyVal%10;
  51.             delay_ms(50);                                //延时
  52.             temp=P1;                                        //读入P1口状态
  53.             temp=temp|0x0f;                        //使P1.3~P1.0为输入
  54.             temp=temp<<1;                        //P1.7~P1.4左移1位,准备下一行扫描
  55.             temp=temp|0x0f;                        //移位后,置P1.3~P1.0为1,保证其仍为输入
  56.             P1=temp;                                        //行扫描值送P1口,为下一行扫描做准备
  57.         }
  58.         //******Keypad scan******************
  59.     }

  60. }

  61. void delay_ms(unsigned int n)
  62. {
  63.     {
  64.         while(n--);
  65.     }
  66. }
复制代码




回复

使用道具 举报

5#
ID:1068026 发表于 2023-4-3 15:01 | 只看该作者
lkc8210 发表于 2023-4-3 12:33
变量名不要用a,b,c,d!
变量名不要用a,b,c,d!
变量名不要用a,b,c,d!

好的好的,谢谢大佬
回复

使用道具 举报

6#
ID:1068026 发表于 2023-4-3 15:01 | 只看该作者
xxxevery 发表于 2023-4-3 09:03
这程序简直是太酸爽了,是楼主自己写的吗?还是别改了,到网上搜一下别人写的程序,再把编程思想想明白了就 ...

谢谢,已经想明白了,用for循环重新写了一个
回复

使用道具 举报

7#
ID:1068026 发表于 2023-4-3 15:02 | 只看该作者
xianfajushi 发表于 2023-4-3 07:56
如果觉得不好用就学别的矩阵扫描方法

好的好的,谢谢建议
回复

使用道具 举报

8#
ID:69038 发表于 2023-4-4 09:55 | 只看该作者
char 矩阵4X4键扫()//行、列全都上拉
{
行全输出低;
读列值;//Key_L4
列值全为高,则无键入,返回0;//退出;
列值不全为高
{
  简单延时;
  再读列值不全为高,确认是有键入
   {
    列全输出低;
    读行值;//Key_H4
    while(读行值不全为高)
  {
     简单延时;
     Kt++;//此处可加入按键计数,用于判断长短按=>静态变量Kt可视为按键时长
   }  返回 (Key_H4+Key_L4);//退出;
  }
  
返回0;//退出;
}
}
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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