找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1555|回复: 6
收起左侧

扫键极限复用IO口的单片机实现代码

[复制链接]
ID:441351 发表于 2022-8-23 23:04 | 显示全部楼层 |阅读模式
本人初学单片机,前几天看到论坛里"qinshuai"发的“堪称一绝的“IO口扫键”法-单片机端口不够用时键盘扫描方法”一文,发现真是把IO口的复用玩到了极致!按照原文的说明,如果在电路中借助二极管,那么N个IO口最多能扫描N^2个按键!一般8脚的单片机有6个IO口,在不用其他IC的情况下最多能扫描36个按键!
下面是该方法的示意图:

首先,我们将IO1~5全部置1,扫描IO1~5,如果有0就说明最下面K61~K65中对应的按键被触发。接下来,将IO1置0,IO2~5置1,扫描IO2~5;将IO2置0,IO1,IO3~5置1并扫描;······;将IO5置0,IO1~4置1并扫描。以上便是一个完整的扫描周期,25个键都能够被扫描到。

我自己仿真了用6个IO口扫描30个按键的程序,效果还不错,代码、hex烧录文件和仿真文件都打包放在文章末尾了。不过暂时还没有在实际中实验,等我焊好按键键盘之后再试试!

下面是我的仿真电路图,理论上6个IO口最多可以扫描36个按键,不过我只需要30个就够了(6行5列),所以接地的六个按键我没有接(写程序也省事)。按键按下后,程序需要把对应的数字显示在数码管上。
51hei截图20220824012254.png

按键对应的数字:
第1行 01 02 03 04 05
第2行 06 07 08 09 10
第3行 11 12 13 14 15
第4行 16 17 18 19 20
第5行 21 22 23 24 25
第6行 26 27 28 29 30

实现该功能的代码如下
  1. #include <reg52.h>

  2. //CTRL1与CTRL2控制两位数码管的使能
  3. sbit CTRL1 = P3^0;
  4. sbit CTRL2 = P3^1;

  5. //BUTTON是按键端口,本次使用P0的0~5这6个io口。(P0:0x80, P1:0x90, P2:0xA0, P3:0xB0)
  6. sfr BUTTON = 0x80;

  7. //点亮数码管(共阳)的函数
  8. void dig_num(unsigned int x)
  9. {
  10.         unsigned int i;
  11.         unsigned int y;
  12.         //共阳数码管0~9对应的编码
  13.         unsigned char code num[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
  14.         y = x % 10;
  15.         x = x / 10;

  16.         CTRL1 = 0;
  17.         CTRL2 = 1;
  18.         P2 = num[y];
  19.         for(i=0;i<20;i++);

  20.         CTRL2 = 0;
  21.         CTRL1 = 1;
  22.         P2 = num[x];
  23.         for(i=0;i<20;i++);

  24.         P2 = 0xFF;
  25.         CTRL1 = 0;
  26. }

  27. void main()
  28. {
  29.         unsigned int i, j;
  30.         //key_map用于定义每个按键的功能
  31.         unsigned int key_map[6][5] = {{1, 2, 3, 4, 5},
  32.                                                                 {6, 7, 8, 9, 10},
  33.                                                                 {11, 12, 13, 14, 15},
  34.                                                                 {16, 17, 18, 19, 20},
  35.                                                                 {21, 22, 23, 24, 25},
  36.                                                                 {26, 27, 28, 29, 30}};
  37.         unsigned char mask = 0x01;
  38.         
  39.         BUTTON = 0xFF;
  40.         while (1)
  41.         {
  42.                 //逐行扫描
  43.                 for (i=0; i<6; i++)
  44.                 {
  45.                         BUTTON = 0xFF ^ mask;
  46.                         //逐列扫描
  47.                         for (j=0; j<6; j++)
  48.                         {
  49.                                 //检测到某个io口低电平,可能是按钮被按下
  50.                                 if (((BUTTON >> j) & 0x01) == 0x00)
  51.                                 {
  52.                                         //i == j时的低电平io口恰好是逐行扫描设定的io口,不用管
  53.                                         if (i < j) dig_num(key_map[i][5-j]);
  54.                                         else if (i > j) dig_num(key_map[i][4-j]);
  55.                                 }
  56.                         }
  57.                         mask = mask << 1;
  58.                 }
  59.                 mask = 0x01;
  60.         }
  61. }
复制代码


下面是仿真的效果展示:


https://v.youku.com/v_show/id_XNTg5NTk3OTU2OA==.html

proteus仿真文件、hex文件、c源码文件在这个压缩包里:
6个引脚控制30个开关.zip (40.1 KB, 下载次数: 13)
回复

使用道具 举报

ID:807591 发表于 2022-8-24 08:23 | 显示全部楼层
这些只合适娱乐,实际应用性也不大,全键按下无冲突貌似不行,另外程序负担多一点点
回复

使用道具 举报

ID:161164 发表于 2022-8-24 08:51 | 显示全部楼层
请问你的proteus是什么版本?
回复

使用道具 举报

ID:441351 发表于 2022-8-24 15:17 | 显示全部楼层
szb314 发表于 2022-8-24 08:23
这些只合适娱乐,实际应用性也不大,全键按下无冲突貌似不行,另外程序负担多一点点

全键无冲太难了
回复

使用道具 举报

ID:441351 发表于 2022-8-24 15:19 | 显示全部楼层
lkc8210 发表于 2022-8-24 08:51
请问你的proteus是什么版本?

版本是7.8 SP2
回复

使用道具 举报

ID:441351 发表于 2022-8-25 11:18 | 显示全部楼层
lkc8210 发表于 2022-8-24 08:51
请问你的proteus是什么版本?

版本是7.8 SP2
回复

使用道具 举报

ID:624769 发表于 2022-8-25 14:11 来自手机 | 显示全部楼层
地球 发表于 2022-8-24 15:17
全键无冲太难了

矩阵是可以全键无冲的,关键看你代码怎么写。单线扫描的话,是可以识别组合键的。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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