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

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

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

点赞(1)

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

Dotcpp在线编译      (登录可减少运行等待时间)