找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1154|回复: 5
收起左侧

求助,写的单片机按键矩阵不能实现功能

[复制链接]
ID:376790 发表于 2020-1-17 16:34 | 显示全部楼层 |阅读模式
      写的是用定时器扫描矩阵按键,然后在数码管显示,可是代码不能实现功能,检查了几遍也没想明白哪里出错了,单片机小白,求助
  1. #include "reg52.h"
  2. #include "intrins.h"

  3. void anjian();

  4. unsigned int a,b;

  5. sbit KEY_IN1 = P3^7;
  6. sbit KEY_IN2 = P3^6;
  7. sbit KEY_IN3 = P3^5;
  8. sbit KEY_IN4 = P3^4;
  9. sbit KEY_OUT1 = P3^0;
  10. sbit KEY_OUT2 = P3^1;
  11. sbit KEY_OUT3 = P3^2;
  12. sbit KEY_OUT4 = P3^3;

  13. unsigned char code pucseg_code[] = {
  14.         0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8,
  15.         0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e
  16. };  //数码管显示段码

  17. /*unsigned char ledbuff[8] = {
  18.         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
  19. };*/

  20. unsigned char keysta[4][4] = {
  21.         {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}
  22. };   //矩阵按键当前状态

  23. void Delay1ms()                //@12.000MHz
  24. {
  25.         unsigned char i, j;

  26.         i = 12;
  27.         j = 169;
  28.         do
  29.         {
  30.                 while (--j);
  31.         } while (--i);
  32. }

  33. void Delay300us()                //@12.000MHz
  34. {
  35.         unsigned char i, j;

  36.         i = 4;
  37.         j = 125;
  38.         do
  39.         {
  40.                 while (--j);
  41.         } while (--i);
  42. }

  43. void cls_periphercal(void)                //系统初始化
  44. {
  45.         P0 = 0xff;
  46.         P2 = P2 & 0x1f | 0x80;
  47.         P2 = 0x1f;
  48.         P0 = 0;
  49.         P2 = P2 & 0x1f | 0xa0;
  50.         P2 = 0x1f;
  51.        
  52.        
  53. }

  54. void seg_disp(unsigned char pu, unsigned char ucseg_pos)   //数码管段选
  55. {       
  56.         P0 = 0xff;
  57.         P2 = P2 & 0x1f | 0xe0;
  58.         P2 &= 0x1f;
  59.         Delay300us();
  60.        
  61.         P0 = 0x80 >> ucseg_pos;
  62.         P2 = P2 & 0x1f | 0xc0;
  63.         P2 &= 0x1f;
  64.         Delay300us();
  65.        
  66.         P0 = pu;
  67.         P2 = P2 & 0x1f | 0xe0;
  68.         P2 &= 0x1f;
  69.         Delay300us();
  70. }

  71. void saomiao(unsigned char i)   //数码管循环刷新显示
  72. {
  73.         switch(i)
  74.         {
  75.                 case 0: seg_disp(pucseg_code[0], 0); break;
  76.                 case 1: seg_disp(pucseg_code[1], 1); break;
  77.                 case 2: seg_disp(pucseg_code[2], 2); break;
  78.                 case 3: seg_disp(pucseg_code[3], 3); break;
  79.                 case 4: seg_disp(pucseg_code[4], 4); break;
  80.                 case 5: seg_disp(pucseg_code[5], 5); break;
  81.                 case 6: seg_disp(pucseg_code[6], 6); break;
  82.                 case 7: seg_disp(pucseg_code[7], 7); break;
  83.         }
  84.        
  85. }


  86. /*void Timer0Init(void)                //2??@12.000MHz   //定时器定时2ms
  87. {
  88.         AUXR |= 0x80;                //?????1T??
  89.         TMOD &= 0xF0;                //???????
  90.         TL0 = 0x40;                //??????
  91.         TH0 = 0xA2;                //??????
  92.         TF0 = 0;                //??TF0??
  93.         TR0 = 1;                //???0????
  94.         ET0 = 1;
  95.         EA = 1;
  96. }*/

  97. void InterruptTimer0() interrupt 1
  98. {
  99.         unsigned char i;
  100.         static unsigned char keyout = 0;       //输出索引值
  101.         static unsigned char keybuf[4][4] = {  //扫描缓冲数组
  102.         {0xff, 0xff, 0xff, 0xff}, {0xff, 0xff, 0xff, 0xff},
  103.         {0xff, 0xff, 0xff, 0xff}, {0xff, 0xff, 0xff, 0xff}
  104.         };
  105.         TH0 = 0XFC;
  106.         TL0 = 0X67;
  107.        
  108.        
  109.         keybuf[keyout][0] = (keybuf[keyout][0] << 1) | P3^7;
  110.         keybuf[keyout][0] = (keybuf[keyout][0] << 1) | P3^6;
  111.         keybuf[keyout][0] = (keybuf[keyout][0] << 1) | P3^5;
  112.         keybuf[keyout][0] = (keybuf[keyout][0] << 1) | P3^4;
  113.        
  114.         for(i=0; i<4; i++)
  115.         {
  116.                 if((keybuf[keyout][i] & 0x0f) == 0x00)
  117.                         keysta[keyout][i] = 0;      //连续扫描四次4值为0,可以认为按键已经稳定按下或弹起
  118.                 else if((keybuf[keyout][i] & 0x0f) == 0x0f)
  119.                         keysta[keyout][i] = 1;
  120.         }
  121.        
  122.         keyout++;                     //索引值递增
  123.         keyout = keyout & 0x03;       //当索引值到4时归零
  124.         switch(keyout)          //根据索引值,释放当前输出引脚,拉低下次输出引脚
  125.         {
  126.                 case 0 : KEY_OUT4 = 1; KEY_OUT1 = 0; break;
  127.                 case 1 : KEY_OUT1 = 1; KEY_OUT2 = 0; break;
  128.                 case 2 : KEY_OUT2 = 1; KEY_OUT3 = 0; break;
  129.                 case 3 : KEY_OUT3 = 1; KEY_OUT4 = 0; break;
  130.                 default: break;
  131.         }
  132. }

  133. void anjian(void)                //判断按键按下的是哪一位
  134. {
  135.                                         if(b == 0 & a == 0)
  136.                                                 {
  137.                                                         saomiao(0);
  138.                                                         Delay1ms();
  139.                                                 }
  140.                                                 else if(b == 1 & a == 0)
  141.                                                 {
  142.                                                         saomiao(1);
  143.                                                         Delay1ms();
  144.                                                 }
  145.                                                 else if(b == 2 & a == 0)
  146.                                                 {
  147.                                                         saomiao(2);
  148.                                                         Delay1ms();
  149.                                                 }
  150.                                                 else if(b == 3 & a == 0)
  151.                                                 {
  152.                                                         saomiao(3);
  153.                                                         Delay1ms();
  154.                                                 }
  155.                                                 else if(b == 0 & a == 1)
  156.                                                 {
  157.                                                         saomiao(4);
  158.                                                         Delay1ms();
  159.                                                 }
  160.                                                 else if(b == 1 & a == 1)
  161.                                                 {
  162.                                                         saomiao(5);
  163.                                                         Delay1ms();
  164.                                                 }
  165.                                                 else if(b == 2 & a == 1)
  166.                                                 {
  167.                                                         saomiao(6);
  168.                                                         Delay1ms();
  169.                                                 }
  170.                                                 else if(b == 3 & a == 1)
  171.                                                 {
  172.                                                         saomiao(7);
  173.                                                         Delay1ms();
  174.                                                 }
  175.                                                 else if(b == 0 & a == 2)
  176.                                                 {
  177.                                                         saomiao(8);
  178.                                                         Delay1ms();
  179.                                                 }
  180.                                                 else if(b == 1 & a == 2)
  181.                                                 {
  182.                                                         saomiao(9);
  183.                                                         Delay1ms();
  184.                                                 }
  185. }

  186. void main(void)
  187. {
  188.         unsigned char backup[4][4] = {
  189.         {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}
  190.         };   //按键扫描值备份
  191.        
  192.         EA = 1;
  193.         //ENLED = 0;
  194.         TMOD = 0X01;
  195.         TH0 = 0XFC;
  196.         TL0 = 0X67;
  197.         ET0 = 1;
  198.         TR0 = 1;
  199.         saomiao(0);
  200.        
  201.         cls_periphercal();
  202.         Timer0Init();

  203.         while(1)
  204.         {
  205.                 for(a=0; a<4; a++)
  206.                 {
  207.                         for(b=0; b<4; b++)
  208.                         {
  209.                                 if(backup[a][b] != keysta[a][b])
  210.                                 {
  211.                                         if(backup[a][b] != 0)
  212.                                         {
  213.                                                 //anjian();
  214.                                                 saomiao(7);
  215.                                                 Delay1ms();
  216.                                                 Delay1ms();
  217.                                                 Delay1ms();
  218.                                                 Delay1ms();
  219.                                                 Delay1ms();
  220.                                                 Delay1ms();
  221.                                         }
  222.                                         backup[a][b] = keysta[a][b];
  223.                                 }       
  224.                         }
  225.                 }
  226.         }
  227. }





