自然采樣法
規(guī)則采樣法
單極性
雙極性
如何編寫程序
總結(jié)
基本原理SPWM的全稱是(Sinusoidal PWM),正弦脈沖寬度調(diào)制是一種非常成熟,使用非常廣泛的技術(shù);
之前在PWM的文章中介紹過,基本原理就是面積等效原理,即沖量相等而形狀不同的窄脈沖加在具有慣性的環(huán)節(jié)上時,其效果基本相同 。
換句話說就是通過一系列形狀不同的窄脈沖信號,相對應(yīng)時間的積分相等(面積相等),其最終效果相同;
所以SPWM就是輸入一段幅值相等的脈沖序列去等效正弦波,因此輸出為高的脈沖時間寬度基本上呈正弦規(guī)律變化;
這里通常使用的采樣方法是:自然采樣法和規(guī)則采樣法;
自然采樣法自然采樣法是用需要調(diào)制的正弦波與載波鋸齒波的交點,
來確定最終PWM脈沖所需要輸出的時間寬度,最終由此生成SPWM波;
具體如下圖所示,這里會對局部①部分進行簡單分析,下面進一步介紹;
SPWM波形
局部①的情況如下圖所示;簡單分析一下整個圖形的情況;
鋸齒波和調(diào)制正弦波的交點為 A和 B;
因此 A點所需時間為 T1, B點所需時間為 T2;
所以在該周期內(nèi),PWM所需要的脈沖時間寬度 Ton滿足: 最終結(jié)論就是,只要求出 A點和 B點位置,就可以求出 ;

自然采樣法
這里對于求解A,B位置的推導不做介紹,但是計算量比較大,因此在微處理器中進行運算會占用大量資源,下面再介紹另一種優(yōu)化的采樣方法:規(guī)則采樣法。
規(guī)則采樣法根據(jù)載波PWM的電壓極性,一般可以分為單極性SPWM和雙極性SPWM;下面進一步介紹;
單極性單極性SPWM在正弦波的正版周期,PWM只有一種極性,在正弦波的負半周期,PWM同樣只有一種極性,但是與正半周期恰恰相反,具體如下圖所示;
下面取正弦波的正半周期的情況進行分析;

單極性SPWM
正弦波的正半周期整體如下所示;由圖中我們可以知道以下幾點;
載波PWM的周期為 T;
線段 BO為當前這個等腰三角形的垂線;
線段 BO與正弦曲線 相較于點 A;
所以在該周期內(nèi) ,PWM所需要的脈沖時間寬度 Ton滿足:

單極性正半周期
具體的推導過程如下:
第一步:由于O點的位置比較好確認,因此,線段 第二步:這里載波鋸齒波的最大幅值為1,因此線段 第三步:根據(jù)初中學過的相似三角形定理,滿足:
最終簡化得到:
這里對載波的幅值做了歸一化處理,如果鋸齒波的最大值為 ,正弦波的幅值最大為 ,則;
雙極性只要符合面積等效原理,PWM還可以是雙極性的,具體如下圖所示;這種調(diào)制方式叫雙極性SPWM,在實際應(yīng)用中更為廣泛。

雙極性SPWM如何編寫程序上面講到這里PWM的 時間滿足:
其中 為正弦波幅值, 為載波鋸齒波幅值;
那么下面以STM32為例,介紹以下如何進行程序編寫;
首先得先STM32是如何產(chǎn)生PWM?
通過數(shù)據(jù)手冊可以知道,STM32通過TIM輸出PWM,這里有幾個寄存器;
計數(shù)寄存器: CNT
比較寄存器: CCR (決定了占空比,決定了脈沖寬度)
自動重裝寄存器: AAR(決定了PWM的周期)
可能這么說,還是云里霧里的,先看下圖;

