是在程序中查寻此I/O口的电平状态就可以了解我们是否有按键动作了。
在用单片机对键盘处理的时候涉及到了一个重要的过程,那就是键盘的去抖动。这里说的抖动是机械的抖动,是当键盘在未按到按下的临界区产生的电平不稳定正常现象,并不是我们在按键时通过注意可以避免的。这种抖动一般10~200毫秒之间,这种不稳定电平的抖动时间对于人来说太快了,而对于时钟是微秒的单片机而言则是慢长的。硬件去抖动就是用部分电路对抖动部分加之处理,软件去抖动不是去掉抖动,而是避抖动部分的时间,等键盘稳定了再对其处理。所以这里选择了软件去抖动,实现法是先查寻按键当有低电平出现时立即延时10~200毫秒以避开抖动(经典值为20毫秒),延时结束后再读一次I/O 口的值,这一次的值如果为1 表示低电平的时间不到10~200 毫秒,视为干扰信号。当读出的值是0时则表示有按键按下,调用相应的处理程序。硬件电路如图16所示:
k1k2k3S2SW SPSTS1SW SPSTS3SW SPSTGND 图16 按键电路
2、软件设计
2.1 原理图如图18所示:
RA2220RA1220GND+5GNDGNDPOWERR14.7kQ1PNPINP121+5RL1+5123AFAMQ-3BFB654+5R24.7kQ2PNPR34.7kQ3PNPR44.7kQ4PNP3S1246FR12.2kQ5PNP246135135999F12D2LEDD1LEDABBUZZERD01D12D23D34D45D56D67D78VCCabacfbdgeecfdgdpdpDS1REDCAD01D12D23D34D45D56D67D78VCCabacfbdgeecfdgdpdpDS2REDCAD01D12D23D34D45D56D67D78VCCabacfbdgeecfdgdpdpDS3REDCAD01D12D23D34D45D56D67D78VCCabacfbdgeecfdgdpdpDS4REDCARL12.2KRL22.2KU1STC89C52GNDADC08091234567891011121314In3In4In5In6In7STARTEOCD3OECLOCKVccVref+GNDD1ADC1ADC0809In2In1In0ADDAADDBADDCALED7D6D5D4D0Vref-D22827262524232221201918171615+5INGNDSTD7D6D5D4D0D0D1D2D3D4D5D6D71234567891011121314151617181920P1.0P1.1P1.2P1.3P1.4P1.5P1.6P1.7RESTP3.0/RXDP3.1/TXDP3.2/INT0P3.3/INT1P3.4/T0P3.5/T1P3.6/WRP3.7/RDXTAL2XTAL1GNDSTC89C52VCCP0.0P0.1P0.2P0.3P0.4P0.5P0.6P0.7EAALESPENP2.7P2.6P2.5P2.4P2.3P2.2P2.1P2.04039383736353433323130292827262524232221+5J1123456789+5CLK10KD0D1D2D3D4D5D6D7+C310ufSTEOCD3OECLK+5R110KOESTEOCk1k2k3GNDY1k1k29S2SW SPSTD1D212MHZC130PGNDGNDC230PS1SW SPSTk3S3SW SPSTGND 图17 原理图
五、程序设计
1.程序设计的基本思路
13
主程序流程图如下图所示:
结束 图18 主程序框图
Y 设置相应参数 显示设置数值 N 判断按键 是否按下 执行相应 的指示控制 判断当前 酒精范围 读取AD转换酒精值 开始 初始化 2.数据采集子程序程序框图
A/D转换子程序流程图如下图19所示。ADC0809初始化后,把0通道输入的0-5V的模拟信号转换为对应的数字量,然后将对应数值存储到内存单元。
14
开始
启动ADC0809通道,并延时100μs N 转换完?
Y
读出A/D转换结果
结果存入内存单元
返回 图19 数据采集子程序框图
3.程序代码
//程序头函数
#include
#define uint unsigned int #define uchar unsigned char #define Data_ADC0809 P1 //ADC0809 sbit ST=P3^3; sbit EOC=P3^4; sbit OE=P3^2;
//显示数组 0-9 - F
uchar Data_[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x71,0x3f}; sbit Wei1 = P2^7; sbit Wei2 = P2^6; sbit Wei3 = P2^5; sbit Wei4 = P2^4; //函数声明
extern uchar ADC0809();
void Display(uchar X,uchar Data); void delay(uint t); //酒精含量变量 uchar temp=0; //显示模式
15
uchar Mode=0; uchar p;
void main() //主函数 {
while(1) {
//正常模式 if(Mode==0) {
//读取AD值 temp=ADC0809(); for(p=0;p<30;p++) Display(0,temp); } } }
//ADC0809读取信息 uchar ADC0809() {
uchar temp_=0x00; //初始化高阻太 OE=0;
//转化初始化 ST=0;
//开始转换 ST=1; ST=0;
//外部中断等待AD转换结束 while(EOC==0) //读取转换的AD值 OE=1;
temp_=Data_ADC0809; OE=0;
return temp_; }
//延时
void delay(uint t) {
uint i,j;
for(i=0;i for(j=0;j<10;j++); } //显示 X表示状态 Data表示数据 void Display(uchar X,uchar Data) { Wei1=1; Wei2=1; Wei3=1; 16

