PWM:通俗的講,就是對高地電平持續時間的控制。
圖1
如上圖所示,當計數值<CCR時,被判定為低電平。當,CCR<計數值<ARR時,被判定為高電平。
第一步,先初始化PWM的時基函數 HAL_TIM_PWM_Init(&tim3_handler);這個函數的入口參數tim3_handler是個指針,又回到了TIM_HandleTypeDef這個結構體,把Instance和Init進行相關的初始化。
第二步,配置完初始化函數之后,接下來就是配置通道函數。HAL_TIM_PWM_ConfigChannel(&tim3_handler,&TIM3_OC_Handler,TIM_CHANNEL_4);
第三步:使能定時器,相當於啟動定時器。HAL_TIM_PWM_Start(&tim3_handler,TIM_CHANNEL_4);
三個步驟可以放到一個函數中,進行書寫。
void TIM3_PWM_Init() { tim3_handler.Instance = TIM3; tim3_handler.Init.CounterMode = TIM_COUNTERMODE_UP; tim3_handler.Init.Prescaler = 90-1; tim3_handler.Init.Period = 500-1; //可理解為自動裝載值,ARR. HAL_TIM_PWM_Init(&tim3_handler); TIM3_OC_Handler.OCMode = TIM_OCMODE_PWM1; TIM3_OC_Handler.OCPolarity = TIM_OCPOLARITY_LOW; TIM3_OC_Handler.Pulse = 250; HAL_TIM_PWM_ConfigChannel(&tim3_handler,&TIM3_OC_Handler,TIM_CHANNEL_4); HAL_TIM_PWM_Start(&tim3_handler,TIM_CHANNEL_4); }
void TIM_SetCompare(u32 compare) { TIM3->CCR4 = compare; }
定時器時鍾和通道IO口時鍾可以在回調函數中進行。HAL_TIM_PWM_MspInit
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim) { if(htim->Instance == TIM3 ) { __HAL_RCC_TIM3_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); GPIO_InitTypeDef GPIO_Initure; GPIO_Initure.Pin=GPIO_PIN_1; //PA9 GPIO_Initure.Mode=GPIO_MODE_AF_PP; //復用推挽輸出 GPIO_Initure.Pull=GPIO_PULLUP; //上拉 GPIO_Initure.Speed=GPIO_SPEED_FAST; //高速 GPIO_Initure.Alternate=GPIO_AF2_TIM3; //復用為USART1 HAL_GPIO_Init(GPIOB,&GPIO_Initure); //初始化PB1 } }
PWM的相關配置已經完畢,就可以寫主函數了
int main(void) { u8 dir=1; u16 led0pwmval=0; HAL_Init(); //初始化HAL庫 Stm32_Clock_Init(360,25,2,8); //設置時鍾,180Mhz delay_init(180); //初始化延時函數 uart_init(115200); //初始化USART LED_Init(); //初始化LED KEY_Init(); //初始化按鍵 TIM3_PWM_Init(); while(1) { delay_ms(10); if(dir)led0pwmval++; //dir==1 led0pwmval遞增 else led0pwmval--; //dir==0 led0pwmval遞減 if(led0pwmval>300)dir=0; //led0pwmval到達300后,方向為遞減 if(led0pwmval==0)dir=1; //led0pwmval遞減到0后,方向改為遞增 TIM_SetCompare(led0pwmval); //修改比較值,修改占空比 } }
主函數中前面的初始化和按鍵,LED的初始化差不多
主要是while大循環里面的語句。可以看到dir這個關鍵的變量,起着燈光亮度由亮變暗,暗變亮的作用。
TIM_SetCompare(led0pwmval); //修改比較值,修改占空比這個函數正好和圖1是相對應的,
2019-10-14
21:49:58