關於PWM的STM32
stm32的定時器除了TIM6和TIM7。其他的定時器都可以用來產生PWM輸出。其中高級定時器TIM1和TIM8可以同時產生7路的PWM輸出。而通用定時器也能同時產生多達4路PWM輸出,stm32最多可以同時產生30路PWM輸出。通用定時器TIMx產生PWM輸出,用到寄存器:捕獲/比較模式寄存器TIMx_CCMR1/2)、捕獲/比較使能寄存器(TIMx_CCER)、捕獲/比較寄存器(TIMx_CCR1~4),還有個TIMx的ARR寄存器是用來控制PWM輸出頻率的。
PWM基本原理:
控制方式就是對逆變電路開關器件的通斷進行控制,使輸出端得到一系列幅值相等的脈衝,用這些脈衝來代替正弦波或所需要的波形。也就是在輸出波形的半個週期中產生多個脈衝,使各脈衝的等值電壓爲正弦波形,所獲得的輸出平滑且低次諧波少。按一定的規則對各脈衝的寬度進行調製,即可改變逆變電路輸出電壓的大小,也可改變輸出頻率。
PWM工作過程:
定時器從0開始向上計數
0-t1段,定時器計數器TIMx_CNT值小於CCRx值,輸出低電平
t1-t2段,定時器計數器TIMx_CNT值大於CCRx值,輸出高電平
當TIMx_CNT值達到ARR時,定時器溢出,至此一個PWM週期完成。
PWM一般配置步驟:
- 使能相關時鐘(定時器和GPIO)
- 初始化GPIO
- 初始化定時器
- 初始化輸出比較參數
- 使能自動重裝載的預裝載寄存器
- 使能定時器
- 不斷改變比較值CCRx,達到不同的佔空比效果:TIM_SetCompare2();
//TIM3 PWM輸出初始化,arr:自動重裝值,psc:時鐘預分頻數 void TIM3_PWM_Init(u16 arr,u16 psc) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);//使能定時器3時鐘 //使能GPIO外設和AFIO複用功能模塊時鐘 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE); GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //Timer3部分重映射 //設置該引腳爲複用輸出功能,輸出TIM3 CH2的PWM脈衝波形 GPIOB.5 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //TIM_CH2 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //複用推輓輸出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO //設置在下一個更新事件裝入活動的自動重裝載寄存器週期的值 TIM_TimeBaseStructure.TIM_Period = arr; //設置用來作爲TIMx時鐘頻率除數的預分頻值 TIM_TimeBaseStructure.TIM_Prescaler =psc; TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設置時鐘分割:TDTS = Tck_tim //TIM向上計數模式 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //根據TIM_TimeBaseInitStruct中指定的參數初始化TIMx的時間基數單位 TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure); //初始化TIM3 //選擇定時器模式:TIM脈衝寬度調製模式2 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能 //輸出極性:TIM輸出比較極性高 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC2Init(TIM3, &TIM_OCInitStructure); //根據指定的參數初始化外設TIM3 OC2 //使能TIM3在CCR2上的預裝載寄存器 TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); TIM_Cmd(TIM3, ENABLE); //使能TIM3 }