找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索

51单片机8个IO口扫描检测64个按键+仿真程序+算法实现和心法要点讲解

查看数: 6431 | 评论数: 6 | 收藏 7
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2021-9-11 23:23

正文摘要:

51单片机8个IO口扫描检测64个按键+数码管显示+程序+Proteus仿真+算法实现和心法要点讲解扫描原理想通了很简单,就是通过一个IO拉低,其检测这一组其他7个IO口状态,如果检测到有被拉低了,说明就有按键按下了,因为 ...

回复

ID:795427 发表于 2021-9-16 10:33
npn 发表于 2021-9-12 16:58
这个程序还可以优化很多,仿真测试OK。

感谢坛友的集思广益,群策群力,在源代码基础上做的优化和改进。
ID:954686 发表于 2021-9-12 17:03
不错,这个例程好。IO不够的时候,之前用过4个IO口实现16个按键的方法,和楼主的电路差不多。
ID:57657 发表于 2021-9-12 16:58
这个程序还可以优化很多,仿真测试OK。
  1. #include "reg51.h"
  2. #include "intrins.h"
  3. #define u8 unsigned char
  4. sbit P36 = P3 ^ 6;
  5. sbit P37 = P3 ^ 7;
  6. sbit STCP = P3 ^ 0;//定义74HC595移位寄存器
  7. sbit SHCP = P3 ^ 2;
  8. sbit DS = P3 ^ 1;

  9. u8 code table[16] = {                //共阴数码管段码16进制
  10.         0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71
  11. };

  12. void delay(){
  13.     u8 a,b;
  14.     for(b=19;b>0;b--)
  15.         for(a=130;a>0;a--);
  16. }

  17. void txd595(u8 d) {
  18.         u8 i;
  19.         for (i = 0; i < 8; i++) {
  20.                 DS = d & 0x80;
  21.                 SHCP = 0;
  22.                 d <<= 1;
  23.                 SHCP = 1;
  24.         }
  25.         STCP=0;_nop_();STCP=1;
  26. }

  27. void display(u8 d) {
  28.         P37 = 0;
  29.         txd595(table[d%10]);
  30.         delay();
  31.         P37 = 1;
  32.         _nop_();
  33.         P36 = 0;
  34.         txd595(table[d/10]);
  35.         delay();
  36.         P36 = 1;
  37. }

  38. u8 b0(u8 dat) {                //取一个字节中有多少个二进制0 返回0~8
  39.         u8 i, j = 0;
  40.         for (i = 0; i < 8; i++) {
  41.                 if (!(dat & (1 << i))) {
  42.                         j++;
  43.                 }
  44.         }
  45.         return j;
  46. }

  47. u8 key_scan() {                //无按键返回0 有按键返回1~64 (禁止多个按键同时按下,出错返回99)
  48.         u8 i, j, k, l, m;
  49.         P0 = 0xFF;
  50.         _nop_();
  51.         k = P0;
  52.         if (k != 0xFF) {
  53.                 if (b0(k) != 1) return 99;
  54.                 for (i = 0; i < 8; i++) {
  55.                         if (!(k & (1 << i))) {
  56.                                 return 57 + i;
  57.                         }
  58.                 }
  59.         }

  60.         for (i = 0; i < 8; i++) {
  61.                 j = ~(1 << i);
  62.                 P0 = j;
  63.                 _nop_();
  64.                 k= P0;
  65.                 if (k != j) {
  66.                         if (k & ~j || b0(k) != 2) return 99;
  67.                         m = 0;
  68.                         for (l = 0; l < 8; l++) {
  69.                                 if (i == l) continue;
  70.                                 m++;
  71.                                 if (!(k & (1 << l))) {
  72.                                         return i * 7 + m;
  73.                                 }
  74.                         }
  75.                 }

  76.         }
  77.         return 0;
  78. }

  79. void main() {
  80.         while (1) {
  81.                 display(key_scan());
  82.         }
  83. }
复制代码
ID:164385 发表于 2021-9-12 10:14
楼主很厉害,辛苦了
ID:284488 发表于 2021-9-12 09:14
感谢楼主的分享,学习了。
ID:333678 发表于 2021-9-12 07:51
感谢楼主的无私奉献,下载学习了。

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

Powered by 单片机教程网

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