STM32第七章-脈衝寬度調製

2021-01-15 果果小師弟
另外 CC4S 用於設置通道的方向(輸入/輸出)默認設置為00,就是設置通道作為輸出使用。捕獲/比較使能寄存器

見名知意,當然是使能TIM3定時器的啊。使CC4E置位為1就可以了。

捕獲/比較寄存器該寄存器總共有 4 個,對應 4 個通道 CH1~4。我們使用的是通道3。在輸出模式下,該寄存器的值與 CNT 的值比較,根據比較結果產生相應動作。利用這點,我們通過修改這個寄存器的值,就可以控制 PWM 的輸出脈寬了。
程序代碼配置

我們文本的例子是定時器3的通道3,對應PB0管腳。

1.開啟TIM3時鐘,配置 PB0

要使用 TIM3,我們必須先開啟 TIM3的時鐘,這點相信大家看了這麼多代碼,應該明白了。這裡我們還要配置 PB0 為復用輸出(當然還要使能 GPIOB的時鐘),這是因為 TIM3_CH3通道將使用 PB0的復用功能作為輸出,我們配置 PB0為復用輸出,才可以實現 TIM3_CH3的 PWM 經過 PB0輸出。

GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);    //使能TIM外設時鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);  //使能GPIO外設時鐘                                                                      
//設置該引腳為復用輸出功能,輸出TIM3 CH3的PWM脈衝波形
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;         //TIM3_CH3
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //復用推輓輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);

2.設置 TIM3的ARR和PSC在開啟了 TIM3的時鐘之後,我們要設置 ARR 和 PSC 兩個寄存器的值來控制輸出 PWM 的周期。這在庫函數是通過 TIM_TimeBaseInit 函數實現的,在上一節定時器中斷章節已經有講解過,這裡就不詳細講解,調用的格式為:

TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period = 100;     
TIM_TimeBaseStructure.TIM_Prescaler =360-1;     
TIM_TimeBaseStructure.TIM_ClockDivision = 0;  //設置時鐘分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上計數模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根據TIM_TimeBaseInitStruct中指定的參數初始化TIMx的時間基數單位

如果你想修改你的輸出PWM波形的頻率按我上面自己配置即可。3.使能TIM3的CH3輸出

接下來,我們要設置 TIM3_CH3為 PWM 模式,我們要通過配置 TIM3_CCMR2的相關位來控制 TIM3_CH3 的模式。在庫函數中,PWM 通道設置是通過函數 TIM_OC1Init()~TIM_OC4Init()來設置的,不同的通道的設置函數不一樣,這裡我們使用的是通道 3,所以使用的函數是 TIM_OC3Init()。這裡的結構體我就不多少了,自己看一下就可以明白,對於普通定時器我們只需要設置下面這四個參數就可以了。

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //選擇定時器模式:TIM脈衝寬度調製模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能
TIM_OCInitStructure.TIM_Pulse = 500;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //輸出極性:TIM輸出比較極性高
TIM_OC3Init(TIM3, &TIM_OCInitStructure);  //根據TIM_OCInitStruct中指定的參數初始化外設TIMx

③配置佔空比:佔空比=配置佔空比的值/TIM_TImeBaseStructure.TIM_Period,這裡的佔空比為50/100=50% 

50%的佔空比那麼波形也一定是一半高一半低對吧,一會我們仿真看一看。

4使能TIM3

所有的都配置完了,最後能一下TIM3。

TIM_Cmd(TIM3, ENABLE);//使能TIM3

5.使能TIM3的預裝載寄存器

使能TIM3在CCR3上的預裝載寄存器

TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);  ////使能TIM3在CCR3上的預裝載寄存器,即TIM3_CCR3的預裝載值在更新事件到來時才能被傳送至當前寄存器中。
TIM_ARRPreloadConfig(TIM3, ENABLE); //使能TIM3在ARR上的預裝載寄存器    (影子寄存器)

這裡我們來講一下影子寄存器
1.有影子寄存器的有3個:分頻寄存器PSC,自動重裝載寄存器 ARR,自動捕獲CCRx(x是對應的通道),注意,PSC,ARR,CCRx不是影子寄存器,而是它們對應的"預裝載寄存器"
2、影子寄存器才是真正起作用的寄存器,但是ST沒有提供這個寄存器出來,只是提供出與之相對應的預裝載寄存器,分別為"PSC,ARR,CCRx"
3、我們用戶能接觸到,能修改或讀取的都是預裝載寄存器,ST只是把它們開放出來(影子寄存器並沒有開放給用戶),其實就是ARR寄存器,如:TIM3->ARR
4、從預裝載寄存器ARR傳送到影子寄存器,有兩種方式,一種是立刻更新,一種是等觸發事件之後更新;這兩種方式主要取決於寄存器TIMx->CR1中的"APRE"位;

