0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

單片機輸出PWM的常見方法

jf_78858299 ? 來源:嵌入式專欄 ? 作者:strongerHuang ? 2023-05-10 14:53 ? 次閱讀

PWM的應用可以說非常廣泛,控制電機速度、燈光亮度、通信調(diào)制等眾多領域。

PWM的問題小伙伴問的比較多,最近也在用PWM,這里就分享一下關于PWM的一些內(nèi)容。

什么是PWM?

PWM: Pulse Width Modulation,脈沖寬度調(diào)制。

網(wǎng)上的解釋很多,通過下圖,你就能直觀的理解PWM,其實就是高低電平組成的脈沖信號。

圖片

通過改變其中頻率(脈沖周期)、占空比,就能應用在很多場合。

圖片

PWM常見輸出方式

通過上面描述,PWM就是一個IO口以不同的時間周期輸出高、低電平。

1.新手 (菜鳥) 級別

while循環(huán)中,阻塞延時,控制IO口高低輸出:

while(1)
{
  IO口高電平
  Delay阻塞延時
  IO口低電平
  Delay阻塞延時
}

阻塞延時可以是:軟件模擬延時,定時器阻塞延時等。

2.入門 (初級) 級別

while循環(huán)中,非阻賽延時,控制IO口高低輸出:

while(1)
{
  IO口高電平
  Delay非阻塞延時
  IO口低電平
  Delay非阻塞延時
}

非阻賽延時可以是:定時器標識檢測RTOS(系統(tǒng))延時等。

3.熟悉 (中級) 級別

定時器中斷控制IO高低電平輸出:

定時器中斷配置 ——> 啟動定時器 ——> 響應中斷,控制IO高低電平···

4.熟練 (中級+) 級別

定時器PWM硬件控制輸出:

配置PWM對應的IO,以及定時器PWM輸出 ——> 啟動PWM自動輸出···

void AppTask(void *p_arg)
{
  PWM_TIM_Configuration();


  PWM_Output(頻率, 占空比);


  while(1)
  {
    //自己的應用代碼
  }
}

比較:

上面幾種PWM輸出方式,前面三種都會CPU干預PWM的輸出,也就是會占用CPU資源,特別是前面兩種方式,不僅占用CPU,誤差還比較大。

使用第三種中斷方式,如果頻率比較高,CPU消耗的也比較嚴重。這種情況適合于沒有硬件PWM輸出的單片機。

第四種就是單片機自帶硬件PWM輸出功能,只需要簡單配置就可以自動輸出PWM波形,無需CPU干預。

硬件輸出PWM例子

這里以大家熟悉的STM32F1為例:為大家簡單分享一下硬件定時器輸出PWM波形。

PWM定時器相關宏定義:

//定時器計數(shù)時鐘(1M次/秒)
#define PWM_COUNTER_CLOCK         1000000


//預分頻值(與系統(tǒng)時鐘、計數(shù)值有關)
#define PWM_PRESCALER_VALUE       (SystemCoreClock/PWM_COUNTER_CLOCK - 1)

**PWM配置:

**

/**
  * @brief  定時器PWM輸出配置
  * @param  無
  * @retval 無
  */
void PWM_TIM_Configuration(void)
{
  GPIO_InitTypeDef        GPIO_InitStructure;
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  TIM_OCInitTypeDef       TIM_OCInitStructure;


  /* 時鐘配置 */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);


  /* 引腳配置 */
  GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_0;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);


  /* 時基配置 */
  TIM_TimeBaseStructure.TIM_Prescaler = PWM_PRESCALER_VALUE;         //預分頻值
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;        //向上計數(shù)
  TIM_TimeBaseStructure.TIM_Period = 0xFFFF;                         //定時周期(暫定值)
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;            //分頻因子
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);


  /* PWM模式配置 */
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;                  //輸出PWM1模式
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;      //使能輸出
  TIM_OCInitStructure.TIM_Pulse = 0;                                 //脈寬值(暫定值)
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;          //輸出極性(TIM_OC1對應通道1)
  TIM_OC1Init(TIM2, &TIM_OCInitStructure);
}

PWM輸出函數(shù)接口:

/**
  * @brief  輸出PWM
  * @param  Frequency:頻率
            Dutycycle:占空比
  * @retval 無
  */
