版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/little_white__/article/details/70148310
在单片机中会遇到识别按键的问题,常用的独立按键电路如下图:
由于机械式触点开关具有弹性,会发生抖动,所以要进行消抖。有两种消抖方式:硬件消抖和软件消抖。
硬件消抖电路:
软件消抖常采用延时消抖:按键被按下时,当检测到低电平时,延时一段时间,一般是5到10ms,然后再检测端口,若还是低电平,则表示检测到按键按下,按键弹起时同理可得。
独立按键的检测一般采用两种方法:中断检测和查询检测。
按键连接P3^2引脚,检测按键按下和弹起的次数。
1.查询检测:可以直接在主程序中循环检测,也可以通过定时器,每隔20ms检测一次。下面是直接在循环中检测的。
主函数:
#include <reg51.h>
#include <intrins.h>
#define uint unsigned int
sbit in0 = P3^2 ; //输入信号引脚
uint Press_flag = 1 ; //按键按下标志
uint count = 0 ; //按键次数
void delay_ms(uint ms)
{
uint i , j ;
for(i = 0 ; i < ms ; i++)
{
for(j = 0 ; j < 333 ; j++)
{
_nop_() ;
}
}
}
void key()
{
if(in0 == 0) //检测到0
{
delay_ms(10) ; // 延时消抖
if(in0 == 0) //再次检测到0
{
Press_flag = 0 ; //代表按键被按下
}
}
if(Press_flag == 0) //如果按键被按下,再检测按键弹起
{
if(in0 == 1)
{
delay_ms(10) ;
if(in0 == 1)
{
count ++ ; //表示按键按下并弹起的次数
Press_flag = 1 ; //复位按键按下标志
}
}
}
}
void main(void)
{
while(1)
{
key() ;
}
}
信号函数:
signal void test(unsigned int cc)
{
unsigned int i , j ;
for(i = 0 ; i < cc ; i++)
{
for(j = 0 ; j < 2 ; j++)
{
port3 &= ~(1<<2) ;
swatch(0.002) ;
port3 |= 1<<2 ;
swatch(0.002);
}
port3 &= ~(1<<2) ;
swatch(0.002) ;
swatch(0.01) ;
for(j = 0 ; j < 2 ; j++)
{
port3 |= 1<<2 ;
swatch(0.002) ;
port3 &= ~(1<<2) ;
swatch(0.002) ;
}
port3 |= 1<<2 ;
swatch(0.02) ;
swatch(0.1) ;
}
_break_ = 1 ;
}
信号函数波形图:
可以看到count的值为4
2.中断检测
主程序:
#include <reg51.h>
#include <intrins.h>
#define uint unsigned int
sbit in0 = P3^2 ;
uint count = 0 ;
uint press_flag = 1 ;
void delay_ms(uint ms)
{
uint i , j ;
for(i = 0 ; i < ms ; i++)
{
for(j = 0 ; j < 333 ; j++)
{
_nop_() ;
}
}
}
void Init_INT(void)
{
EA = 1 ; //开总中断
EX0 = 1 ; //开外部中断0
IT0 = 1 ; //下降沿触发中断
}
void Int0 (void) interrupt 0
{
EX0 = 0 ; //关闭外部中断0,防止频繁触发中断
delay_ms(10) ;
if(in0 == 0)
{
press_flag = 0 ;//按键按下标志
}
if(press_flag == 0 && in0 == 1)//检测按键弹起
{
delay_ms(10) ;
if(in0 == 1)
{
count++ ;
press_flag = 1 ;
}
}
EX0 = 1 ; //开启外部中断
}
void main(void)
{
Init_INT() ; // 中断初始化
while(1)
{
}
}
新手小白,请多指教。