在上一期的項目:最簡單DIY的51藍牙遙控小車設計方案 訪問地址是:https://www.cirmall.com/circuit/20328 源碼里面有舵機控制部分的程序,但是被我注釋掉了,由于舵機控制還是比較復雜,這里還是開一個專題來講解51單片機如何控制180度舵機。接線請看詳細的程序注解吧,學過51肯定啃得動的。
#include "reg52.h"
unsigned char count; //0.5ms 次數(shù)標識
sbit pwm =P2^7 ; //PWM信號輸出,接舵機的數(shù)據(jù)線
sbit jia =P3^7; //角度增加按鈕
sbit jan =P3^6; //角度減少按鈕,低電平觸發(fā)
unsigned char jd; //角度標識 1.0ms->45 1.5->90 2.0->135 2.5->180
void delay(unsigned char i)//普通延時函數(shù)
{
unsigned char j,k;
for(j=i;j>0;j--)
for(k=125;k>0;k--);
}
void Time0_Init() //定時器0初始化
{
TMOD = 0x01; //定時器0工作在方式1,16位增計數(shù)定時器,16位全是1,最大計數(shù)值是65535,就溢出了
IE = 0x82;//EA=1全局中斷允許,ET0=1,定時器中斷允許
TH0 = 0xfe;//(65536-N)/256=0xef=254推出N=512,N就是需要計數(shù)的個數(shù),機器周期是1.09us,所以
//512*1.09us=0.5ms,這時候舵機為0度,1ms是45度,2.5ms是180度,其他的類推
TL0 = 0x33; //11.0592MHz晶振的單片機,導致0.5ms計數(shù)器溢出一次,產(chǎn)生定時器中斷
TR0=1; //開啟定時器
}
void Time0_Int() interrupt 1 //定時器0中斷服務程序
{
TH0 = 0xfe; //重新裝載初值
TL0 = 0x33;
if(count< jd) //判斷計數(shù)次數(shù)是否小于標識
pwm=1; //輸出高電平PWM
else
pwm=0; //低電平PWM
count=(count+1); //計數(shù)次數(shù)繼續(xù)增加
count=count%40; //計數(shù)次數(shù)必須小于40,因為0.5ms*40=20ms,這是舵機PWM的固定周期
}
void keyscan() //按鍵掃描
{
if(jia==0) //按下增加按鈕
{
delay(10); //消除抖動
if(jia==0) //按下增加按鈕
{
jd++; //標識增加,一共有5檔,jd=1對應0度,jd=2對應0,45度,jd=3對應90,4對應135,5對應180度
count=0; //計數(shù)清0,當count加到2的時候,溢出兩次,時間是0.5*2=1ms,對應舵機轉(zhuǎn)到45度
if(jd==6)
jd=5; //標識清0
while(jia==0); //等待按鍵釋放
}
}
if(jan==0) //按下減少按鈕
{
delay(10);
if(jan==0)
{
jd--; //同理
count=0;
if(jd==0)
jd=1; //復位
while(jan==0);
}
}
}
void main()
{
jd=1;
count=0;
Time0_Init();
while(1)
{
keyscan(); //死循環(huán),按鍵檢測
}
}
程序分析結(jié)束了。
總結(jié):
根據(jù)工作原理,舵機的具體控制方法就是需要一個20ms左右的時基脈沖,
該脈沖的高電平部分一般為0.5ms~2.5ms范圍內(nèi)的角度控制脈沖部分。
脈沖寬度從0.5ms~2.5ms,相對應舵盤的位置為0~180度,呈線性變化。
***************一般舵機脈沖寬度20ms,高電平寬度與角度對應關(guān)系***********
0.5ms————0度;
1.0ms————45度;
1.5ms————90度;
2.0ms————135度;
2.5ms————180度;
根據(jù)上面的原理,我們知道單片機只要產(chǎn)生20ms的脈沖信號,通過改變高電平時間從0.5ms到2.5ms變化,就能使舵機轉(zhuǎn)動到對應的角度
最后程序的功能就是按下增加按鍵,舵機從0度到180 ,按5次;舵機從180到0也需要按5次減少按鈕。
下個項目將會推出用手機app和串口藍牙模塊控制舵機翻轉(zhuǎn)。