做STM32智能小車的實驗中會用到定時器PWM輸出,來改變直流電機的轉速。分享本文了解如何通過PWM實現對電機速度的控制。
PWM控制電機速度的基本原理
PWM(Pulse Width Modulation),也就是脈沖寬度調制。
PWM中有一個比較重要的概念,占空比:是一個脈沖周期內有效電平在整個周期所占的比例。
為了實現IO口上電壓的持續性變化,可以調節PWM的占空比。這也能夠使外設的功率進行持續性變化,最終控制直流電機轉速的快慢。如何調節PWM波形的輸出就是重點。相關推薦:STM32中PWM的配置與應用詳解。
上圖中的ARR是我們給定時器的一個預裝載值,CCRx的上下變化是產生PWM波的關鍵。我們假設ARR大于CCRx的部分輸出為高電平(即t1-t2、t3-t4、t5-t6),ARR小于CCRx的部分輸出為低電平(即0-t1、t2-t3、t4-t5),則改變CCRx的值就能改變輸出PWM的占空比。因此,想要控制PWM的輸出波形,重要的就是如何設置ARR與CCRx這兩個寄存器的值了。
STM32定時器中斷
為了便于理解接下來關于PWM應用的內容,先插一段定時器中斷的知識。
產生定時中斷是定時器的用法之一,與定時器用來進行PWM輸出和輸入捕獲相比,定時器中斷更容易理解、掌握。
原理簡介
使用通用定時器進行中斷的原理,其實和開發板Systick定時器進行中斷延時很相似(Stm32入門——Systick定時器),即:用psc(預分頻系數)設置好定時器時鐘后,arr(預裝載值)在每個時鐘周期內減1,當arr減為0時觸發中斷然后進入中斷處理程序進行中斷處理。以下代碼為例:
void TIM3_Int_Init(u16 arr,u16 psc){ RCC->APB1ENR|=1<<1; //TIM3時鐘使能 TIM3->ARR=arr; //設定計數器自動重裝值 TIM3->PSC=psc; //預分頻器設置 TIM3->DIER|=1<<0; //允許更新中斷 TIM3->CR1|=0x01; //使能定時器3 MY_NVIC_Init(1,3,TIM3_IRQn,2);//搶占1,子優先級3,組2 }
RCC->APB1ENR|=1<<1
解釋一下上面這行代碼,由于定時器3(TIM3)是掛在APB1上的外設,所以要打開APB1,這里的預分頻器值psc是來設置TIM3的時鐘頻率的,如果系統時鐘(SYSTICK)頻率為72MHz、psc為7199,則TIM3的時鐘頻率就為:
72MHz/(7199+1)Hz = 10KHz //這里的“+1”是手冊中規定的。
10KHz是什 么意思呢?就是一秒鐘會產生10K個周期,那么一個周期的時間長度就是1/10KHz,如果你想將定時器中斷的時間間隔設置為0.5秒,那么你將arr設置為5000即可,因為arr每減1就需要一個周期的時間,減5000次就經過了5000*(1/10KHz)=0.5秒。
TIM3->DIER|=1<<0
再解釋下上面這一行,設置允許更新中斷,即arr減到0以后可以觸發更新中斷,還有其他類型的中斷。
MY_NVIC_Init(1,3,TIM3_IRQn,2);//搶占1,子優先級3,組2
看上面這行代碼,中斷優先級有搶占優先級和響應(即子優先級)優先級兩種,搶占優先級即:若程序1正在使用CPU,這時如果程序2要求使用CPU,并且程序2的搶占優先級高,則CPU被程序2搶占;若兩者搶占優先級相同,則就算程序2的響應優先級高于程序1,CPU也不能被搶占;若程序1正在使用CPU,程序2和程序3的搶占優先級等于或低于程序1,且程序2的響應優先級高于程序三,則待CPU空出后,程序2先運行,程序3最后運行。TIM3_IRQn是指定將要運行的中斷處理程序號。“組2”是設置中斷優先級分組的,這是因為寄存器提供了四位來設置優先級,組2代表的是前兩位給搶占優先級,后兩位給響應優先級。
PWM模式、有效電平
前面介紹完中斷,再說一下PWM工作原理。相關文章:淺析PWM控制電機轉速的原理。
假設上圖中ARR大于CCRx時輸出為高電平,ARR小于CCRx時輸出為低電平,但在實際運用中可能并非如此,有可能是相反的情況——ARR大于CCRx時輸出為低電平,ARR小于CCRx時輸出為高電平,至于到底是哪種情況,還要看PWM是哪種模式、有效電平又設置的是何種極性了。
模式1:ARR小于CCRx時輸出為“有效”電平,ARR大于CCRx時輸出為“無效”電平。
模式2:ARR小于CCRx時輸出為“無效”電平,ARR大于CCRx時輸出為“有效”電平。
這里說的是“有效”和“無效”,而不是“高”和“低”,也就是說有效電平可高可低,并非一定就是高電平。PWM模式、效電平極性,需要程序員自己配置相關的寄存器來實現。通過下面的代碼來講解。
TIM1_PWM_Init(899,0);//不分頻。PWM頻率=72000/(899+1)=80Khz
上一小節講過關于定時器參數的設置。使用定時器1的通道1來輸出一路PWM波,這里的899設置的就是ARR的值,至于那個0是用來設置TIM1的頻率的,不分頻就代表TIM1的時鐘頻率和系統時鐘相同,這里假設為72MHz。
void TIM1_PWM_Init(u16 arr,u16 psc){ //此部分需手動修改IO口設置 RCC->APB2ENR|=1<<11; //TIM1時鐘使能 GPIOA->CRH&=0XFFFFFFF0; //PA8清除之前的設置 GPIOA->CRH|=0X0000000B; //復用功能輸出 TIM1->ARR=arr; //設定計數器自動重裝值 TIM1->PSC=psc; //預分頻器設置 TIM1->CCMR1|=7<<4; //CH1 PWM2模式 TIM1->CCMR1|=1<<3; //CH1預裝載使能 TIM1->CCER|=0<<1; //OC1 輸出使能 //TIM1->CCER|=1<<1; TIM1->BDTR|=1<<15; //MOE 主輸出使能 TIM1->CR1=0x0080; //ARPE使能 TIM1->CR1|=0x01; //使能定時器1 }
下文具體分析上面的代碼。
前面4-6行是用來配置GPIO口的。
TIM1->ARR=arr; //設定計數器自動重裝值TIM1->PSC=psc; //預分頻器設置
這兩行就是我上門提到的設置定時器的頻率和重裝載值。
TIM1->CCMR1|=7<<4; //CH1 PWM2模式TIM1->CCMR1|=1<<3; //CH1預裝載使能TIM1->CCER|=0<<1; //OC1 輸出使能
這三行是用來設置PWM輸出模式和設置通道的,通道是什么呢?簡單地講就是輸出PWM波的GPIO口,代碼一開始不是設置了PA8這個GPIO口嘛,這個PA8就是通道1。使用通道的話要先進行輸入輸出方向、通道使能的設置。
TIM1->CCER|=1<<1;
這行代碼是用來設置“有效電平”極性的,根據手冊,當TIM1->CCER[1]這位置1時,有效電平為低電平,置0時有效電平為高電平,而默認情況下置0。
TIM1->BDTR|=1<<15; //MOE 主輸出使能
這行代碼只要對高級定時器進行設置,普通定時器無需設置。
TIM1->CR1=0x0080; //ARPE使能
這行代碼是用來使能ARPE,ARPE是什么呢,就是當它被置1時,你自己設置的CCRx會立即生效,如果它被置為0,那么你自己設置的CCRx值不會立即生效(可能之前ARPE已經有值了),而是當之前設置的CCRx生效后才會使用你最新設置的CCRx值。
上面的代碼里沒有對CCRx進行設置,這是因為CCRx常常是一個變化的值,你可以在主函數中用一個for循環+if判斷語句對它進行++或–的操作,從而達到連續改變CCRx值得目的,例如:
for(i=0;i<300;i++){ TIM1->CCR1=i;if(i==300){ i=0; }}
PWM波的周期是由定時器時鐘頻率和預裝載值兩者決定的,預裝載值就是ARR。
預裝載值PSC設置為899,那么,當定時器的當前值val從0增加到899時,一共經過了900個時鐘周期,這900個時鐘周期會產生一個PWM波形,也就是說900個定時器時鐘周期才相當于一個PWM周期,那么PWM的頻率就為72MHz/900=80KHz,周期為1/80KHz。
審核編輯 :李倩
-
直流電機
+關注
關注
36文章
1733瀏覽量
71407 -
PWM
+關注
關注
116文章
5380瀏覽量
218094 -
電機
+關注
關注
143文章
9252瀏覽量
148386
原文標題:STM32通過PWM控制電機速度
文章出處:【微信號:mcu168,微信公眾號:硬件攻城獅】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
評論