51單片機(jī)-PWM調(diào)速(直流電機(jī),智能小車的電機(jī)調(diào)速)
大家好,今天給大家介紹51單片機(jī)-PWM調(diào)速,下方附有本文涉及的全部資料和源代碼的獲取方式,可進(jìn)群免費(fèi)領(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)取!!!
- 贊