上一节我们学习了用51单片机点亮LED,这节我们继续围绕点灯进行进一步学习——实现跑马灯效果。
跑马灯的核心就是LED闪烁,要实现LED的闪烁,那就需要周期性地控制LED的亮和灭,而亮和灭的间隔如何实现呢就得用到延时了,本实验的延时采用阻塞式延时(让程序不停地执行空语句,空耗处理器的时间)。
文章目录
- 一、单个LED闪烁
-
- 实验代码
- 编译+烧录
- 实验效果
- 二、LED跑马灯
-
- 实验代码
- 实验效果
- 三、其他花样灯
-
- 流水灯
- 呼吸灯
一、单个LED闪烁
在介绍代码前,我们先来讨论延时的实现,在学习定时器之前,我们只能通过空语句的方法实现延时。接下来的内容十分枯燥,建议跳过,直接看实验代码。
我们先看看单行C代码(一行空语句)在51单片机里需要运行的时间:
_nop延时这里就不讨论了,只讨论空语句
首先使用软件调试,在空语句之前程序运行时间为(0.1955ms)【单片机从0s开始运行】;
这里需要注意一点,51单片机的类型只有2个字节,最大的数值为,如果用,最大能使用,虽然可以用类型(4字节),但 上说效率会降低,作为新手,我们还是保险点,尽量使用常用的类型,我就先用0.5秒做实验(50000行空语句)
同样,使用软件仿真查看,由于空语句前的运行时间和之前相同,所以我直接给出执行完50000行空语句后的运行时间,(225.29850ms),与空语句前的运行时间的差值大约为。
这和我们设想的0.5秒相差得太大了吧。其实这里我犯了一个错误—–细心的朋友会发现,之前我算的并不是空语句的运行时长,而是一个运行的时长,即一个语句再加一个空语句。
上面的调试都是使用Keil软件进行的,软件仿真往往只能作为参考,所以我们还需对开发板进行实测
就测试250ms延时吧,利用刚才得出的结果—–每次循环运行耗时为4.5us(i不能太小,也不能超过65535)。
0.25s需要的循环空语句数量约为(保留整数)
测试代码见下文,其实就是LED闪烁的实验代码。
实验代码
在写代码前,我们需要先创建一个Keil工程,创建工程的步骤已经在第一节讲述,传送门:(点我)。这里就不进行赘述。
编译+烧录
程序编写完成后,接下来的操作就是编译+烧录了,这些步骤已经在本系列第一篇文章中讲述,传送门:(点我)。不过这里还是会简单描述一下操作过程:
- 点击编译按钮,如果怕出现意外,可以点第三个(重新编译),编译完成后窗口会显示 错信息,如果没有错误和警告(如果这几行都有警告,那说明有问题),且生成了文件,说明编译成功。
实验效果
- 实际效果:可以看到右边的LED1在闪烁,闪烁间隔约为250ms(250ms为软件仿真值,下文实测值为540~660ms)。
- 很遗憾,实际测试的时间和软件仿真相差很大,下面第一张图是灯亮到灯灭的延时时间,542ms,是250ms的两倍多。
二、LED跑马灯
从LED闪烁的实验我们可以得知用C语言的空语句实现的延时是十分不准确的,但这些误差人眼并不能识别出来,所以本实验继续使用循环实现延时。这次我就不进行软件仿真来调延时时间了,因为仿真的时间和真实时间相差太大。
根据上文的延时时间实测结果,空语句循环次数为时,延时时间大约为,所以我们可以算出运行一次耗时约(这和第一次软件仿真的结果相同,奇怪了)。
同时为了提高代码简洁度,我把延时代码封装成了一个函数,这样重复调用时就更加方便了:
接下来就是实现跑马灯了:
跑马灯大家应该听说过,有些人喜欢叫流水灯,这里我不对它们进行区分,我要实现的就是8个LED依次亮灭,这就是核心原理了,直接上代码吧(下文)。
实验代码
下面是跑马灯的完整代码
如果你对下面这行代码不理解,你可以去看我的上一篇文章,里面介绍了的含义,传送门:(点我)。
实验效果
- 实际效果:(不用管数码管,同时gif图片进行了加速)
三、其他花样灯
有了延时函数,你想实现怎样的LED灯效果都行。
下面展示流水灯和呼吸灯的代码。
流水灯
我这里说的流水灯指的是LED像水流一样点亮,即LED依次点亮但不立刻熄灭,等到8个LED都点亮后,再把所有灯一次性熄灭。
- 实际效果:(不用管数码管,同时gif图片进行了加速)
呼吸灯
呼吸灯使用模拟PWM实现,函数用来设置8个LED的亮度,然后动态地修改这个亮度,就能实现呼吸灯的效果,代码如下:
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!