找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 14702|回复: 14
收起左侧

新手入门,单片机延时函数看不懂

  [复制链接]
ID:288745 发表于 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循环,结果发现灯变成了常亮,这是怎么回事呢?这个函数的大致意思是什么?为什么要定义两个局部变量?
回复

使用道具 举报

ID:288753 发表于 2018-3-7 16:08 | 显示全部楼层
第一个for循环括号没括住,语句结束时加";"

评分

参与人数 1黑币 +10 收起 理由
admin + 10 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:288641 发表于 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.
为什么要有两个局部变量:因为要实现两个循环函数,一个不够

评分

参与人数 1黑币 +90 收起 理由
admin + 90 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:287770 发表于 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灭,肉眼是看不出来的。速度很快,你就感觉灯一直在亮着。

评分

参与人数 1黑币 +80 收起 理由
admin + 80 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:135900 发表于 2018-3-7 16:32 | 显示全部楼层
删除后因为延时时间短,灯的闪烁肉眼看不到,就变成所谓的常亮了,定义两个变量是为了延迟时间

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:288779 发表于 2018-3-7 16:51 | 显示全部楼层
现在是ms延时,你删掉第二个循环之后延时就不是ms级了,很可能你的延时以ms都没有,由于视觉暂留效应就是常亮了

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:266943 发表于 2018-3-8 15:24 | 显示全部楼层

加一句,应该是与转换成汇编语言后语句条数有关

本帖最后由 出来逛逛 于 2018-3-9 13:38 编辑

函数的每条语句运行需要时间,虽然只有几微秒,延时函数中for语句循环代表了延时函数中执行语句的数量,执行延时函数所需的时间就是延时函数的延时时间。延时函数延时时间长短和延时函数里语句的多少是等价的。灯变常亮是因为闪的太快了,人眼分辨不出来。
回复

使用道具 举报

ID:289589 发表于 2018-3-9 11:38 | 显示全部楼层
你删除一个for循环,延时时间你赋值的时间乘上113的循环,如果删除循环次数不够循环时间太短,人眼看起来就是一直常亮
回复

使用道具 举报

ID:289617 发表于 2018-3-9 12:36 | 显示全部楼层
应该是时间太短造成的
回复

使用道具 举报

ID:288745 发表于 2018-3-10 11:37 | 显示全部楼层
DYQ_DYQ 发表于 2018-3-7 16:31
首先52的机器周期大约1us,也就是说走一个语句需要时间是1us。然后你要弄懂,C语言的for是怎么走的,for的 ...

好的谢谢你的答案
回复

使用道具 举报

ID:288745 发表于 2018-3-10 11:38 | 显示全部楼层
accac 发表于 2018-3-7 16:08
第一个for循环括号没括住,语句结束时加";"

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

使用道具 举报

ID:288745 发表于 2018-3-10 11:38 | 显示全部楼层
23131sda3dsad 发表于 2018-3-7 16:29
通过循环实现延时函数的原理:单片机执行每一条程序需要时间(时间非常短),通过循环函数,达到延时的目的 ...

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

使用道具 举报

ID:288745 发表于 2018-3-10 11:39 | 显示全部楼层
ly4517143 发表于 2018-3-9 11:38
你删除一个for循环,延时时间你赋值的时间乘上113的循环,如果删除循环次数不够循环时间太短,人眼看起来就 ...

谢谢啦
回复

使用道具 举报

ID:261175 发表于 2018-3-10 12:35 | 显示全部楼层
因为定义两个的延时更长,常亮是因为延时太短,人眼因为余晖效应,看它是常亮的,大致意思就是延时
回复

使用道具 举报

ID:290016 发表于 2018-3-10 13:52 | 显示全部楼层
延时太短造成的
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表