微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 单片机如何设计防抖动程序(源代码),单片机高阻态怎样克服?开发板死机程序跑飞该如何解决?

单片机如何设计防抖动程序(源代码),单片机高阻态怎样克服?开发板死机程序跑飞该如何解决?

时间:10-11 来源:互联网 点击:

0 则判定为按下,如果0 和 1 交错,就认为是抖动,不做任何判定。想一下,这样是不是比简单的延时更加可靠?

利用这种方法,就可以避免通过延时消抖占用单片机执行时间,而是转化成了一种按键状态判定而非按键过程判定,我们只对当前按键的连续 16ms 的 8 次状态进行判断,而不再关心它在这 16ms 内都做了什么事情,那么下面就按照这种思路用程序实现出来,同样只以K4 为例。

#include

sbit ADDR0 = P1^0;

sbit ADDR1 = P1^1;

sbit ADDR2 = P1^2;

sbit ADDR3 = P1^3;

sbit ENLED = P1^4;

sbit KEY1 = P2^4;

sbit KEY2 = P2^5;

sbit KEY3 = P2^6;

sbit KEY4 = P2^7;

unsigned char code LedChar[] = { //数码管显示字符转换表

0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,

0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E

};

bit KeySta = 1; //当前按键状态

void main(){

bit backup = 1; //按键值备份,保存前一次的扫描值

unsigned char cnt = 0; //按键计数,记录按键按下的次数

EA = 1; //使能总中断

ENLED = 0; //选择数码管 DS1 进行显示

ADDR3 = 1;

ADDR2 = 0;

ADDR1 = 0;

ADDR0 = 0;

TMOD = 0x01; //设置 T0 为模式 1

TH0 = 0xF8; //为 T0 赋初值 0xF8CD,定时 2ms

TL0 = 0xCD;

ET0 = 1; //使能 T0 中断

TR0 = 1; //启动 T0

P2 = 0xF7; //P2.3 置 0,即 KeyOut1 输出低电平

P0 = LedChar[cnt]; //显示按键次数初值

while (1){

if (KeySta != backup){ //当前值与前次值不相等说明此时按键有动作

if (backup == 0){ //如果前次值为 0,则说明当前是弹起动作

cnt++; //按键次数+1

if (cnt 》= 10){ //只用 1 个数码管显示,所以加到 10 就清零重新开始

cnt = 0;

}

P0 = LedChar[cnt]; //计数值显示到数码管上

}

//更新备份为当前值,以备进行下次比较

backup = KeySta;

}

}

}

/* T0 中断服务函数,用于按键状态的扫描并消抖 */

void InterruptTImer0() interrupt 1{

//扫描缓冲区,保存一段时间内的扫描值

staTIc unsigned char keybuf = 0xFF;

TH0 = 0xF8; //重新加载初值

TL0 = 0xCD;

//缓冲区左移一位,并将当前扫描值移入最低位

这个算法是我们在实际工程中经常使用按键所总结的一个比较好的方法,介绍给大家,今后都可以用这种方法消抖了。当然,按键消抖也还有其它的方法,程序实现更是多种多样,大家也可以再多考虑下其它的算法,拓展下思路。

  单片机高阻态是什么意思

在一个系统中或在一个整体中,我们往往定义了一些参考点,就像我们常常说的海平面,在单片中也是如此,我们无论说是高电平还是低电平都是相对来说的。

在51单片机,没有连接上拉电阻的P0口相比有上拉电阻的P1口在I/O口引脚和电源之间相连是通过一对推挽状态的FET来实现的,51具体结构如下图。

51结构图

组成推挽结构,从理论上讲是可以通过调配管子的参数轻松实现输出大电流,提高带载能力,两个管子根据通断状态有四种不同的组合,上下管导通相当于把电源短路了,这种情况下在实际电路中绝对不能出现,从逻辑电路上来讲,上管开-下管关开时IO与VCC直接相连,IO输出低电平0,这种结构下如果没有外接上拉电阻,输出0就是开漏状态(低阻态),因为I/O引脚是通过一个管子接地的,并不是使用导线直接连接,而一般的MOS在导通状态也会有mΩ极的导通电阻。

排阻

无论是低阻态还是高阻态都是相对来说的,把下管子置于截止状态就可以把GND和I/O口隔离达到开路的状态,这时候推挽一对管子是截止状态,忽略读取逻辑的话I/O口引脚相当于与单片机内部电路开路,考虑到实际MOS截止时会有少许漏电流,就称作“高阻态”

由于管子PN节带来的结电容的影响,有的资料也会称作“浮空”,通过I/O口给电容充电需要一定的时间,那么IO引脚处的对地的真实电压和水面浮标随波飘动类似了,电压的大小不仅与外界输入有关还和时间有关,在高频情况下这种现象是不能忽略的。

  单片机程序死机,跑飞了可以从以下几个方面查找原因:

1、意外中断。是否打开了某个中断,但是没有响应和清除中端标志,导致程序一直进入中断,造成死机假象;

2、中断变量处理不妥。若定义某些会在中断中修改的全局变量,这时要注意两个问题:首先为了防止编译器优化中断变量,要在这些变量定义时前加volaTIle,其次在主循环中读取中断变量前应该首先关闭全局中断,防止读到一半被中断给修改了,读完之后再打开全局中断;否则出现造成数据乱套。

3、地址溢出,常见错误为指针操作错误。我要着重说的是数组下标使用循环函数中循环变量,如果循环变

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top