拍的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寄存器值
}
}