void PWM_Output(uint32_t Frequency, uint32_t Dutycycle)
{
  uint32_t tim_period;
  uint32_t tim_pulse;


  tim_period = PWM_COUNTER_CLOCK/Frequency - 1;                      //計算出計數(shù)周期(決定輸出的頻率)
  tim_pulse  = (tim_period + 1)*Dutycycle / 100;                     //計算出脈寬值(決定PWM占空比)


  TIM_Cmd(TIM2, DISABLE);                                            //失能TIM
  TIM_SetCounter(TIM2, 0);                                           //計數(shù)清零
  TIM_SetAutoreload(TIM2, tim_period);                               //更改頻率
  TIM_SetCompare1(TIM2, tim_pulse);                                  //更改占空比(TIM_SetCompare1對應通道1)
  TIM_Cmd(TIM2, ENABLE);                                             //使能TIM
}

初始化配置,調(diào)用函數(shù)接口,直接就輸出PWM波形了:

void AppTask(void *p_arg)
{
  PWM_TIM_Configuration();


  PWM_Output(1000, 20);


  while(1)
  {
    //自己的應用代碼
  }
}

輸出PWM波形:

圖片

說明:

本例使用的是STM32標準外設庫,如果要深入理解其中原理,還是建議使用標準外設庫。

當然,如果想要快速使用PWM這個功能,不想理解其原理,可以直接使用STM32CubeMX配置生成代碼:

圖片

配置注意事項

想要更加精確控制,并更加滿足應用層的需求,就需要自己一步一步深入了解原理。

下面說幾點常見的問題吧。

1.引腳映射

如果你使用的引腳需要映射,就需要配置對應的參數(shù)。

比如:STM32F1使用PB11(需要查看數(shù)據(jù)手冊):

圖片

需要增加對應的“映射”代碼:

//復用功能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);


//定時器(PWM)引腳映射
GPIO_PinRemapConfig(GPIO_FullRemap_TIM2, ENABLE);

2.頻率和占空比精度

如果使用32位定時器的話,頻率范圍更寬、精度也可以達到更高。比如:頻率:0.01Hz、 占空比0.01%等。

如果是16位的話,其中的參數(shù)都不能超過16位(65535):

#define PWM_COUNTER_CLOCK         1000000
#define PWM_PRESCALER_VALUE       (SystemCoreClock/PWM_COUNTER_CLOCK - 1)


tim_period = PWM_COUNTER_CLOCK/Frequency - 1;                      //計算出計數(shù)周期(決定輸出的頻率)
tim_pulse  = (tim_period + 1)*Dutycycle / 100;                     //計算出脈寬值(決定PWM占空比)

具體可根據(jù)自己情況進行配置,比如PWM(定時器)計數(shù)時鐘、分頻值等。

實際應用代碼,建議增加各個參數(shù)的判斷,以防越界(這里為了方便理解,就寫的比較簡單)。

3.更多

STM32都有硬件PWM輸出功能,但不同的系列,其配置可能略有一些差異,簡單參考官方例程以及手冊。

現(xiàn)在大部分單片機都自帶有硬件PWM輸出功能,硬件的好處就是不用CPU干預。如果沒有,可以嘗試上面說的定時器中斷的方式。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • IO
    IO
    +關注

    關注

    0

    文章

    430

    瀏覽量

    39012
  • PWM
    PWM
    +關注

    關注

    114

    文章

    5105

    瀏覽量

    212869
  • 通信調(diào)制器

    關注

    0

    文章

    2

    瀏覽量

    5258
  • 電機速度控制

    關注

    0

    文章

    10

    瀏覽量

    1402
