在学习了中断函数后突发奇想想自己创建一个用中断函数来控制led灯的闪烁,说干就干,期望达到的效果如下:
按下key1后蜂鸣器发出声音同时led以绿,蓝,红的顺序进行闪烁;按下key2后蜂鸣器停止发出声音同时led灯熄灭。
在经过一番操作后代码如下:
#include <rtthread.h> #include <rtdevice.h> #include <board.h> #define KEY0_PIN_NUM 0 #define BEEP_PIN_NUM 8 int jb,junbian; /*完成对led的初始化*/ void led_start(){ rt_pin_mode(16,PIN_MODE_OUTPUT); rt_pin_write(16,PIN_HIGH); rt_pin_mode(17,PIN_MODE_OUTPUT); rt_pin_write(17,PIN_HIGH); rt_pin_mode(21,PIN_MODE_OUTPUT); rt_pin_write(21,PIN_HIGH); } /*完成对蜂鸣器的初始化*/ void jun_ready(){ rt_pin_mode(8,PIN_MODE_OUTPUT); rt_pin_write(8,PIN_HIGH); } /*完成led的闪烁控制*/ void jun_on(){ rt_pin_write(16,PIN_LOW); rt_thread_delay(50); rt_pin_write(16,PIN_HIGH); rt_pin_write(17,PIN_LOW); rt_thread_delay(50); rt_pin_write(17,PIN_HIGH); rt_pin_write(21,PIN_LOW); rt_thread_delay(50); rt_pin_write(21,PIN_HIGH); } /*完成关闭led的控制*/ void jun_off(){ rt_pin_write(8,PIN_LOW); rt_pin_write(16,PIN_HIGH); rt_pin_write(17,PIN_HIGH); rt_pin_write(21,PIN_HIGH); } void jun_start(){ led_start();//调用led初始化函数 /*将key1和key2设置成上拉输入*/ rt_pin_mode(0,PIN_MODE_INPUT_PULLUP ); rt_pin_mode(45,PIN_MODE_INPUT_PULLUP ); while(1){ rt_pin_attach_irq(0,PIN_IRQ_MODE_FALLING,jun_ready,RT_NULL);//绑定引脚中断回调函数 rt_pin_irq_enable(0,PIN_IRQ_ENABLE);//使能引脚中断 jb=rt_pin_read(8);//读取蜂鸣器的电平 if(jb==PIN_HIGH){ while(jb==PIN_HIGH){ jun_on(); rt_pin_attach_irq(45,PIN_IRQ_MODE_FALLING,jun_off,RT_NULL); rt_pin_irq_enable(45,PIN_IRQ_ENABLE); junbian=rt_pin_read(8); if(junbian==PIN_LOW){ break; } } } } } MSH_CMD_EXPORT(jun_start,sat8 is the best)
现在说一下项目设计的思路,首先在完成对于引脚的初始化后我们首先要做的事就是实现闪烁功能,通过延时函数rt_thread_delay()我们可以轻易做到闪烁的功能。有关本项目所使用到的函数在这里我都写了注释:https://www.mdrfb.com/2019/09/03/examples-of-functions-in-rt_thread/
接下来就要解决用按钮控制的问题了,根据中断回调函数我们可以让程序在读到这一行的时候执行中断并作出相应的操作,
rt_pin_attach_irq(0,PIN_IRQ_MODE_FALLING,jun_ready,RT_NULL);//绑定引脚中断回调函数 rt_pin_irq_enable(0,PIN_IRQ_ENABLE);//使能引脚中断
这两行实现了使用key1按钮来让蜂鸣器器响起来的功能因为蜂鸣器要和led灯一起闪烁所以我们需要时刻对蜂鸣器进行电平检测,当电平被检测为高时就代表我们的led就要开始闪起来了,
jb=rt_pin_read(8);//读取蜂鸣器的电平
这一行代码完成了对于蜂鸣器电平的检测,再根据if函数来执行检测到蜂鸣器电平为high时led开始闪烁的功能。
因为我们还要通过key2按钮来关闭led和蜂鸣器所以我们还要再打一行中断回调函数和使能引脚中断,
rt_pin_attach_irq(45,PIN_IRQ_MODE_FALLING,jun_off,RT_NULL); rt_pin_irq_enable(45,PIN_IRQ_ENABLE);
根据上文的思路,当蜂鸣器电平变低时led就要熄灭所以我们又添加了一条检测函数,
junbian=rt_pin_read(8);
再根据if判断语句和c语言中break指令完成对闪烁的中断,也就是跳出while循环,至此我们的操作目标已经都达成了。
在编写此类程序的时候有一点需要注意,有些人在编程时会忽略编译器对于读取程序的顺序,程序在运行时速度非常快所以有时候会发生这种情况,我的程序明明符合逻辑天衣无缝为什么下载到开发板上后功能却不完全或根本没有功能,为了达到随按随停,随按随开的功能我们要在主体函数外边加一个while(1)循环,也就是无限循环,否则就会发生按了按钮灯死活不亮的反应,因为你的程序早就被执行完毕了!