性无码一区二区三区在线观看,少妇被爽到高潮在线观看,午夜精品一区二区三区,无码中文字幕人妻在线一区二区三区,无码精品国产一区二区三区免费

小麥大叔
認證:普通會員
所在專題目錄 查看專題
UART協(xié)議快速掃盲(圖文并茂+超詳細)
I2C協(xié)議快速掃盲
原來SPI并沒有我想的那么簡單
芯片的大小端到底是怎么回事?
別找了,這篇SPWM入門教程完全夠用
太難了,炸機后才去注意PWM的死區(qū)時間
作者動態(tài) 更多
一款輕量級的開源GUI項目——SimpleGUI,可以完美適配單色屏
02-22 09:47
看到這100多個軟硬件開源項目,真是爽爆了
2024-11-30 14:12
推薦一個高效,可靠,安全的串口通訊開源方案
2024-11-27 11:17
推薦一款開源hack硬件平臺工具
2024-11-26 13:58
新手學(xué)STM32的話,先學(xué)標(biāo)準(zhǔn)庫還是HAL庫?
2024-10-18 15:09

別找了,這篇SPWM入門教程完全夠用

本文簡單介紹了SPWM的原理和調(diào)制方法,推導(dǎo)了SPWM的PWM脈沖寬度的計算時間,最后給出了基于STM32單片機產(chǎn)生SPWM驅(qū)動呼吸燈的部分代碼。如果覺得不錯,歡迎關(guān)注、分享、收藏、點贊、下載代碼。希望能幫助到大家,如有錯誤敬請指出,謝謝!

目錄

  • 基本原理
  • 自然采樣法
  • 規(guī)則采樣法
    • 單極性
    • 雙極性
  • 如何編寫程序
  • 總結(jié)

基本原理

SPWM的全稱是(Sinusoidal PWM),正弦脈沖寬度調(diào)制是一種非常成熟,使用非常廣泛的技術(shù);

之前在PWM的文章中介紹過,基本原理就是面積等效原理,即沖量相等而形狀不同的窄脈沖加在具有慣性的環(huán)節(jié)上時,其效果基本相同 。

換句話說就是通過一系列形狀不同的窄脈沖信號,相對應(yīng)時間的積分相等(面積相等),其最終效果相同;

所以SPWM就是輸入一段幅值相等的脈沖序列去等效正弦波,因此輸出為高的脈沖時間寬度基本上呈正弦規(guī)律變化;

這里通常使用的采樣方法是:自然采樣法和規(guī)則采樣法;

自然采樣法

自然采樣法是用需要調(diào)制的正弦波與載波鋸齒波的交點,

來確定最終PWM脈沖所需要輸出的時間寬度,最終由此生成SPWM波;

具體如下圖所示,這里會對局部①部分進行簡單分析,下面進一步介紹;

[SPWM波形 ]

局部①的情況如下圖所示;簡單分析一下整個圖形的情況;

  • 鋸齒波和調(diào)制正弦波的交點為AB;
  • 因此A點所需時間為T1,B點所需時間為T2
  • 所以在該周期內(nèi),PWM所需要的脈沖時間寬度Ton滿足:
  • 最終結(jié)論就是,只要求出A點B點位置,就可以求出;

[自然采樣法 ]

這里對于求解A,B位置的推導(dǎo)不做介紹,但是計算量比較大,因此在微處理器中進行運算會占用大量資源,下面再介紹另一種優(yōu)化的采樣方法:規(guī)則采樣法

規(guī)則采樣法

根據(jù)載波PWM的電壓極性,一般可以分為單極性SPWM和雙極性SPWM;下面進一步介紹;

單極性

單極性SPWM在正弦波的正版周期,PWM只有一種極性,在正弦波的負半周期,PWM同樣只有一種極性,但是與正半周期恰恰相反,具體如下圖所示;

下面取正弦波的正半周期的情況進行分析;

[單極性SPWM ]

正弦波的正半周期整體如下所示;由圖中我們可以知道以下幾點;

  • 載波PWM的周期為T;
  • 線段BO為當(dāng)前這個等腰三角形的垂線;
  • 線段BO與正弦曲線 相交于點A;
  • 所以在該周期內(nèi),PWM所需要的脈沖時間寬度Ton滿足:

[單極性正半周期 ]

具體的推導(dǎo)過程如下:

  • 第一步:由于O點的位置比較好確認,因此,線段

  • 第二步:這里載波鋸齒波的最大幅值為1,因此線段

  • 第三步:根據(jù)初中學(xué)過的相似三角形定理,滿足:

最終簡化得到:

這里對載波的幅值做了歸一化處理,如果鋸齒波的最大值為,正弦波的幅值最大為,則;

雙極性

只要符合面積等效原理,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的輸出都是低電平;當(dāng)CNT>CCR之后,PWM輸出為高電平;
  • 第三步:當(dāng)CNT的值等于AAR之后,CNT開始減少,同理CNT<CCR,PWM的輸出低電平;當(dāng)CNT>CCR,PWM輸出為高電平;
  • 第四步:循環(huán)上述三個步驟;

腦補一下畫面,或者結(jié)合上圖理解一下,知道整體過程,暫時先忽略細節(jié),繼續(xù)看下面;

程序中如何實現(xiàn)?

從上述STM32產(chǎn)生PWM的過程中不難發(fā)現(xiàn),滿足;

