天天看點

stm32入門——PWM控制直流電機變速

stm32入門——PWM輸出控制直流電機變速

最近剛做了智能小車的尋迹實驗,實驗中用了定時器PWM輸出來改變直流電機的轉速,我在這裡就大緻總結一下PWM相關的知識。

什麼是PWM?

PWM(Pulse Width Modulation)脈沖寬度調制。

占空比:pwm占空比就是一個脈沖周期内有效電平在整個周期所占的比例。

通過調節PWM的占空比就能調節IO口上電壓的持續性變化,是以也能夠控制外設的功率進行持續性變化,也就能控制直流電機的轉速快慢。

那麼重點就在于如何調節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這兩個寄存器的值了。

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波,想詳細了解定時器參數的設定的朋友可以參考(stm32入門——定時器中斷),我這裡簡單介紹一下,這裡的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 										  
}  
           

前三行是用來配置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。

有很多同學私信我很多的問題,也有要手冊和源碼的,CSDN下載下傳要積分,我放公衆hao了:遊俠嵌入式。(計科卓越班的可以私我)

繼續閱讀