51單片機(jī)-PWM調(diào)速(直流電機(jī),智能小車的電機(jī)調(diào)速)

大家好,今天給大家介紹51單片機(jī)-PWM調(diào)速,下方附有本文涉及的全部資料和源代碼的獲取方式,可進(jìn)群免費(fèi)領(lǐng)取。

點(diǎn)擊這里找小助理0元領(lǐng)取:

一、PWM

PWM即脈沖寬度調(diào)制,在具有慣性的系統(tǒng)中,可以通過對一系列脈沖的寬度進(jìn)行調(diào)制,來等效的獲得所需要的模擬參量。

說白了就是通過控制高低電平的時間,來對輸出的波形進(jìn)行控制。

其中有幾個重要的參數(shù)

  • 頻率:頻率等于周期頻率除以1
  • 占空比:高電平在整個周期內(nèi)所占的時間,即高電平和周期時間的比值
  • 精度:占空比變化的步距

二、產(chǎn)生PWM的方法

下方為江科大ppt教程ppt里的圖就是通過定時器定時自增,設(shè)置一個比較值,然后通過判斷計(jì)數(shù)器和比較值的大小,輸出對應(yīng)的高低電平

波形詳解,就比如第一個周期內(nèi),小于比較值60的部分輸出的是低電平,大于比較值60的部分輸出高電平。兩圖的波形等效,PWM波形就這樣產(chǎn)生了,控制不同的高低電平存在的時間,然后輸出。

使用定時器產(chǎn)生一個恒定的周期

這里沒有限制使用什么定時器,當(dāng)使用多個定時器的時候,一定要注意不同定時器中斷和外部中斷的優(yōu)先級,因?yàn)槿绻煌〞r器的中斷優(yōu)先級不相同,就有可能一個優(yōu)先級較高的定時器中斷打破了當(dāng)前定時器產(chǎn)生的中斷。使當(dāng)前中斷失效。下方為中斷優(yōu)先級以及使用C語言編程使用到的中斷號

例程序
定時器0產(chǎn)生恒定周期

#include <REGX52.H> /**
  * @brief 定時器0初始化
  * @param  
  * @retval 
  */ void Timer0Init() //100us  10ms  11.0592MHZ {
	TMOD&=0xF0; //高四位不變 TMOD|=0x01; //設(shè)置定時器模式1 以及設(shè)置為定時方式 0 TL0 = 0xA4; //設(shè)置定時初值 TH0 = 0xFF; //設(shè)置定時初值 TF0=0; //定時器0溢出標(biāo)志位 TR0=1; //定時器0運(yùn)行控制位 TF0=1; //設(shè)置外部中斷 ET0=1;
	EA=1;
	PT0=0;
} //中斷函數(shù) /*void Timer0_Rourine() interrupt 1
{
	static unsigned int T0count;
		TL0 = 0xA4;		//設(shè)置定時初值
	TH0 = 0xFF;		//設(shè)置定時初值
	T0count++;
	if(T0count>=1000)
	{
		T0count=0;
		P2_0=~P2_0;
	}
}*/


中斷服務(wù)子程序里設(shè)置比較值

和比較值相比較大小,可以自己設(shè)置究竟是大于比較值,輸出高電平還是低電平,同時小于比較值也同理

void Timer0_Rourine() interrupt 1 //每隔100us進(jìn)來一次 {
	TL0 = 0xA4; //設(shè)置定時初值 TH0 = 0xFF; //設(shè)置定時初值 Counter++; if(Counter>=100){Counter=0;} if(Counter<Compare) //小于比較值 輸出高電平 {
		out1=1; //out代表輸出高電平對應(yīng)的管腳 } else { out=0;
	}

三、實(shí)驗(yàn)

使用PWM對直流電機(jī)調(diào)速

通過按鍵控制直流電機(jī)的速度,使速度在數(shù)碼管上顯示,通過PWM調(diào)速
主程序
定時器0程序,和上方定時器0,程序相同

