前面我们简单的学习了C51的IO结构,现在我们来看看,准双向IO口如何使用按键输入
这是准双向IO的基本结构,单片机就靠内部输入线来读取IO的电平状态。
我们以这个电路分析准双向IO上的按键使用
在准双向口中,我们需要先给IO写高电平才能去读取IO的电平变化(高->低)
在写高电平的情况下……
三极管截止
没有按下按键,电流由正极经过上拉电阻流到内部输入线路,这时候内部读出高电平
这时候按下按键,按下按键,电流由VCC流经上拉电阻再流经按键最后流向GND。由于电流由正极流向负极。内部输入线路线路的电流流向负极,这时候读出的数值就是低电平的
如果我们写IO是低电平的话,三极管始终导通,内部输入的电流经过三极管接到负极,这时候无论有没有按下按键,都只能读出低电平
按键的电路
我们使用的开发板有四个独立按键,这四个独立按键接在P3.2 - P3.4
我们使用单片机准双向IO提供的IO内部的上拉电阻,所以不需要外部上拉电阻
首先,需要使用sbit定义我们的按键所连接的IO
sbit KEY = P3^4;
接下来,给这个按键所属的IO写高电平
KEY = 1;
读取按键按下的代码
if(KEY == 0) { unsigned char a = 550; while(a--);//延迟消抖 if(KEY == 0) { while(!KEY);//检测按键是否松开,防止连按 //这里是你的要放下按键按下后执行的代码 } }
这里需要说明一下
if(KEY == 0)用于读取按键是否按下按键,读取方式直接用KEY == 0,KEY == 1直接读取这一位IO寄存器值。
当我们第一次读取之后,还需要延迟一会再次读取按键,我们把这个过程称为延迟消抖
这是因为我们使用的按键是物理按键,内部的简化结构如图
按键上面有一个弹片,按下按键弹片后触点接触,按键导通,松开按键,弹片回弹,按键断开,电压的变化总是高电平》低电平》高电平
上面描述的是理想状态,但是实际上,物理按键并不像我们想象如此理想,当我们按下按键的时候,按键的弹片会发生震动,导致电压会有一定的抖动幅度
这些幅度的抖动会影响单片机对按键的读取和识别
我们可以用硬件电路消抖,下面展示一个简单的硬件消抖电路
在这个电路里面,一颗0.1u的电容用于消除抖动,电容充放电实现消抖的效果
那么为什么不使用上面的电路实现消抖呢??
答案很简单——成本高嘛
所以我们使用软件消抖
if(KEY == 0) { unsigned char a = 550; while(a--);//延迟消抖 if(KEY == 0) { while(!KEY);//检测按键是否松开,防止连按 //这里是你的要放下按键按下后执行的代码 } }
单片机先读取按键引脚的电平,软件延迟后再次读取后再次读取按键的电平,如果还是按下的状态,那么就开始等待按键松开,等待按键松开是必要的,如果不等待按键松开,可能我们按下按键久一点按键就变成多次连按了
那么下面就是一个简单的项目,按键开关LED灯
/*
按键学习
按键按下,LED实现开关
青青子衿工作室
Zi Jin Code
*/
#include < reg52.h >
sbit LED = P1^0;
sbit KEY = P3^3;
void main()
{
KEY = 1;//使用按键之前,对应的引脚写高电平
LED = 1;
while(1)
{
if(KEY == 0)
{
unsigned int a = 550;
while(a--);//延迟消抖
if(KEY == 0)//再次检测...
{
while(!KEY){}//检测按键是否松开
LED = !LED;//LED状态取反
}
}
}
}
编译并且上传程序,测试