收藏 人收藏

    評論

    相關推薦

    單片機Flash自檢和添加CRC常見方法

    市面上很多基于單片機的產(chǎn)品都具有在線或離線升級功能,為了防止升級過程出現(xiàn)意外,一般我們都會對Flash程序數(shù)據(jù)進行校驗,常見的就是添加 CRC 校驗信息。
    發(fā)表于 05-19 10:49 ?4457次閱讀
    <b class='flag-5'>單片機</b>Flash自檢和添加CRC<b class='flag-5'>常見方法</b>

    單片機輸出PWM脈沖有什么方法

    單片機輸出PWM脈沖有什么方法
    發(fā)表于 03-12 07:01

    單片機輸出PWM有哪些注意事項

    單片機輸出PWM常見方法和注意事項(點擊鏈接閱讀原文) ...
    發(fā)表于 01-11 07:54

    單片機PWM控制輸出電路

    電子發(fā)燒友為您提供了單片機PWM控制輸出電路,輸出電路的電流在4~20MA之間。希望對您的工作學習有所幫助!
    發(fā)表于 07-09 16:47 ?1.7w次閱讀
    <b class='flag-5'>單片機</b><b class='flag-5'>PWM</b>控制<b class='flag-5'>輸出</b>電路

    AVR單片機定時器輸出PWM的設計及注意問題

    本內(nèi)容提供了AVR單片機定時器輸出PWM的設計及注意問題,根據(jù)PWM的特點,在使用ATmega128的定時/計數(shù)器設計輸出
    發(fā)表于 11-09 17:39 ?1618次閱讀

    51系列單片機輸出PWM的兩種方法

    PWM利用51單片機的幾種方法,看看,挺好的
    發(fā)表于 11-13 14:41 ?11次下載

    如何利用51單片機輸出PWM

    如何利用51單片機輸出PWM波,控制電機轉動速度
    發(fā)表于 12-31 14:26 ?230次下載

    使用51單片機輸出PWM波形的程序免費下載

    本文檔的主要內(nèi)容詳細介紹的是使用51單片機輸出PWM波形的程序免費下載。
    發(fā)表于 08-29 17:29 ?66次下載
    使用51<b class='flag-5'>單片機</b><b class='flag-5'>輸出</b><b class='flag-5'>PWM</b>波形的程序免費下載

    使用單片機PWM實現(xiàn)電壓輸出的程序免費下載

    本文檔的主要內(nèi)容詳細介紹的是使用單片機PWM實現(xiàn)電壓輸出的程序免費下載。
    發(fā)表于 08-19 17:31 ?18次下載
    使用<b class='flag-5'>單片機</b><b class='flag-5'>PWM</b>實現(xiàn)電壓<b class='flag-5'>輸出</b>的程序免費下載

    MCS-51系列單片機實現(xiàn)PWM輸出功能的方法解析

    MCS-51系列單片機PWM輸出功能,可以采用定時器配合軟件的方法實現(xiàn),對精度要求不高的場合是非常實用的。采用高速光隔6N137輸出,并將
    發(fā)表于 06-20 15:46 ?1910次閱讀

    51單片機實現(xiàn)PWM輸出功能的兩種方法解析

    51單片機沒有PWM輸出功能,可以采用定時器配合軟件的方法實現(xiàn),對精度要求不高的場合是非常實用的。采用高速光隔6N137輸出,并將
    發(fā)表于 08-22 14:51 ?2.1w次閱讀
    51<b class='flag-5'>單片機</b>實現(xiàn)<b class='flag-5'>PWM</b><b class='flag-5'>輸出</b>功能的兩種<b class='flag-5'>方法</b>解析

    使用51單片機輸出PWM方法詳細說明

     51系列單片機PWM輸出功能,可以采用定時器配合軟件的方法輸出。對精度要求不高的場合,非常實用。電路圖見圖一,采用了高速光隔(6N137
    發(fā)表于 05-13 17:54 ?39次下載
    使用51<b class='flag-5'>單片機</b><b class='flag-5'>輸出</b><b class='flag-5'>PWM</b>的<b class='flag-5'>方法</b>詳細說明

    實現(xiàn)STC單片機PWM輸出的程序免費下載

      本文檔的主要內(nèi)容詳細介紹的是實現(xiàn)STC單片機PWM輸出的程序免費下載。
    發(fā)表于 06-28 18:00 ?83次下載
    實現(xiàn)STC<b class='flag-5'>單片機</b><b class='flag-5'>PWM</b><b class='flag-5'>輸出</b>的程序免費下載

    單片機PCA和PWM的關系

    這里寫自定義目錄標題單片機PCA和PWM的關系單片機PCA和PWM的關系PCA指的是單片機的一個功能模塊,然后
    發(fā)表于 11-17 10:51 ?17次下載
    <b class='flag-5'>單片機</b>PCA和<b class='flag-5'>PWM</b>的關系

    單片機I/O驅動與隔離常見設計方法

    單片機I/O驅動與隔離常見設計方法
    的頭像 發(fā)表于 10-25 17:36 ?2131次閱讀
    <b class='flag-5'>單片機</b>I/O驅動與隔離<b class='flag-5'>常見</b>設計<b class='flag-5'>方法</b>