3.1 按键原理分析
首先我们可以看到按键连接在GND一端,然后通过按键连接在另外一端的是单片机的引脚,此时我们注意到单片机的引脚分别是P30,P31,P32 从原理图上面可以简单看出来单片机的引脚并没有接上拉电阻,因为在STC89C52单片机中他的P3引脚具有内部上拉,这样就可以不用接上拉电阻了,如果接的话也是可以的,一般可以接上10K的上拉电阻。其中P30,P31可以作为普通的按键去使用,这里需要注意的是,因为在单片机中这两个引脚是单片机串口脚位,P32是单片机的外部中断,所以接下面我们可以撰写程序去让大家理解的更加深刻。
3.2 按键的触发过程
按键触发我们一般分为三个步骤
1.按下瞬间
2.按下不动
3.松开瞬间
/**********************************
函数名: Chiclet_Keyboard_Scan
传递参数: 无
返回参数: 无
函数作用: 按键函数
**********************************/
void Chiclet_Keyboard_Scan(void)
{
if(K1 == 0)//按键K1为低电平
{
usleep(2);//2ms消抖
if(K1 == 0)//按键K1依然为低电平,此时确认是K1按下
{
//这里是按下瞬间的程序撰写的地方
LED=0;
}
while(!K1)//while死循环,直到抬手跳出
{
//这里是长按的程序撰写的位置
LED=0;
usleep(500);//2ms消抖
LED=1;
usleep(500);//2ms消抖
}
//这里是抬手跳出的程序撰写位置
LED=1;
}
}
从上述程序位置可以看到按键的三个步骤分别写在不同的位置,我们简单分析一下,第一个 if 是判断是否按下按键,然后第二个 if 是确认就是人为按下按键中间的延时是软件的消抖,这样可以为了防止因为电压电流等问题出现异常出现按键误触。
3.4 按键触发外部中断
/**********************************
函数名: main
传递参数:无
返回参数:无
函数作用:主函数
**********************************/
void main(void)
{
IT0 = 1; //设置外部中断为下降沿触发
EX0 = 1; //打开外部中断开关
EA = 1; //打开总中断开关
while(1)
{
Chiclet_Keyboard_Scan();
}
}
/**********************************
函数名: exint0
中断号: 0
函数作用: 外部中断0
**********************************/
void exint0() interrupt 0
{
LED = ~LED;
usleep(500);
}
通过对数据手册的分析,外部中断可以有两个触发方式,第一则是下降沿触发,第二就是低电平触发
通过上面程序可以看出触发方式的不同可以应用在不一样的地方,但是一般情况下我们都是在按下按键出进行处理。下面通过具体的示例展开对实用按键函数的说明
3.4 几种实用的按键函数
看到这里我们因为程序在写在单独的.c .h文件中,所以需要了解他们之间的关系以及分别代表着什么,详细可以观看下面的文章。
第一种
key.c
/**********************************
包含头文件
**********************************/
#include "key.h"
/**********************************
变量定义
**********************************/
uchar key_Flag = 0; //独立按键标志位
/**********************************
函数名: Chiclet_Keyboard_Scan
传递参数: 无
返回参数: 键值
函数作用: 按键函数
**********************************/
uchar Chiclet_Keyboard_Scan(void)
{
if(K1==1 && K2==1 && K3==1) key_Flag = 1;
if(K1==0 && key_Flag==1) //K1是否按下
{
usleep(2); //消抖
if(K1==0 && key_Flag==1)//再次判断K1是否按下
{
key_Flag = 0;
return 1; //返回1
}
}
if(K2==0 && key_Flag==1)
{
usleep(2);
if(K2==0 && key_Flag==1)
{
key_Flag = 0;
return 2;
}
}
if(K3==0 && key_Flag==1)
{
usleep(2);
if(K3==0 && key_Flag==1)
{
key_Flag = 0;
return 3;
}
}
return 0;//没有按键按下,返回0
}
key.h
#ifndef _KEY_H_
#define _KEY_H_
/**********************************
包含头文件
**********************************/
#include "main.h"
/**********************************
PIN口定义
**********************************/
sbit K1=P3^0; //独立按键K1引脚 P2.2
sbit K2=P3^1; //独立按键K2引脚 P2.3
sbit K3=P3^2; //独立按键K3引脚 P2.4
/**********************************
函数声明
**********************************/
uchar Chiclet_Keyboard_Scan(void); //独立按键扫描函数
#endif
第二种
key.c
/**********************************
包含头文件
**********************************/
#include "key.h"
/**********************************
变量定义
**********************************/
uchar key_Flag = 0; //独立按键标志位
/**********************************
函数名: Chiclet_Keyboard_Scan
传递参数: 无
返回参数: 键值
函数作用: 按键函数
**********************************/
uchar Chiclet_Keyboard_Scan(void)
{
if(K1 == 0)//按键K1为低电平
{
usleep(2);//2ms消抖
if(K1 == 0)//按键K1依然为低电平,此时确认是K1按下
{
//这里是按下瞬间的程序撰写的地方
key_Flag=1;
}
while(!K1);//while死循环,直到抬手跳出
//这里是抬手跳出的程序撰写位置
return key_Flag;
}
if(K2 == 0)//按键K1为低电平
{
usleep(2);//2ms消抖
if(K2 == 0)//按键K1依然为低电平,此时确认是K1按下
{
//这里是按下瞬间的程序撰写的地方
key_Flag=2;
}
while(!K2);//while死循环,直到抬手跳出
//这里是抬手跳出的程序撰写位置
return key_Flag;
}
if(K3 == 0)//按键K1为低电平
{
usleep(2);//2ms消抖
if(K3 == 0)//按键K1依然为低电平,此时确认是K1按下
{
//这里是按下瞬间的程序撰写的地方
key_Flag=3;
}
while(!K3);//while死循环,直到抬手跳出
//这里是抬手跳出的程序撰写位置
return key_Flag;
}
return 0;//没有按键按下,返回0
}
key.h 不变
按键函数是相对十分实用的一个驱动,等后期我们学习定时器之后可以根据定时器,去写一些长按,短按,等的按键方式,这样可以更加完善人机交互系统。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
暂无评论内容