A. 51单片机LED按键延时3秒一次点亮,取反按键依次熄灭程序是怎么写的
现功能:按下按键三个全亮,在按下LED2灭,再按下三个LED全灭,如此循环,相当于三档,第三档是停止。第一档和第二档定时5S,5S终了,停止运行,如果此时再按1次则回到第一档。如果5S之内按下,则切换到下一档,实现功能:按下按键三个全亮,在按下LED2灭,再按下三个LED全灭,如此循环,相当于三档,第三档是停止。第一档和第二档定时5S,5S终了,停止运行,如果此时再按1次则回到第一档。如果5S之内按下,则切换到下一档。
B. 单片机关于延时函数,请问这段代码不是延时500ms吗为什么这里说是200ms
按键的延时消抖是初学单片机的必经之路,因为只要是机械开关所传递的信号,都会存在波动,有时这些波动是“致命”的,所以消除其影响就是一门手艺了。硬件消抖有其优点,同样的也有不方便的地方,开发成本高,操作难度大,可移植性差。软件消抖就相对较好些,新手即可操作,延时消抖,并非消抖的最终最优方法,但好在简单易懂,我们先认识消抖的方法和目的。
按键在按下和抬起时,都会出现短暂的抖动,称之为前沿抖动和后沿抖动,他们持续的时间大致在5-10毫秒,键稳定时间会在100毫秒以上,就人的操作速度来看,键稳定的时间不会低于100毫秒,因为,1秒十次的操作,估计手都受不了。除非科幻世界或武侠世界的人。
既然抖动时间基本不变,那么,我们就有这样一种方法,当按键出现第一个电位变化,假设是高电位转变成低电位,那么我们就延时一段时间,设置10毫秒,10毫秒以后,我们再次判断此时的电位状态,是否是低电位,如果是低电位,那么就认为按键按下了,如果是高电位,就认为按键是抖动。从低电位变成高电位也是一样。
我们就是用延时来,把抖动的时间空过去了,这样就不用担心抖动产生的电位频繁变化了。接下来,我们看下程序如何写。
按流程来,基本上就能写出来,程序分为两大块,一个是主函数,处理开关状态,一个是延时函数。
我们先定义一个开关,然后我又声明了一个位变量,其实这个位变量在这里可以不用,不过习惯如此,对采集来的数据我习惯让其保存在特定的变量中,这样方便后期使用,以防自己改变变量值,造成端口的电位随之改变。
主函数中,先把开关采集端口置1,这是读取数据的前提条件,然后把需要采集的io的状态转移给中间变量,接着判断此时中间变量是否为零,也就是按键是否按下,如果没有按下,那就跳出,继续赋值,接着判断,直到判断为零,进入语句中,先延时一段时间,让抖动空过去,延时结束,再判断一次,由于此时程序还没走出去,所以中间变量的值也没有实时切换,我们此时要判断按键实时状态是否为零,就需要判断端口的实际值,当key10为零,就说明按键确实处于按下状态,这就可以执行,移位指令。
需要说明,如果使用函数,在调用时,只需写出函数名即可。但是在程序最开始位置,需要声明函数,声明时,要写全,尤其是返回值的类型和变量名,不能省略。可以把函数直接复制到前方,然后加一个冒号即可。
程序看完,我们仿真一下测试下程序是否执行。
这是之前我们使用的仿真电路,直接使用就好。我没有改变工程文件,所以无需重新导入可执行文件,程序会直接读取我保存好的新的可执行文件,文件名没有改变。
这是软件的初始状态,所有端口都是高电位,我们按下P10.
按键随着按下,可以稳定的响应,我们再通过实际电路测试一下。
测试发现,我按下按键,还没松手,就已经流水般的熄灭了5个灯了,什么情况?
我们可以看程序的这里
keybuff=key10; //赋值
if(keybuff==0) //判断开关是否按下
{
delay(50); //延时一段时间
if(key10==0) //再次判断开关是否按下
{
P3=P3>>1; //P3左移一位
}
}
从这一段可以看出,只要我能满足keybuff为零,key10为零,那么程序就会在延时结束再次进入程序,如此循环,就造成了,按键按下,P3被连续执行动作。我们怎么才能让这种情况不发生呢?这就需要我们不仅检测按键按下,还需要检测按键弹起,只有按键弹起我们才允许它执行下一步,这样就能按下一次,抬起手,才会停止,保证了操作的准确。
执行流程如下:
判断按键按下》按键按下》延时》判断按键按下》按键按下》执行动作》判断按键抬起》按键抬起》结束。
我们再次测试,此时发现,按下后,不松开,按键不再连续动作,但是松开按键后,原本熄灭的小灯又点亮了,我们梳理程序,可以发现,是不存在错误的,流程也没有问题。其实这就涉及我们的硬件了,我们使用软件仿真时,这些问题都是没有的,但硬件跟仿真的区别就在这里,在单片机中,如果我们没有规定执行下一步的位置,单片机就会在流程走完后,随机进入我们无法控制的流程,这在专业中称之为跑飞。为了防止跑飞,我们一般会在结束添加循环语句,让程序停止在我们设定的位置,这样就不会有问题了。
此处我们需要连续监测按键状态,所以就让程序不断的循环判断按键即可。
再次测试,一切就按照程序执行了,动作也正常了。
这就是为什么我们之前的测试程序,都会在主函数中添加循环的作用。通过这个示例,也是告诉大家,仿真只是学习的方法,最终目的还是要在实际的硬件上进行。不然你永远不知道自己的程序能不能完成真正的功能,设计不能光纸上谈兵哦。
C. 需要一个C语言程序。51单片机控制:按键按一下,延迟1分钟后开灯,灯亮半个小时就熄灭的程序急需!
如果对时间要求不精确,用软延时即可。
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit s=P1^0;
sbit led=P1^1;
void delayms(uint i) //1ms延时程序
{
uchar j;
for(;i>0;i--)
{
for(j=0;j<125;j++)//如果延时时间误差较大,可按比例改变125这个数
//取值范围0-255,数值越大,延时越长
{;}
}
}
void delay1s(uint i) //1s延时程序
{
for(;i>0;i--){delay1ms(1000);}
}
void main()
{
led=0;
while(1)
{
if (s==0)
{
delayms(20);
if (s==0);{delay1s(60);led=1; }
}
if(led==1){delay1s(1800);led=0; }
}
}
如果对时间要求精确,则要用到定时器,还要确保电路外接有晶振,并已知晶振频率
D. 单片机键盘扫描中的软件时延作用是什么
简单说就是消除按键抖动;使得单片机正确读取按键值,屏蔽干扰信号;
通常的按键所用开关为机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开。因而在闭合及断开的瞬间均伴随有一连串的抖动,为了不产生这种现象而作的措施就是按键消抖