簡介
PWM:Pulse Width Modulation,即脈衝寬度調製,它是通過對一系列脈衝的寬度進行調製,等效出所需要的波形(包含形狀以及幅值),對模擬信號電平進行數字編碼,也就是說通過調節佔空比的變化來調節信號、能量等的變化。
佔空比:指在一個週期內,信號處於高電平的時間佔據整個信號週期的百分比,例如方波的佔空比就是50%.
應用:調光電路,直流斬波電路、蜂鳴器驅動、電機驅動、逆變電路、加溼機霧化量等,廣泛應用在從測量、通信到功率控制與變換的許多領域中。
以交流調光電路爲例,高電平佔多一點,也就是佔空比大一點亮度就亮一點,佔空比小一點亮度就沒有那麼亮,前提是PWM的頻率要大於我們人眼識別頻率,要不然會出現閃爍現象。
原理
如圖:
ARR是自動重裝載寄存器(TIMx_ARR)的值,CNT是定時器計數器當前的值,CCRx是捕獲/比較寄存器 x(TIMx_CCRx)的值。當計數器 的值CNT小於CCRx,則輸出低電平,大於CCRx,則輸出高電平,通過改變CCRx的值即可改變佔空比,改變ARR的值即可改變週期。
使用相關
工作過程
1,TIMx_CCMR1寄存器的OC1M[2:0]位,設置輸出模式控制器
110:PWM模式1
111:PWM模式22,計數器值TIMx_CNT與通道1捕獲比較寄存器CCR1進行比較,通過比較結果輸出有效電平和無效電平
OC1REF=0 無效電平
OC1REF=1 無效電平
3,通過輸出模式控制器產生的信號TIMx_CCER寄存器的CC1P位,設置輸入/捕獲通道1輸出極性
0:高電平有效
1:低電平有效
4,TIMx_CCER:CC1E位控制輸出使能電路,信號由此輸出到對應引腳
0:關閉
1:開啓
有效電平與無效電平:
首先,OCxREF是一個參考信號,並且被約定
OCxREF有效則OCxREF=1,即高電平爲OCxREF的有效電平;
OCxREF無效則OCxREF=0,即低電平爲OCxREF的無效電平。
相應計算
向上計數,設置PWM模式爲2(即TIMx_CNT<TIMx_CCR1時通道1爲無效電平,否則爲有效電平),使PSC分頻設置成71,ARR的值設置成4999,由TimeOut=(ARR+1)(PSC+1)/Tclk,此時溢出時間爲5ms,並且由每一次計數時間爲(PSC+1)/Tclk=1μs,此時使CCRx的值爲2000,則一個週期內低電平持續時間爲2ms,高電平持續時間3ms。佔空比爲60%。
配置
輸出配置步驟
1.使能定時器與相關IO口時鐘;
2.初始化IO口爲複用功能輸出;
3.把相應引腳設置爲定時器的PWM輸出引腳;(相應引腳在手冊查找,如果需要配置重映射,必須開啓AFIO時鐘,並設置重映射)
4.初始化定時器;(ARR,PSC等)TIM_TimeBaseInit();
5.初始化相應輸出比較參數;TIM_OC2Init();
6.使能預裝載寄存器;TIM_OC2PreloadConfig();
7.使能定時器;TIM_Cmd();
相關結構體
typedef struct
{
uint16_t TIM_OCMode; //設置PWM的模式
uint16_t TIM_OutputState;//輸出使能/使能
uint16_t TIM_OutputNState;
uint16_t TIM_Pulse; //比較值,即CCRx的值,控制佔空比
uint16_t TIM_OCPolarity; //比較輸出極性
uint16_t TIM_OCNPolarity;
uint16_t TIM_OCIdleState;
uint16_t TIM_OCNIdleState;
} TIM_OCInitTypeDef;
PWM模式爲2:TIMx_CNT<TIMx_CCR1時通道1爲無效電平,否則爲有效電平
PWM模式爲1:TIMx_CNT<TIMx_CCR1時通道1爲有效電平,否則爲無效電平
(可在TIMx_CCMR1的OCxM位配置這兩個模式)
配置範例
void TIM3_PWM_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;//相關結構體初始化
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitSrtue;
TIM_OCInitTypeDef TIM_OCInitStrie;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定時器3時鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); //使能GPIO外設和AFIO複用功能模塊時鐘
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED0-->PB.5 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //複用推輓輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度爲50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //根據設定參數初始化GPIOB.5
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE);//重映射函數,部分重映射
TIM_TimeBaseInitSrtue.TIM_Prescaler=psc;//預分頻係數
TIM_TimeBaseInitSrtue.TIM_CounterMode=TIM_CounterMode_Up;//向上計數
TIM_TimeBaseInitSrtue.TIM_Period=arr;//自動裝載值
TIM_TimeBaseInitSrtue.TIM_ClockDivision=TIM_CKD_DIV1;//設置時鐘分割:TDTS = Tck_tim
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitSrtue);//初始化TIMx的時間基數單位
TIM_OCInitStrie.TIM_OCMode=TIM_OCMode_PWM2;//模式2
TIM_OCInitStrie.TIM_OCPolarity=TIM_OCPolarity_High;//輸出極性
TIM_OCInitStrie.TIM_OutputState=TIM_OutputState_Enable;
TIM_OCInitStrie.TIM_Pulse=100;//設置比較值爲100(如果想動態改變佔空比,這裏不要設置,而是用其它函數設置
TIM_OC2Init(TIM3,&TIM_OCInitStrie);//初始化輸出比較參數
TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);//使能輸出比較預裝載
TIM_Cmd(TIM3,ENABLE);//使能定時器
}
之後,在主函數調用並輸入適當的ARR,PSC值即可
附:相關函數
1.設置比較值函數
void TIM_SetCompareX(TIM_TypeDef*TIMx.uint16_t Compare2);
2.使能輸出比較預裝載
void TIM_OC2PreloadConfig(TIM_TypeDef*TIMx.uint16_t TIM_OC2Preload);
3.使能自動重裝載的預裝載寄存器允許位
void TIM_ARRPreloadConfig(TIM_TypeDef*TIMx.FunctionalState NewState);