今天我学习了NUCLEO-F410开发板官网(链接:click me)提供的一些参考例程,学习了点亮LED和PWM输出的一些示例项目。想着怎么做出一个呼吸灯,于是努力进行了一些修改,终于实现了呼吸灯功能。
呼吸灯就是通过改变PWM脉冲的占空比(duty-cycle, dc)来控制灯的亮度。为了使人眼看不出明显的闪烁,PWM脉冲的频率应不低于100Hz,即周期10ms。
第一步就是产生一个脉宽可变的PWM信号。我一开始尝试写一个子函数来控制dc锯齿状变化,但总是失败。后来放到主函数循环里,可以产生dc循环变化的PWM波。第二步就是让PWM波控制灯亮度。我的想法是让PWM波直接与LED1的引脚PA_5连接。就有了这句代码:
my_led.write(my_pwm);
但是这时灯在达到最大亮度时总是爆闪(亮度突然变大),经过查看库函数,发现这种写法不妥,因为write函数的参数应该是整数,而my_pwm是PwmOut类的对象。
库函数相关部分如下:
/** Set the output, specified as 0 or 1 (int)
*
* @param value An integer specifying the pin output value,
* 0 for logical 0, 1 (or any other non-zero value) for logical 1
*/
void write(int value)
{
// Thread safe / atomic HAL call
gpio_write(&gpio, value);
}
于是我改成了这样:
my_led.write(PA_7);
这样灯的亮度变化就变得柔和了许多。改变wait_ms()函数的参数值可以控制灯闪烁的频率。我使用PA_7口输出PWM波,LED1连接到了PA_5口,工程实现时需要把两个端口通过杜邦线连接在一起才能输出呼吸灯效果。
项目源代码如下:(使用keil MDK5 实现工程)
#include "mbed.h"
DigitalOut my_led(LED1);
PwmOut my_pwm(PA_7);
int main()
{
float i = 0.5;
bool flag = true;
// Set PWM
my_pwm.period_ms(10);
while (1) {
my_led.write(PA_7); //PWM连接至led控制GPIO
my_pwm.write(i); //改变PWM占空比
if(flag){
i+=0.01;
if(i>=1.0) flag=false;
}
else {
i=i-0.01;
if(i<=0) flag=true;
}
wait_ms(10);
}
return 0;
}