复制代码



回复

使用道具 举报

ID:376790 发表于 2020-1-17 16:44 | 显示全部楼层
求助
回复

使用道具 举报

ID:473159 发表于 2020-1-17 20:08 | 显示全部楼层
一个一个按键的调试,屏蔽其他按键,先调通一个,后面就会照做就OK!
回复

使用道具 举报

ID:213173 发表于 2020-1-17 22:12 | 显示全部楼层

楼主这是从哪里东拼西凑来的代码,只是用数码管显示矩阵按键键值的简单程序,竟然洋洋洒洒几百条代码。给你简化一下经仿真无误。 无标题.jpg

  1. #include "reg52.h"
  2. #include "intrins.h"
  3. #define uint unsigned int
  4. #define uchar unsigned char
  5. uchar code pucseg_code[] = {//段码
  6.         0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8,
  7.         0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e};
  8. uchar code weia[] = {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};//位码
  9. uchar data dis_buf[8];//显示缓存
  10. uchar key=0;                                        //定义键值全局变量

  11. void anjian()                                        //按键扫描程序
  12. {
  13.         static bit sign=0;                        //按键有效标志
  14.         static uchar count=0;                //消抖计数变量                       
  15.         uchar num=0;                                //临时变量
  16.         P3=0xf0;                                        //赋值P3 1111 0000
  17.         if(P3!=0xf0)                                //检测有按键按下
  18.         {
  19.                 count++;                                //消抖计数
  20.                 if((count>=10)&&(sign==0))
  21.                 {                       
  22.                         sign=1;                                //按键有效标志置1
  23.                         num=P3;                                //保存P3值xxxx 0000,x为0或1
  24.                         num|=0x0f;                        //保存num按位或0x0f值xxxx 1111
  25.                         P3=num;                                //赋值P3 xxxx 1111
  26.                         switch(P3)
  27.                         {
  28.                                 case 0xee: key= 1; break;
  29.                                 case 0xde: key= 2; break;
  30.                                 case 0xbe: key= 3; break;
  31.                                 case 0x7e: key= 4; break;
  32.                                 case 0xed: key= 5; break;
  33.                                 case 0xdd: key= 6; break;
  34.                                 case 0xbd: key= 7; break;
  35.                                 case 0x7d: key= 8; break;
  36.                                 case 0xeb: key= 9; break;
  37.                                 case 0xdb: key=10; break;
  38.                                 case 0xbb: key=11; break;
  39.                                 case 0x7b: key=12; break;
  40.                                 case 0xe7: key=13; break;
  41.                                 case 0xd7: key=14; break;
  42.                                 case 0xb7: key=15; break;
  43.                                 case 0x77: key=16; break;
  44.                         }
  45.                 }
  46.         }
  47.         else                                                //键抬起
  48.         {
  49.                 sign=0;                                        //按键有效标志清0
  50.                 count=0;                                //消抖计数清0
  51.         }
  52. }

  53. void saomiao()//共阳数码管循环刷新显示
  54. {        
  55.         static bit i=0;
  56.         if(i)
  57.                 dis_buf[0]=pucseg_code[key%10];
  58.         else
  59.                 dis_buf[1]=pucseg_code[key/10];
  60.         P0=0xff;//消隐
  61.         P2=weia[i];
  62.         P0=dis_buf[i];
  63.         i=~i;
  64. }
  65. void main()                                                //主函数
  66. {
  67.         TMOD = 0X01;//1ms
  68.         TH0 = 0XFC;
  69.         TL0 = 0X67;
  70.         EA = 1;
  71.         ET0 = 1;
  72.         TR0 = 1;
  73.         while(1);
  74. }
  75. void InterruptTimer0() interrupt 1
  76. {
  77.         TH0 = 0XFC;
  78.         TL0 = 0X67;
  79.         anjian();        //按键扫描程序
  80.         saomiao();  //共阳数码管显示程序
  81. }
复制代码



回复

使用道具 举报

ID:376790 发表于 2020-1-18 14:22 | 显示全部楼层
wulin 发表于 2020-1-17 22:12
楼主这是从哪里东拼西凑来的代码,只是用数码管显示矩阵按键键值的简单程序,竟然洋洋洒洒几百条代码。给 ...

自己参考书里改的,感谢大佬, 我参考
回复

使用道具 举报

ID:376790 发表于 2020-1-18 14:23 | 显示全部楼层
yoxi 发表于 2020-1-17 20:08
一个一个按键的调试,屏蔽其他按键,先调通一个,后面就会照做就OK!

好的,感谢解答
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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