導讀:PWM(Pulse Width Modulation)控制——脈沖寬度調制技術,通過對一系列脈沖的寬度進行調制,來等效地獲得所需要波形(含形狀和幅值)。 PWM控制技術在逆變電路中應用最廣,應用的逆變電路絕大部分是PWM型,廣泛應用在從測量、通信到功率控制與變換的許多領域中。
本文引用地址:http://www.eepw.com.cn/article/272990.htm
PWM是什么——PWM原理
脈寬調制(PWM)基本原理:控制方式就是對逆變電路開關器件的通斷進行控制,使輸出端得到一系列幅值相等的脈沖,用這些脈沖來代替正弦波或所需要的波形。也就是在輸出波形的半個周期中產生多個脈沖,使各脈沖的等值電壓為正弦波形,所獲得的輸出平滑且低次諧波少。按一定的規則對各脈沖的寬度進行調制,即可改變逆變電路輸出電壓的大小,也可改變輸出頻率。
例如,把正弦半波波形分成N等份,就可把正弦半波看成由N個彼此相連的脈沖所組成的波形。這些脈沖寬度相等,都等於 ∏/n ,但幅值不等,且脈沖頂部不是水平直線,而是曲線,各脈沖的幅值按正弦規律變化。如果把上述脈沖序列用同樣數量的等幅而不等寬的矩形脈沖序列代替,使矩形脈沖的中點和相應正弦等分的中點重合,且使矩形脈沖和相應正弦部分面積(即沖量)相等,就得到一組脈沖序列,這就是PWM波形。可以看出,各脈沖寬度是按正弦規律變化的。根據沖量相等效果相同的原理,PWM波形和正弦半波是等效的。對於正弦的負半周,也可以用同樣的方法得到PWM波形。
在PWM波形中,各脈沖的幅值是相等的,要改變等效輸出正弦波的幅值時,只要按同一比例系數改變各脈沖的寬度即可,因此在交-直-交變頻器中,PWM逆變電路輸出的脈沖電壓就是直流側電壓的幅值。
根據上述原理,在給出了正弦波頻率,幅值和半個周期內的脈沖數后,PWM波形各脈沖的寬度和間隔就可以准確計算出來。按照計算結果控制電路中各開關器件的通斷,就可以得到所需要的PWM波形。
下圖為輸出時的PWM波的實時波形。
PWM是什么——特點
PWM的一個優點是從處理器到被控系統信號都是數字形式的,無需進行數模轉換,讓信號保持為數字形式可將噪聲影響降到最小。噪聲只有在強到足以將邏輯1改變為邏輯0或將邏輯0改變為邏輯1時,也才能對數字信號產生影響。
對噪聲抵抗能力的增強是PWM相對於模擬控制的另外一個優點,而且這也是在某些時候將PWM用於通信的主要原因。從模擬信號轉向PWM可以極大地延長通信距離。在接收端,通過適當的RC或LC網絡可以濾除調制高頻方波並將信號還原為模擬形式。
由NE555產生的PWM調速系統
總之,PWM既經濟、節約空間、抗噪性能強,是一種值得廣大工程師在許多設計應用中使用的有效技術。
STM32 PWM的輸出
脈沖寬度模式(PWM模式)可以用來產生一個由TIMx_ARR寄存器確定平率,由TIMx_CCRx寄存器確定占空比的信號。在STM32開發中,由於官方提供了較為完善的庫函數,使得我們的開發工作變得相當的輕松,甚至可以在不需要太多了解硬件結構的條件下,完成我的開發工作,實現我們所需要的功能。在此,筆者也建議大家,在初學的時候盡量去熟悉固件庫中提供的函數來調節PWM的頻率和占空比,對底層寄存器的操作應盡量減少。
本文使用的STM32F103RB的芯片,輸出通道是TIM2_CH2通道,STM32有較強的可移植性,如果讀者的芯片類型跟我不一樣,可以做適當的修改,完成自己的開發。
使用到的庫函數有:
stm32f10x.h:用以系統的初始化,無論做什么開發,該庫必須包含
stm32f10x_tim.h:TIM定時器庫函數
stm32f10x_rcc.h:時鍾配置庫函數
stm32f10x_gpio.h:GPIO配置庫函數
由以上的庫函數可知,我們需要初始化的內容有TIM2定時器,時鍾使能配置,GPIO的使能配置。
void RCC_Config(void); void GPIO_Config(void); void TIM_Config(void);
接下來就是編寫各個函數的函數體,在這些內容里面,其實官方已經給出了示例,我們按照官方給的函數庫進行配置,然后修改一下官方的一些變量屬性即可。
RCC_Config函數體
void RCC_Config(void) { //使能GPIOA,TIM2 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); }
GPIO_Config函數體
void GPIO_Config(void)
{
//GPIO的配置,官方庫有給出需要配置的一些參數,如果忘記了,參照一下即可,我這里配置的是GPIOA_Pin_1 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStructure); }
TIM_Config函數體
在配置函數體之前,先了解一下stm32的占空比以及頻率是如何計算的
①頻率:我們使用的APB1時鍾源是72MHz的,在此我們不做分頻,通過配置相關的參數來設置輸入頻率,計算方法:輸入頻率=APB1時鍾/(預分頻系數+1)=72000000Hz/360=200000Hz
②TIM_TImeBaseStructure.TIM_Period參數決定了輸出PWM波形的頻率,輸出PWM波形的頻率=定時器的輸入頻率/TIM_TImeBaseStructure.TIM_Period,本例程20000Hz/100=200Hz,即5ms一個周期
③配置占空比:占空比=配置占空比的值/ TIM_TImeBaseStructure.TIM_Period,以此計算來確定占空比,本案例的占空比為50/100=50%
④定時器使能
void TIM_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TImeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; //配置TIM2的時鍾輸出頻率,以及其它相關參數初始化 TIM_TImeBaseStructure.TIM_Prescaler=360-1;//設置PWM的頻率 TIM_TImeBaseStructure.TIM_CounterMode=0; TIM_TImeBaseStructure.TIM_Period=100; TIM_TimeBaseInit(TIM2,&TIM_TImeBaseStructure); //設置PWM的輸出方式 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; //配置占空比 TIM_OCInitStructure.TIM_Pulse=50; TIM_OC2Init(TIM2,&TIM_OCInitStructure); TIM_ForcedOC1Config(TIM2,TIM_ForcedAction_Active); TIM_Cmd(TIM2,ENABLE); TIM_CtrlPWMOutputs(TIM2,ENABLE); }
由此,我們的整個PWM配置完成
Main函數
int main() { RCC_Config(); GPIO_Config(); TIM_Config(); while(1) { ; } }
接下來,我們講解一下,在Keil里面看我們的GPIOA_Pin_1引腳的輸出頻率,波形
Keil軟件仿真
①配置調試工具
②打開調試,並設置並檢測GPIO的輸出引腳
③全速運行,觀察示波器