PWM --真正的流水灯 傷城~ 2022-08-20 01:15 184阅读 0赞 很早以前,在某个论坛上就看到下面的题目: 用单片机的 I/O 口控制 8 个 LED,要求编写程序,实现下面的功能。 1.第 1、3、5、7 个灯半亮,其余的全亮。 2.第1个亮1/8、第2个亮2/8、第3个亮3/8、第4个亮4/8、第5个亮5/8、第6个亮6/8、第7个亮7/8、第8个全亮。 3.所有的灯逐渐从暗到全亮,再由全亮到暗。 4.8 个灯从第一个开始依次渐亮,直到最后一个。再从最后一个起渐暗,直到第一个。如此循环。 好像是用来搞竞赛的,只是没有看到像样的结果。 这些个要求,都是要使用 PWM 来解决。下面,做而论道依次写出程序,大家看看是否能够满足题目的要求。 ------------------------------------------ 1.第 1、3、5、7 个灯半亮,其余的全亮。 这就太简单了。就是要求 LED 如下显示: ![PWM --真正的流水灯 - 非著名博主 - 电子信息角落][PWM _ - _ -] 程序,都没有什么好编的,就是下面的几行就行。 ;----------------------------------------- ORG 0000H START: MOV P0, \#0 XRL P0, \#55H ;第 1、3、5、7 取反 DJNZ R7, $ ;延时 SJMP $ - 5 ;再去取反 END ;----------------------------------------- ------------------------------------------ 2.第1个亮1/8、第2个亮2/8、第3个亮3/8、第4个亮4/8、第5个亮5/8、第6个亮6/8、第7个亮7/8、第8个全亮。 这个小题,要求 LED 的显示如下: ![PWM --真正的流水灯 - 非著名博主 - 电子信息角落][PWM _ - _ - 1] 程序的思路也不难,只要按照下面的形式,输出数据到接口就行了。 ○○○○○○○○ 全亮 ○○○○○○○● D0灭 ○○○○○○●● D1又灭了 ○○○○○●●● ○○○○●●●● ○○○●●●●● ○○●●●●●● ○●●●●●●● D6~D0都灭了 反复循环的输出上述 8 个数据,那么 D7 就永远是亮的,D6 有 7/8 的时间是亮的,... D0 只亮了 1/8 的时间。 程序如下: ;----------------------------------------- ORG 0000H JMP START ORG 000BH JMP T0\_INT ORG 0030H START: MOV TH0, \#220 ;1250us@11.0592MHz, T0定时方式0 SETB TR0 MOV IE, \#82H MOV 30H, \#00H ;准备数据 MOV 31H, \#03H MOV 32H, \#0FH ;这些数据是交错存放的 MOV 33H, \#3FH ;类似“隔行扫描” MOV 34H, \#01H ;显示起来就显得平滑、稳定 MOV 35H, \#07H MOV 36H, \#1FH MOV 37H, \#7FH /\* ○○○○○○○○ ○○○○○○●● ○○○○●●●● ○○●●●●●● ○○○○○○○● ○○○○○●●● ○○○●●●●● ○●●●●●●● \*/ MOV R0, \#30H ;设定指针 SJMP $ ;----------------------------------------- T0\_INT: ;1.25ms中断一次 MOV TH0, \#220 ;220: 1250us@11.0592MHz MOV P0, @R0 ;输出一个数据 INC R0 ;修改指针 CJNE R0, \#38H, $ + 5 MOV R0, \#30H RETI ;----------------------------------------- END ;----------------------------------------- ------------------------------------------ 3.所有的灯逐渐从暗到全亮,再由全亮到暗。 这个就是呼吸灯,看看做而论道的前一篇博文吧,这里就不重复了。 ------------------------------------------ 4.8 个灯从第一个开始依次渐亮,直到最后一个。再从最后一个起渐暗,直到第一个。如此循环。 这个才是真正的流水灯。LED 显示的一部分截图如下: ![PWM --真正的流水灯 - 非著名博主 - 电子信息角落][PWM _ - _ - 2] 程序也不长,全部的代码,都在下面: ;----------------------------------------- ORG 0000H JMP START ORG 000BH JMP T0\_INT ORG 0030H START: MOV TH0, \#220 ;1250us@11.0592MHz, T0定时方式0 SETB TR0 MOV IE, \#82H MOV R2, \#100 MOV R3, \#0 MOV R4, \#0 SJMP $ ;此处可以编写主程序 ;----------------------------------------- T0\_INT: ;1.25ms中断一次 MOV TH0, \#220 ;220: 1250us@11.0592MHz DJNZ R2, T0\_2 MOV R2, \#100 INC R3 CJNE R3, \#33, T0\_2 MOV R3, \#0 T0\_2: MOV A, R3 ;R3:0~32 ADD A, R4 ;R4:0~7 ADD A, \#TAB - $ - 3 MOVC A, @A + PC MOV P0, A INC R4 CJNE R4, \#08H, $ + 5 MOV R4, \#0 RETI ;本程序用不上 15us ;----------------------------------------- TAB: DB 255,255,255,255,255,255,255,255 DB 127, 63, 31, 15, 7, 3, 1, 0 DB 0, 0, 0, 0, 0, 0, 0, 0 DB 0, 1, 3, 7, 15, 31, 63,127 DB 255,255,255,255,255,255,255,255 ;----------------------------------------- END ;----------------------------------------- 这个小题,做而论道是用查表的方法解决的,程序相当的简短,而且还比较通用,改成别的花样也很容易。 也有另外的方法,毕竟 LED 变化还是有明显的规律的,所以也可以用计算的方法来解决。 有网友确实是这样弄的,可以参考:[http://www.eehome.cn/read-htm-tid-5208.html][http_www.eehome.cn_read-htm-tid-5208.html]。 他这种编程的思路,编写起来就难多了,恐怕,几天也弄不出来。 ------------------------------------------ 上述各个程序,都在硬件系统中,通过了验证。图中的 8 个电容,做硬件试验时,就不用了。 [PWM _ - _ -]: /images/20220731/ac8aeb2016394ad5afe3b9fffebdf4ce.png [PWM _ - _ - 1]: /images/20220731/5090a762466a40e7becad850beb07c9c.png [PWM _ - _ - 2]: /images/20220731/b45a51634a1d4e9c8f450adbe8e9948a.png [http_www.eehome.cn_read-htm-tid-5208.html]: http://www.eehome.cn/read-htm-tid-5208.html
还没有评论,来说两句吧...