标题: 新手入门,单片机延时函数看不懂 [打印本页]

作者: 苏宁cheung    时间: 2018-3-7 15:54
标题: 新手入门,单片机延时函数看不懂
我学着一本书上打了一段控制led灯闪烁的单片机程序,如下
#include "reg52.h"         
                                                                 
                #define uInt16 unsigned int
                sbit LED1=P2^0 ;
                void delayms(uInt16 valMS)
        {
        uInt16 uival,ujval;
        for(uival=0;uival<valMS;uival++
for(ujval=0;ujval<113;ujval++);
}
        void main(void)         
        {
        while(1)
        {        LED1=0;
        delayms(1000);
        LED1=1;
        delayms(1000);
        }
        }

然后我试着删除第二个for循环,结果发现灯变成了常亮,这是怎么回事呢?这个函数的大致意思是什么?为什么要定义两个局部变量?

作者: accac    时间: 2018-3-7 16:08
第一个for循环括号没括住,语句结束时加";"
作者: 23131sda3dsad    时间: 2018-3-7 16:29
通过循环实现延时函数的原理:单片机执行每一条程序需要时间(时间非常短),通过循环函数,达到延时的目的。
这个函数的意思:经过多次调试,发现单片机每做113条循环指令需要的时间为1ms,因此,通过嵌套循环,输入形参valMS, 单片机就会执行 113*valMS次循环指令,达到延时valMS 毫秒的目的.
去掉第二个循环灯常亮的原因:循环的执行次数少了,导致延时效果减弱,实际灯还是在闪烁,只不过延时太短,肉眼无法分清。假如把里面的循环函数去掉,那么可以将for(uival=0;uival<valMS;uival++) 改成
for(uival=0;uival<valMS*113;uival++); 效果一样,不过此时valMS最大值减小,因为uival 的数据类型是16位,uival不能超过65535.
为什么要有两个局部变量:因为要实现两个循环函数,一个不够

作者: DYQ_DYQ    时间: 2018-3-7 16:31
首先52的机器周期大约1us,也就是说走一个语句需要时间是1us。然后你要弄懂,C语言的for是怎么走的,for的作用我就不多说了。 你这里的   for(uival=0;uival<valMS;uival++)
for(ujval=0;ujval<113;ujval++);
实际上就是for(uival=0;uival<valMS;uival++)
{
  for(ujval=0;ujval<113;ujval++);
{

}
}

你在主函数里面给延时函数赋值1000,也就是说经过那两个for循环下来,执行了1000*113。相当于110ms,一般来说,人的肉眼能感觉的是25ms左右吧(我也不太记得)。所以你原本的程序延时100ms肉眼是能看出来的,所以你感觉灯在闪烁。   后面你把延时函数的第二个for删了,你赋值1000,也就是执行了1000下。相当于1ms,1ms亮,1ms灭,肉眼是看不出来的。速度很快,你就感觉灯一直在亮着。
作者: 13538505758    时间: 2018-3-7 16:32
删除后因为延时时间短,灯的闪烁肉眼看不到,就变成所谓的常亮了,定义两个变量是为了延迟时间
作者: 2962837191    时间: 2018-3-7 16:51
现在是ms延时,你删掉第二个循环之后延时就不是ms级了,很可能你的延时以ms都没有,由于视觉暂留效应就是常亮了
作者: 出来逛逛    时间: 2018-3-8 15:24
标题: 加一句,应该是与转换成汇编语言后语句条数有关
本帖最后由 出来逛逛 于 2018-3-9 13:38 编辑

函数的每条语句运行需要时间,虽然只有几微秒,延时函数中for语句循环代表了延时函数中执行语句的数量,执行延时函数所需的时间就是延时函数的延时时间。延时函数延时时间长短和延时函数里语句的多少是等价的。灯变常亮是因为闪的太快了,人眼分辨不出来。
作者: ly4517143    时间: 2018-3-9 11:38
你删除一个for循环,延时时间你赋值的时间乘上113的循环,如果删除循环次数不够循环时间太短,人眼看起来就是一直常亮
作者: ToddYam    时间: 2018-3-9 12:36
应该是时间太短造成的
作者: 苏宁cheung    时间: 2018-3-10 11:37
DYQ_DYQ 发表于 2018-3-7 16:31
首先52的机器周期大约1us,也就是说走一个语句需要时间是1us。然后你要弄懂,C语言的for是怎么走的,for的 ...

好的谢谢你的答案

作者: 苏宁cheung    时间: 2018-3-10 11:38
accac 发表于 2018-3-7 16:08
第一个for循环括号没括住,语句结束时加";"

没加好像也可以啊我试过了,不过不知道为什么?

作者: 苏宁cheung    时间: 2018-3-10 11:38
23131sda3dsad 发表于 2018-3-7 16:29
通过循环实现延时函数的原理:单片机执行每一条程序需要时间(时间非常短),通过循环函数,达到延时的目的 ...

谢谢你的回答,我会记下来的

作者: 苏宁cheung    时间: 2018-3-10 11:39
ly4517143 发表于 2018-3-9 11:38
你删除一个for循环,延时时间你赋值的时间乘上113的循环,如果删除循环次数不够循环时间太短,人眼看起来就 ...

谢谢啦

作者: 莫邪0    时间: 2018-3-10 12:35
因为定义两个的延时更长,常亮是因为延时太短,人眼因为余晖效应,看它是常亮的,大致意思就是延时
作者: oceane    时间: 2018-3-10 13:52
延时太短造成的




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1