APRE=0,當ARR值被修改時,同時馬上更新影子寄存器的值;APRE=1,當ARR值被修改時,必須在下一次事件發生後才能更新影子寄存器的值;

5、怎麼樣馬上立刻更改影子寄存器的值,而不是下一個事件;方法如下:

將ARPE=0,TIM_ARRPreloadConfig(TIM3, DISABLE);
在ARPE=1,TIM_ARRPreloadConfig(TIM3, ENABLE);


TIM_ARRPreloadConfig設置為DISABLE 和ENABLE的問題,他的作用只是允許或禁止在定時器工作時向ARR的緩衝器中寫入新值,以便在更新事件發生時載入覆蓋以前的值。在開始初始化的時候你已經把

TIM_TimeBaseStructure.TIM_Period=100;  (ARR的值),後來也一直是這個值,原因是你沒有編寫中斷服務函數或者你在中斷服務函數中根本就沒有給ARR緩衝器重新寫入新值,所以設置為DISABLE 和ENABLE都沒有影響,但是最保險的方法就是使能一下。

匯總一下代碼:

void TIM3_PWM_Init()
{  
  GPIO_InitTypeDef GPIO_InitStructure;
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  TIM_OCInitTypeDef  TIM_OCInitStructure;

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能TIM時鐘   
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);//使能GPIO外設時鐘                                                                          

  //設置該引腳為復用輸出功能,輸出TIM3 CH3的PWM脈衝波形
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;         //TIM3_CH3
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //復用推輓輸出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);  
  TIM_TimeBaseStructure.TIM_Period = 100; //輸出PWM波形的頻率=定時器的輸入頻率/TIM_TImeBaseStructure.TIM_Period,200 000Hz/100=2000Hz,即0.5ms一個周期 
  TIM_TimeBaseStructure.TIM_Prescaler =360-1;//不分頻 輸入頻率=APB1時鐘/(預分頻係數+1)=72 000 000Hz/360=200 000Hz =200K 
  TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設置時鐘分割:TDTS = Tck_tim
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上計數模式
  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //選擇定時器模式:TIM脈衝寬度調製模式2
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能
  TIM_OCInitStructure.TIM_Pulse = 50; //佔空比=配置佔空比的值/TIM_TImeBaseStructure.TIM_Period,500/1000=50% 
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //輸出極性:TIM輸出比較極性高
  TIM_OC3Init(TIM3, &TIM_OCInitStructure);  

  TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);  //CH3預裝載使能    
  TIM_ARRPreloadConfig(TIM3, ENABLE); //使能TIM3在ARR上的預裝載寄存器    (影子寄存器)     
  TIM_Cmd(TIM3, ENABLE);  //使能TIM3   
}

6.主函數的編寫

主函數就很簡單,一個while函數就可以解決。

 int main(void)
 {    
    SystemInit ();   
    TIM3_PWM_Init();
       while(1)
       {
    } 
}

根據而上一章講到的方法keil中調試一下,可以清楚地看到周期是0.5ms,跟我們上面設置的一樣。佔空比也是50%,就是1/2。
當然我們這裡設置的PWM波是死的,也就是說是固定的50%。那麼這實際項目中我們一般是要求可變的PWM,最典型的就是控制電機的轉速。舉一個例子,下面是電機的驅動晶片就是TB6612的管腳分配圖。

 TB6612引腳分配:
VM         PWMA---->TIM3_CH3(PBO)
VCC        AIN2---->GPIOB_12
GND        AIN1---->GPIOB_13
AO1        STBY---->GPIOB_14
AO2        BIN1---->GPIOB_15
BO2        BIN2---->GPIOA_12
BO1        PWMB---->TIM3_CH4(PB1)

在這裡我們用GPIOB_12和GPIOB_13的電平高低來控制電機的前進後退,具體的電平高低要看真值表。用TIM3_CH3(PB0)來控制電機的轉速。設置不同的值,電機的轉速就是有快有慢。那麼用哪一個函數來控制呢?

void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);

理所當然,對於其他通道,分別有一個函數名字,函數格式為 TIM_SetComparex(x=1,2,3,4)。現在我們就可以控制 TIM3 的 CH3 輸出 PWM 波了。也就是一個輪子的轉速快慢了。這裡我用一個小小的if語句來使定時器3的通道3的值發生變化。

 int main(void)
 {    
    u16 i=0;  
    SystemInit ();   
    TIM3_PWM_Init();
       while(1)
    {
        i++;
        TIM_SetCompare3(TIM3,i);//定時器3的通道3  
         if(i==100) i=0;
    } 
}