#include <REGX52.H> #include "Delay.h" #include "Key.h" #include "Timer0.h" #include "NixieTube.h" sbit motor=P1^0; //電機(jī)端口 unsigned char Counter,Compare; //counter 0-100 指的是頻率 comapre 指的是占空比 高電平時間   Compare 最大值為100us unsigned char KeyNum,Speed; void main() {
	Timer0Init();
	Compare=5; while(1)
	{
		KeyNum=Key(); if(KeyNum==1)
		{
			Speed++; if(Speed>3){Speed=0;} if(Speed==0){Compare=0;} //compare 指的就是占空比  if(Speed==1){Compare=50;} //5%的占空比 if(Speed==2){Compare=75;} if(Speed==3){Compare=100;}
		}
		NixieTube(8,Speed);
	}
} void Timer0_Rourine() interrupt 1 //每隔100us進(jìn)來一次 {
	TL0 = 0xA4; //設(shè)置定時初值 TH0 = 0xFF; //設(shè)置定時初值 Counter++; if(Counter>=100){Counter=0;} if(Counter<Compare)
	{
		motor=1;
	} else {
		motor=0;
	}
}


使用PWM對智能小車的電機(jī)調(diào)速

直接上源程序啦
在做智能小車的時候肯定大概率會用到,如果你使用PID算法算我沒說。
留個小坑,過段時間會把做智能小車遇到問題如何解決的文章分享給大家。
集成了紅外循跡、紅外避障、紅外遙控功能
這個模塊可以直接使用

 /********************小車PWM輸出****************/ /**
  * @brief 小車PWM輸出  裝載PWM輸出,如果設(shè)置全局變量pwm_left,pwm_right分別配置左右輸出高電平時間
  * @param 無
  * @retval 無
  */ void LoadPWM(void) { if(pwm_left > PWM_HIGH_MAX)		pwm_left = PWM_HIGH_MAX; //如果左輸出寫入大于最大占空比數(shù)據(jù),則強(qiáng)制為最大占空比。 if(pwm_left < PWM_HIGH_MIN)		pwm_left = PWM_HIGH_MIN; //如果左輸出寫入小于最小占空比數(shù)據(jù),則強(qiáng)制為最小占空比。 if(pwm_right > PWM_HIGH_MAX)	pwm_right = PWM_HIGH_MAX; //如果右輸出寫入大于最大占空比數(shù)據(jù),則強(qiáng)制為最大占空比。 if(pwm_right < PWM_HIGH_MIN)	pwm_right = PWM_HIGH_MIN; //如果右輸出寫入小于最小占空比數(shù)據(jù),則強(qiáng)制為最小占空比。 if(pwm_val_left<=pwm_left)		Left_moto_pwm = 1; //裝載左PWM輸出高電平時間 else Left_moto_pwm = 0; //裝載左PWM輸出低電平時間 if(pwm_val_left>=PWM_DUTY)		pwm_val_left = 0; //如果左對比值大于等于最大占空比數(shù)據(jù),則為零 if(pwm_val_right<=pwm_right)	Right_moto_pwm = 1; //裝載右PWM輸出高電平時間 else Right_moto_pwm = 0; //裝載右PWM輸出低電平時間 if(pwm_val_right>=PWM_DUTY)		pwm_val_right = 0; //如果右對比值大于等于最大占空比數(shù)據(jù),則為零 } void Timer1_Routine() interrupt 3 {
    pwm_val_left++;
    pwm_val_right++;
    LoadPWM();//裝載PWM輸出 }

總結(jié)

說白了,PWM就是設(shè)置一個恒定的周期內(nèi),通過設(shè)置計(jì)時數(shù)和設(shè)置的比較值的大小,是在計(jì)時數(shù)比比較值小置高低電平,則要依據(jù)自己的需求來進(jìn)行設(shè)置

這個PWM起初還不知道是啥,看了江科大第一遍視頻沒懂,第二遍懂了一點(diǎn)點(diǎn),后面查看了好幾個資料,摸著摸著不知道怎么就明白了個大概。

初始接觸是應(yīng)為江科大的視頻里,一步一步跟下來

再接觸是自己制作的智能小車的速度一直慢不下來,所以使用PWM對小車的速度進(jìn)行控制

完整資料可點(diǎn)擊此處免費(fèi)領(lǐng)取!!!


the end

評論(0)