Dotcpp  >  编程教程  >  LED及入门  >  延时1秒

延时1秒

点击打开在线编译器,边学边练

1.准确延时

学会了上一讲的软件调试教学,我们现在用软件调试出延时很接近1毫秒的代码:

for(j=115;j>0;j--);

如果要延时1秒,那是不是循环1000次这条语句呢?

for(i=0;i<1000;i++)
{
    for(j=115;j>0;j--);
}

可是这段代码在软件调试中发现循环1000次这个1毫秒的延时语句时却跟1秒差距有点大(大于5ms对于单片机来说是一个很大的误差),在《手把手教你学51单片机》文档的4.4节也提到C 语言的延时时间是不能通过程序看出来的,所以我们只能在软件中继续调试新的延时1秒的代码。

这里调试出很接近1秒的延时代码如下

for(i=0;i<19601;i++)

{

    for(j=5;j>0;j--);

}  

这里需要变量i和j都必须是unsigned int类型才调试得出准确延时1秒。


2.LED间隔1秒闪烁

用本教程的开发板实现LED亮一秒灭一秒闪烁循环的代码:

#include <reg52.h> 
sbit LED2  = P0^0;
sbit ADDR2 = P1^2;
sbit ADDR1 = P1^1;
sbit ADDR0 = P1^0;
sbit ENLED = P1^4;
sbit ADDR3 = P1^3;

void main()
{  
    unsigned int i,j;//定义两个16位的变量  
    ADDR3 = 1;//使能三八译码器
    ENLED = 0;// 

    ADDR2 = 1;//**************************
    ADDR1 = 1;//让三八译码器的IO6输出低电平
    ADDR0 = 0;//**************************

    while (1)
    {
        LED2=0;//点亮最右端的灯
        for(i=0;i<19601;i++)//延时1s
        {
            for(j=5;j>0;j--);
        }
        LED2=1;//熄灭最右端的灯
        for(i=0;i<19601;i++)//延时1s
        {
            for(j=5;j>0;j--);
        }
    }
}

如果把j定义为unsigned char类型,那这一段延时代码就不是1秒了,读者可以测试一下。所以说真的不能用常识来分析代码呀。

还有笔者发现这个代码在实验现象上有说不出的怪样,如果大家拿手机的秒表计时与灯的闪烁对比,即使我们给单片机上电的瞬间立马同步按下手机秒表计时按键,发现刚开始灯的闪烁与计时器还同步,后面过了几秒发现灯的状态跳变与秒表的数字跳变不同步了,软件仿真发现的确循环一次之后时间会加多。

可如果我们像下面这样三种写法led17

仅在后面加多一条简单的语句,上面所说的现象就消失了,也就是灯的跳变和计时的数字跳变是同步的,这个问题笔者还在查找原因,我们姑且先放一下这个纠结,继续往下学习先。

此时读者需要自己加入语句后拿手机秒表计时观察,看看是否灯的跳变与秒表数字的跳变同步,在此之前要保证手机的计时与单片机上电时间同步。


本文固定URL:https://www.dotcpp.com/course/182

单片机教程
第一章 单片机入门
第二章 LED及入门
第三章 蜂鸣器
第四章 数码管
第五章 独立按键
第六章 多文件编程
第七章 外部中断
第八章 定时器
第九章 舵机与超声波模块
第十章 串口通信
第十一章 1602液晶屏
第十二章 IIC通信
第十三章 红外遥控与温度传感器
第十四章 AD与DA
第十五章 混合例程
第十六章 完结
Dotcpp在线编译      (登录可减少运行等待时间)