可以明顯的看到PWM波在不斷地變化,那就對應電機轉速的變化或者小燈的明暗程度。至此我們就明白是STM32是如何輸出PWM的。這裡我們來總結一下:我們輸出PWM用到了定時器3,用TIM_Period 和TIM_Prescaler來確定輸出PWM的頻率和周期.用TIM_Pulse來確定佔空比。如果你單純的使用定時器3做定時功能那麼TIM_Period 和TIM_Prescaler來確定需要定時的時間,也就是多長時間進入一次中斷服務函數執行相應的指令。只是在不同的地方叫法不同,本質還是一樣的。聰明的你會了嗎?

相關焦點

  • PWM脈衝寬度調製
    本節課堂將為大家講解到底什麼是PWM(脈衝寬度調製)、為什麼要使用PWM、怎麼產生PWM控制信號等。PWM拆開來就是:【P=Pulse、W=Width、M=Modulation】=>脈衝寬度調製這樣就完成了一個工作時間寬度的調製,我不斷的上班、下班或者不斷地加班、放假,如此循環則為PWM。
  • PWM (脈衝寬度調製)原理與實現
    一、 PWM(脈衝寬度調製Pulse Width Modulation)原理:本文引用地址:http://www.eepw.com.cn/article/201808/385026.htm脈衝寬度調製波通常由一列佔空比不同的矩形脈衝構成,其佔空比與信號的瞬時採樣值成比例。圖1所示為脈衝寬度調製系統的原理框圖和波形圖。
  • 脈衝寬度調製(PWM)器件的測試(圖)
    同時,結合sts 2110b脈衝寬度調製器件測試系統,對pwm器件的測試原理和實現方法加以闡述和介紹。  關鍵詞:脈衝寬度調製;pwm;開關電源 pwm器件概述  pwm器件是隨著開關電源的發展和半導體集成技術的發展而出現的。
  • PWM(脈衝寬度調製)的工作原理、分類及其應用
    脈衝寬度調製脈衝寬度調製(PWM),是英文「Pulse Width ModulaTIon」的縮寫,簡稱脈寬調製,是利用微處理器的數字輸出來對模擬電路進行控制的一種非常有效的技術,廣泛應用在從測量、通信到功率控制與變換的許多領域中。
  • 直接調製自激振蕩電路的簡易脈衝寬度調製電路分析
    採用OP放大器的不穩多諧振蕩器可以獲得正、負對稱的佔空比為1:1的振蕩輸出,若從外部改變閥值電壓,即可實現對脈衝寬度的調製,這種電路非常簡單。採用CR充放電路,對大調製輸入的線性會產生不良影響。振蕩頻率穩定度取決於CR的時間常,所以穩定度也不會高。不過,它可以作為PWM電力控制電路用。
  • 進一步了解PWM,8個脈衝寬度調製應用電路合輯
    PWM一般指脈衝寬度調製。脈衝寬度調製是一種模擬控制方式,根據相應載荷的變化來調製電晶體基極或MOS管柵極的偏置,來實現電晶體或MOS管導通時間的改變,從而實現開關穩壓電源輸出的改變。整理了電路城上8個脈衝寬度調製應用電路,想進一步了解PWM的朋友可以參考下。
  • 開關磁阻電機脈衝寬度調製佔空比的解析計算新方法
    太原理工大學礦用智能電器技術國家地方聯合工程實驗室、太原理工大學電氣與動力工程學院的研究人員田德翔、曲兵妮、宋建成、趙勇,在2019年第21期《電工技術學報》上撰文,提出一種基於電流斬波控制的脈衝寬度調製佔空比解析計算方法,用以解決開關磁阻電機驅動系統電流斬波控制方式下電流脈動大的問題
  • 一文解析stm32產生spwm原理及程序
    打開APP 一文解析stm32產生spwm原理及程序 發表於 2018-05-18 09:11:49 SPWM法就是以該結論為理論基礎,用脈衝寬度按正弦規律變化而和正弦波等效的PWM波形即SPWM波形控制逆變電路中開關器件的通斷,使其輸出的脈衝電壓的面積與所希望輸出的正弦波在相應區間內的面積相等,通過改變調製波的頻率和幅值則可調節逆變電路輸出電壓的頻率和幅值。本文主要詳解stm32產生spwm原理及程序,首先來了解一下生成SPWM波的基理是什麼,具體得跟隨小編一起來了解一下。
  • 新方法準確測量超快X射線脈衝寬度
    條紋相機技術可測量輻射脈衝寬度,然而目前世界上最先進的商用條紋相機也只能實現幾百飛秒的時間分辨,無法準確測量脈衝寬度僅為數飛秒至數十飛秒的XFEL輻射脈衝。 中國科學院上海高等研究院李賓研究員課題組採用單周期太赫茲場調製來測量和復原超快X射線脈衝,提出了超快X射線脈衝激發氣體光電子波包受太赫茲場調製的全動量模型,可以精準測量XFEL輻射脈衝的時域信息。
  • 【E電路】pwm脈衝寬度調製led驅動控制電路圖
    本文主要對pwm脈衝寬度調製led驅動控制電路圖進行了分析說明。
  • 差動脈寬(脈衝寬度)調製電路
    利用對傳感器電容的充放電使電路輸出脈衝的寬度隨傳感器電容量變化而變化。通過低通濾波器得到對應被測量變化的直流信號。
  • 採用脈衝寬度調製技術實現電力機車制動控制系統的設計
    採用脈衝寬度調製技術實現電力機車制動控制系統的設計 黃志武;周立林; 發表於 2020-04-06 10:56:00 1、引 言 隨著我國國民經濟的蓬勃發展和人民生活水平的日益提高
  • 脈衝雷達的優點,脈衝波形參數
    對於機載雷達,每個發射機不可避免的都會產生噪聲,並且會調製到發射機的輸出,產生調製的邊帶噪聲,覆蓋了發射頻率左右很寬的頻帶。儘管這些邊帶噪聲的功率極小,但是仍然比來自目標的回波信號強很多個數量級。從一個脈衝到下一個脈衝,載波頻率可能增大或減小。在一個脈衝內部,載波頻率也可能隨機地或者按照專門方式改變,這被稱為脈內調製。 脈衝寬度 脈衝寬度是指脈衝持續的時間,根據雷達的不同用途,脈衝寬度可以從微秒級到幾千毫秒。
  • 布袋除塵脈衝寬度什麼意思
    布袋除塵脈衝寬度什麼意思,噴吹時辰(又稱脈衝寬度)即脈衝閥打開噴吹的時辰。普通噴吹時辰越長,噴入濾袋內的緊縮空氣量也越多,清灰效果好普通噴吹時辰在0.1s—0.2s,通常取0.15s。反吹脈衝寬度(即電磁閥的噴吹時間)脈衝間隔(即相鄰電磁閥之間噴吹的時間間歇)的調整,脈衝寬度調節範圍:0.03~0.3秒,脈衝間隔調節範圍:3~60秒。
  • 脈衝重複頻率和脈寬對脈衝相噪的靈敏度測試
    2、理論分析 產生脈衝調製信號的通用方法是使用信號源來持續不斷對載波和脈衝波形進行幅度調製,在進行調製之前,先介紹幾個脈衝的標準術語,圖1是脈衝信號的波形,表1表示脈衝信號幾個主要參數。當號信號被脈衝調製後,信號的頻率譜密度會發生變化,圖2為經脈衝調製後的頻率譜。頻率譜特性按脈衝重複頻率PRF(pulse Repetition Frequency)為等間隔的離散頻譜, 頻譜形狀為sinx/x幸格函數。脈寬的倒數為過零點的位置。
  • 調製解調晶片有哪些_調製解調晶片型號匯總
    調製解調的目的   調製的目的是把要傳輸的模擬信號或數位訊號變換成適合信道傳輸的信號,這就意味著把基帶信號(信源)轉變為一個相對基帶頻率而言頻率非常高的帶通信號。該信號稱為已調信號,而基帶信號稱為調製信號。調製可以通過使高頻載波隨信號幅度的變化而改變載波的幅度、相位或者頻率來實現。調製過程用於通信系統的發端。
  • 用Arduino剖析PWM脈寬調製
    PWM(Pulse Width Modulation)簡介PWM,也就是脈衝寬度調製,用於將一段信號編碼為脈衝信號(一般是方波信號)。
  • Stm32的TFT LCD顯示器控制學習筆記
    學習stm32,TFT LCD顯示屏控制是很重要的一章,本人在初步學習STM32遇到了很多困難,所以把學習中積累的部分感覺重要的知識點羅列出來
  • 雷達接收機測試等應用中脈衝信號的產生與調製
    微波信號源產品的一大典型的應用是通過模擬脈衝雷達信號來完成雷達接收機的測試。雷達脈衝信號是具有恆定重複率、恆定脈衝寬度和形狀以及恆定振幅的一系列射頻脈衝。信號源可以利用脈衝信號對連續波信號進行PWM調製來產生上述所需的信號波形。
  • 脈衝寬度對雷射打孔的影響分析
    採用不同脈寬的雷射打孔,產生的現象和打孔原理有很大的區別,不僅如此,即使採用自由震蕩的中等功率脈衝雷射打孔,對打孔的尺寸和孔的質量也有非常大的影響。從計算公式中得到的孔深、孔徑與雷射脈寬無關,只與雷射束的脈衝能量及聚焦情況有關,這是由於採用準穩定破壞模型忽略了材料的飛濺物對雷射的屏蔽作用,使用這樣推到的公式描述孔的形成過程是比較粗糙的。