找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机2个I/O口扫描5个按键方案 附程序仿真

[复制链接]
跳转到指定楼层
楼主
本文从节省单片机I/O资源的角度,运用动态扫描的方式,实现2个I/O口扫描5个按键的功能。
一、思路:2个I/O口分别定义为KEY1和KEY2,可以有4种状态,如下:
—————————————————————
KEY1    KEY2          功能
  0         0         不使用
  0         1         检测按键2
  1         0         检测按键4
  1         1         检测按键1、3、5
—————————————————————
二、扫描:
1.KEY1=0,KEY2=1,按下按键2可拉低KEY2,从而检测按键2的状态。
2.KEY1=1,KEY2=0,按下按键4可拉低KEY1,从而检测按键4的状态。
3.KEY1=1,KEY2=1,按下按键1可拉低KEY2,按下按键3可拉低KEY1,按下按键5可同时拉低KEY1和KEY2。
当有某个按键按下时,需要进行松手检测,在按下状态使按键扫描停止,不然会出现错乱。
三、总结:
本案例除按键扫描,还有数码管动态显示,仅为单片机初学者或爱好者提供学习研究,了解程序编写的思维,互相交流。
学无止境,如果学友们有兴趣,下次发布1个I/O扫描8个按键的方案。

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


四、单片机程序:

#include <REGX52.H>
#define uint unsigned int
#define uchar unsigned char
uchar code SEG[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};  //共阳代码
uchar keynum;       //定义按键键值变量
sbit COM1=P2^0;     //数码管位1
sbit COM2=P2^1;     //数码管位2
sbit KEY1=P2^6;     //按键位1
sbit KEY2=P2^7;     //按键位2


/***********************************************************
    延时函数
***********************************************************/
void Delay(uint xms)
{
    uchar i;
    while(--xms)
    {
        i=120;
        while(--i);
    }
}


/***********************************************************
    数码管动态扫描显示函数
***********************************************************/
void Show_seg()
{
    P0=SEG[keynum/10];
    COM1=1;
    Delay(5);
    COM1=0;
   
    P0=SEG[keynum%10];
    COM2=1;
    Delay(5);
    COM2=0;        
}


/***********************************************************
    按键扫描函数
***********************************************************/
void Key_scan()             //本按键扫描程序必须要有松手检测,不然会出错
{
    KEY1=1; KEY2=1;         //此状态可以检测按键1、3、5
    if(KEY1==1 && KEY2==0)  {keynum=1; while(KEY1==1 && KEY2==0)Show_seg(); Delay(15);}
    if(KEY1==0 && KEY2==1)  {keynum=3; while(KEY1==0 && KEY2==1)Show_seg(); Delay(15);}
    if(KEY1==0 && KEY2==0)  {keynum=5; while(KEY1==0 && KEY2==0)Show_seg(); Delay(15);}
   
    KEY1=0; KEY2=1;         //此状态可以检测按键2
    if(KEY2==0)  {keynum=2; while(KEY2==0)Show_seg(); Delay(15);}
   
    KEY1=1; KEY2=0;         //此状态可以检测按键4
    if(KEY1==0)  {keynum=4; while(KEY1==0)Show_seg(); Delay(15);}
}


/***********************************************************
    主函数
***********************************************************/
void main()
{
    while(1)
    {
        Key_scan();
        Show_seg();
    }
}

仿真程序下载: 2IO扫描5个按键.7z (18.63 KB, 下载次数: 6)

评分

参与人数 1黑币 +90 收起 理由
admin + 90 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

沙发
ID:433219 发表于 2024-6-13 16:49 | 只看该作者
cowboy前辈3io22key才是经典制作,程序就烧脑了

不用二极管能接6键,2只二极管能接12键,6只二极管能接18键,9只二极管能接21键,第22键要单独占用3只二极管最不化算

3io_22key.JPG (26.94 KB, 下载次数: 1)

3io_22key.JPG
回复

使用道具 举报

板凳
ID:961114 发表于 2024-6-13 17:15 | 只看该作者
宝,现在都是硬件在线仿真了  USB直接仿真 STC8H8K64U  
软件仿真已经淘汰了
回复

使用道具 举报

地板
ID:291549 发表于 2024-6-17 10:42 | 只看该作者
期待8按键程序
回复

使用道具 举报

5#
ID:291549 发表于 2024-6-17 10:52 | 只看该作者
程序还是很完美,前提是不能多按键同时按,否则会误识别,例如1和3同时按,再松开任意一个键会出现判断失误现象。思路很好,值得学习和借鉴,感谢楼主。
回复

使用道具 举报

6#
ID:291549 发表于 2024-6-17 10:54 | 只看该作者
STC庄伟 发表于 2024-6-13 17:15
宝,现在都是硬件在线仿真了  USB直接仿真 STC8H8K64U  
软件仿真已经淘汰了

宝,软件仿真不用硬件,各有特点。
回复

使用道具 举报

7#
ID:619259 发表于 2024-6-18 10:38 | 只看该作者
jinyudz 发表于 2024-6-17 10:52
程序还是很完美,前提是不能多按键同时按,否则会误识别,例如1和3同时按,再松开任意一个键会出现判断失误 ...

感谢支持,本文提供的案例除具有一定的实用性,更重要的是和大家一起探讨编程思维。你提出的同时按下出现的问题,我会追求解决方案。
回复

使用道具 举报

8#
ID:619259 发表于 2024-6-18 10:50 | 只看该作者
wkman 发表于 2024-6-13 16:49
cowboy前辈3io22key才是经典制作,程序就烧脑了

不用二极管能接6键,2只二极管能接12键,6 ...

论坛中从不缺乏大神,正所谓山外有山。如果一个神一般的案例能解释得让小弟们理解,才是真神。这也是论坛建设的初衷和精神所在。
回复

使用道具 举报

9#
ID:619259 发表于 2024-6-18 10:53 | 只看该作者
STC庄伟 发表于 2024-6-13 17:15
宝,现在都是硬件在线仿真了  USB直接仿真 STC8H8K64U  
软件仿真已经淘汰了

宝,当今世界,富人阶层已经不屑于吃红薯了,而老百 姓依然把它当宝。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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