学习编程的第一个输出语言是“hello world!”,那DIY单片机的第一个作业就是:点亮你的LED。如果说“hello world!”是机器语言向世界打的招呼,那么呼吸灯就是机器向世界的呼唤。记得小时候看迪迦,每一次能量快耗尽,迪迦的胸前的红灯就会一闪一灭,但是大家都知道,迪迦会使出最后的全力来终结怪兽,然后潇洒离场。
言归正传,在单片机中实现呼吸灯的原理,就是利用PWM波的数字信号等效为正弦波的模拟信号来实现小灯的呼吸。在循环函数中可以使用计数延时方式来实现,如果利用单片机的中断实现的话,又如何实现呢?因为我想在主循环函数中去运行其他的代码,但是又不想割舍呼吸灯,所以以下是我利用ESP32的中断实现呼吸灯。万事都是由简入入繁,由浅入深,当然方法有很多,欢迎大家畅所欲言,分享学习。
如上图,一个周期由5个小单元组成,LED在每一个单元有一个唯一的状态,用一个5个元素组成数组a(1:IO口输出高电平,LED亮;0:IO口输出低电平,LED灭)表示一个周期,那么这个数组随时间变化将如下所示:
于是,根据上面的逻辑,在main.py文件中代码的实现如下:
from machine import Pin
from machine import Timer #导入定时器模块
Led1=Pin(15,Pin.OUT) #配置GPIO15引脚
Led_min=0 #定义数组的访问计数位
Led_period=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] #定义LED状态数组由20个小单元组成
Led_max=0 #访问一个完整数组计数位
Led_status=1 #定义LED亮/灭标志位
def Time1_irq(Time1): #定时器1的回调函数
global Led_min,Led_max,Led_period,Led_status
Led1.value(Led_period[Led_min]) #LED亮/灭灯控制
Led_min+=1 #移动到数组的下一位
if Led_min==len(Led_period): #判断是否访问到数组的最后一位
Led_min=0 #当访问到数组的最后一位后,回到数组的第一位
Led_period[Led_max]=Led_status #改变数组对应位的LED状态
Led_max+=1 #访问一个完整数组,自增1
if Led_max==len(Led_period): #判断是否数组全部变成1或0
Led_max=0
Led_status=not Led_status #LED标志位取反
#主程序入口
if __name__=="__main__":
Time1=Timer(1) #定时器1的初始化
Time1.init(period=1,mode=Timer.PERIODIC,callback=Time1_irq)#定时1ms,周期性工作模式,中断回调函数:Time1_irq
while True: #循环函数
pass
感谢查阅!