上一節(jié)推導(dǎo)的公式如下:

結(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){    
    
    //標(biāo)志PWM表指向下一個元素
    pwm_index++;            

    //若PWM表已到達結(jié)尾,重新指向表頭
    if( pwm_index >=  POINT_NUM){
     pwm_index=0;
    }
    //重置周期計數(shù)標(biāo)志
    period_cnt = 0;
   }
   //重置幅值計數(shù)標(biāo)志
   amplitude_cnt=0;           
  
  }else{ 
   //每個PWM表中的每個元素有AMPLITUDE_CLASS個等級,
   //每增加一級多輸出一次脈沖,即PWM表中的元素多使用一次
   //根據(jù)RGB顏色分量值,設(shè)置各個通道是否輸出當(dāng)前的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;  
   }
   //必須要清除中斷標(biāo)志位
   TIM_ClearITPendingBit (BRE_TIMx, TIM_IT_Update); 
  }
 }
}

總結(jié)

本文簡單介紹了SPWM的原理和調(diào)制方法,推導(dǎo)了SPWM的PWM脈沖寬度的計算時間,最后給出了基于STM32單片機產(chǎn)生SPWM驅(qū)動呼吸燈的部分代碼,完整代碼點“下載資料“即可獲取。

由于作者能力和水平有限,文中難免存在錯誤和紕漏,請不吝賜教。


聲明:本內(nèi)容為作者獨立觀點,不代表電子星球立場。未經(jīng)允許不得轉(zhuǎn)載。授權(quán)事宜與稿件投訴,請聯(lián)系:editor@netbroad.com
本篇所含全部資料,點擊此處留下郵箱我會發(fā)給你
資料明細:SPWM.zip
覺得內(nèi)容不錯的朋友,別忘了一鍵三連哦!
贊 6
收藏 31
關(guān)注 144
成為作者 賺取收益
全部留言
0/200
  • 冬郎 2024-05-18 13:53
    老師,能不能發(fā)我一下資料,謝謝! 29****@****.com
    回復(fù) 10條回復(fù)
  • pzg1989 2023-06-15 19:58
    老師,能不能發(fā)我一下資料,謝謝! xi****@****.com
    回復(fù) 1條回復(fù)
  • dy-VI7akaDZ 2023-06-04 20:40
    老師,能不能發(fā)我一下資料,謝謝! 28****@****.com
    回復(fù) 1條回復(fù)
  • songxium 2023-03-27 14:15
    老師,能不能發(fā)我一下資料,謝謝! so****@****.com
    回復(fù) 1條回復(fù)
  • sdll825 2023-03-16 22:21
    老師,能不能發(fā)我一下資料,謝謝! sd****@****.com
    回復(fù) 2條回復(fù)
  • 祥哥618 2022-10-05 17:30
    老師,能不能發(fā)我一下資料,謝謝! 72****@****.com
    回復(fù) 1條回復(fù)
  • 祥哥618 2022-10-05 17:29
    老師,能不能發(fā)我一下資料,謝謝! 72****@****.com
    回復(fù) 1條回復(fù)
  • dy-GrBeUvnf 2022-08-06 20:47
    非常感謝老師 14****@****.com
    回復(fù) 1條回復(fù)
  • ruqihua 2022-08-01 17:42
    老師,能不能發(fā)我一下資料,謝謝! ru****@****.com
    回復(fù) 1條回復(fù)
  • Charles〃hy 2022-03-29 18:56
    老師,能不能發(fā)我一下資料,謝謝! 11****@****.com
    回復(fù) 1條回復(fù)
  • dy-npFVLEGQ 2022-03-17 22:50
    老師,能不能發(fā)我一下資料,謝謝! 84****@****.com
    回復(fù) 1條回復(fù)
  • 蔡徐坤 2022-03-15 01:52
    老師,能不能發(fā)我一下資料,謝謝! 31****@****.com
    回復(fù) 1條回復(fù)
  • dy-A2NSWuqV 2022-02-23 13:05
    老師,能不能發(fā)我一下資料,謝謝! BL****@****.com
    回復(fù) 1條回復(fù)
  • dy-uKrvqqiP 2022-02-16 20:31
    老師,能不能發(fā)我一下資料,謝謝! 62****@****.com
    回復(fù) 1條回復(fù)
  • fcbqing 2021-12-26 15:55
    老師,能不能發(fā)我一下資料,謝謝! 24****@****.com
    回復(fù) 1條回復(fù)
  • dy-Ix4eHufp 2021-12-09 11:47
    老師,能不能發(fā)我一下資料,謝謝! 47****@****.com
    回復(fù) 1條回復(fù)
  • csggg 2021-10-30 19:08
    老師,能不能發(fā)我一下資料,謝謝! xi****@****.com
    回復(fù) 1條回復(fù)
  • linus 2021-08-02 18:30
    老師,能不能發(fā)我一下資料,謝謝! li****@****.com
    回復(fù) 1條回復(fù)
  • oicq123258 2021-07-19 01:20
    老師,能不能發(fā)我一下資料,謝謝! 27****@****.com
    回復(fù) 1條回復(fù)
  • bbb201105 2021-07-16 21:27
    老師,能不能發(fā)我一下資料,謝謝! 91****@****.com
    回復(fù) 1條回復(fù)