STM32的PWM產(chǎn)生原理
STM32中PWM的模式有普通的PWM,和中央對齊的PWM,上圖使用的就是中央對齊PWM;
產(chǎn)生PWM的過程可以分為以下幾個過程;
第一步:配置好TIM, 通常時基和ARR都會配置好,這時候PWM的周期就已經(jīng)被設(shè)定好了,另外時基決定了CNT計數(shù)寄存器增加一次技術(shù)所需的時間;
第二步:剛開始, CNT《CCR,并且 CNT開始增加,這時候PWM的輸出都是低電平;當CNT》CCR之后,PWM輸出為高電平;
第三步:當 CNT的值等于AAR之后, CNT開始減少,同理 CNT《CCR,PWM的輸出低電平;當CNT》CCR,PWM輸出為高電平;
第四步:循環(huán)上述三個步驟;
程序中如何實現(xiàn)?
從上述STM32產(chǎn)生PWM的過程中不難發(fā)現(xiàn), 滿足;
①上一節(jié)推導的公式如下:
②結(jié)合①式和②式,可以得到:
上面公式中用CCR表示CCR寄存器中的值,ARR表示ARR寄存器中的值;
最后需要做的三件事
計算出ARR,一般配置TIM定時器的時候能在數(shù)據(jù)手冊找到公式;
調(diào)制比,也就是 的系數(shù);
根據(jù)③式生成正弦表,然后查表(實時計算因為涉及到較多運算量,所以利用查表,空間換時間,提高效率), 利用PWM的事件去觸發(fā)中斷,更新下一次CCR的值;
正弦函數(shù)表:
const uint16_t indexWave[] = { 0, 9, 18, 27, 36, 45, 54, 63, 72, 81, 89, 98, 107, 116, 125, 133, 142, 151, 159, 168, 176, 184, 193, 201, 209, 218, 226, 234, 242, 249, 257, 265, 273, 280, 288, 295, 302, 310, 317, 324, 331, 337, 344, 351, 357, 364, 370, 376, 382, 388, 394, 399, 405, 410, 416, 421, 426, 431, 436, 440, 445, 449, 454, 458, 462, 465, 469, 473, 476, 479, 482, 485, 488, 491, 493, 496, 498, 500, 502, 503, 505, 506, 508, 509, 510, 510, 511, 512, 512, 512, 512, 512, 512, 511, 510, 510, 509, 508, 506, 505, 503, 502, 500, 498, 496, 493, 491, 488, 485, 482, 479, 476, 473, 469, 465, 462, 458, 454, 449, 445, 440, 436, 431, 426, 421, 416, 410, 405, 399, 394, 388, 382, 376, 370, 364, 357, 351, 344, 337, 331, 324, 317, 310, 302, 295, 288, 280, 273, 265, 257, 249, 242, 234, 226, 218, 209, 201, 193, 184, 176, 168, 159, 151, 142, 133, 125, 116, 107, 98, 89, 81, 72, 63, 54, 45, 36, 27, 18, 9, 0};
中斷服務(wù)函數(shù):
extern uint16_t indexWave[];extern __IO uint32_t rgb_color;/* 呼吸燈中斷服務(wù)函數(shù) */void BRE_TIMx_IRQHandler(void){ static uint16_t pwm_index = 0; //用于PWM查表 static uint16_t period_cnt = 0; //用于計算周期數(shù) static uint16_t amplitude_cnt = 0; //用于計算幅值等級 if (TIM_GetITStatus(BRE_TIMx, TIM_IT_Update) != RESET) //TIM_IT_Update { amplitude_cnt++; //每個PWM表中的每個元素有AMPLITUDE_CLASS個等級, //每增加一級多輸出一次脈沖,即PWM表中的元素多使用一次 //使用256次,根據(jù)RGB顏色分量設(shè)置通道輸出 if(amplitude_cnt 》 (AMPLITUDE_CLASS-1)){ period_cnt++; //每個PWM表中的每個元素使用period_class次 if(period_cnt 》 period_class){ //標志PWM表指向下一個元素 pwm_index++; //若PWM表已到達結(jié)尾,重新指向表頭 if( pwm_index 》= POINT_NUM){ pwm_index=0; } //重置周期計數(shù)標志 period_cnt = 0; } //重置幅值計數(shù)標志 amplitude_cnt=0; }else{ //每個PWM表中的每個元素有AMPLITUDE_CLASS個等級, //每增加一級多輸出一次脈沖,即PWM表中的元素多使用一次 //根據(jù)RGB顏色分量值,設(shè)置各個通道是否輸出當前的PWM表元素表示的亮度 //紅 if(((rgb_color&0xFF0000)》》16) 》= amplitude_cnt) { //根據(jù)PWM表修改定時器的比較寄存器值 BRE_TIMx-》BRE_RED_CCRx = indexWave[pwm_index]; }else{ //比較寄存器值為0,通道輸出高電平,該通道LED燈滅 BRE_TIMx-》BRE_RED_CCRx = 0; } //綠 if(((rgb_color&0x00FF00)》》8) 》= amplitude_cnt){ //根據(jù)PWM表修改定時器的比較寄存器值 BRE_TIMx-》BRE_GREEN_CCRx = indexWave[pwm_index]; }else{ //比較寄存器值為0,通道輸出高電平,該通道LED燈滅 BRE_TIMx-》BRE_GREEN_CCRx = 0; } //藍 if((rgb_color&0x0000FF) 》= amplitude_cnt){ //根據(jù)PWM表修改定時器的比較寄存器值 BRE_TIMx-》BRE_BLUE_CCRx = indexWave[pwm_index]; }else{ //比較寄存器值為0,通道輸出高電平,該通道LED燈滅 BRE_TIMx-》BRE_BLUE_CCRx = 0; } //必須要清除中斷標志位 TIM_ClearITPendingBit (BRE_TIMx, TIM_IT_Update); } }}
責任編輯:haq
-
寄存器
+關(guān)注
關(guān)注
31文章
5608瀏覽量
129998 -
SPWM
+關(guān)注
關(guān)注
14文章
361瀏覽量
63590
發(fā)布評論請先 登錄
通俗易懂的晶振專業(yè)術(shù)語
LED驅(qū)動電路設(shè)計
(通俗易懂版)排針的作用和生產(chǎn)加工中對溫度的要求
單片機C語言入門指導(非常通俗易懂!)
C語言精彩編程百例-364頁
電路基礎(chǔ)學習資料
電源模塊PCB設(shè)計注意事項
TCP三次握手和四次揮手,這樣解釋太通俗易懂了!
全網(wǎng)最通俗易懂SPWM入門教程
評論