拍的GIF太朦胧了,就不备份了。。。
呼吸灯的实现实则是通过PWM控制的LED的亮灭时间间隔,由于人眼视觉的暂缓效应,达到预期的效果。
那么呼吸灯的设计思路是怎么的呢?
①需要点灯--LED的配置和实现(GPIO_InitTypeDef结构体)
②时间的调用--定时器的配置(TIM_TimeBaseInitTypeDef结构体)
③时间间隔的控制--PWM的配置和实现(TIM_OCInitTypeDef结构体)
通俗的讲,就是理论上想让LED达到图a的亮灭的效果(LED灯由亮逐渐熄灭后在逐渐点亮),然而在MCU的识别到的高电平为2.2~2.9V以上,也就是说MCU电平变化只有两种情况,高电平(或1)低电平(或0),它没办法达到在电压上 的逐渐升高。因此,利用人眼的暂缓效应,代码设计思想为图b,通过LED的亮灭时间间隔来达到预期的效果。

通过LED8(PC7)实现呼吸灯功能,通过查找数据手册的GPIO复用功能可知,应该使用定时器3的通道2。
void pwm_init()
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;//初始化外设TIMx
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_Init(GPIOC,&GPIO_InitStructure);
TIM_TimeBaseInitStructure.TIM_Period = 900; //PWM频率 = 720000/900=8KHz
TIM_TimeBaseInitStructure.TIM_Prescaler = 0;//100Khz计数频率
TIM_TimeBaseInitStructure.TIM_ClockDivision = 0;//时钟分割
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
TIM_TimeBaseInit(TIM3, & TIM_TimeBaseInitStructure);
GPIO_PinRemapConfig(GPIO_FullRemap_TIM3,ENABLE);//改变指定管脚的映射
//PWM参数配置
TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1; //定时器模式
TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//PWM输出使能
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low; //指定输出引脚的极性
TIM_OC2Init(TIM3,&TIM_OCInitStructure);//开启定时器3的通道2
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);//使能TIMx在CCR2上的预装载寄存器
TIM_Cmd(TIM3,ENABLE);//使能TIMx外设
}
主函数相对简单,使用的普中的例子。
int main()
{
u8 fx=1;//呼吸方向位
u32 ti=0;
pwm_init();
while(1)
{
delay_ms(10);
if(fx==1)
{
ti++;
if(ti>300)
{
fx=0;
}
}
else
{
ti--;
if(ti==0)
{
fx=1;
}
}
TIM_SetCompare2(TIM3, ti);//设置TIMx捕获比较2寄存器值
}
}