這個是我用了20天用泡沫板、黑膠帶、杜邦線、3D打印的夾子、12V鋰電池、木棍、l298n驅動電路模塊、51單片機做成的一輛比較粗糙的小車;
這裏所說的只會一招便是控制單片機的IO口。
一開始呢,是因爲學校舉辦了一個機械結構設計大賽,目的是做一輛智能小車做規定動作,走完規定的路線。而我手上現成的有51單片機的一個完整的開發板,也學過一點點單片機的知識,就打算開始弄起來。一開始也是一臉懵逼,不知道幹什麼。也許我該感謝百度這個平臺,讓我能夠查閱了大量的資料,才發現智能小車大致由一下四個模塊構成:
1.電池供電模塊(就是如何在小車上給單片機供電)
2.電機驅動模塊(就是如何給電機足夠的動力,讓它能驅動)
3.單片機控制模塊(就是代碼實現控制)
4.機械結構部分(就是輪胎設計,車體設計)
一、電池供電模塊
一般來說呢,對於一些要求不高的智能小車,用幾個幾V的乾電池就足以驅動。但是考慮到我的單片機本身的重量,用3個鋰電池能夠大大減少由於電池帶來的重量,這樣小車也能夠走得非常的輕巧。
二、電機驅動模塊
對於電機驅動我所採用的是l298n,說起來這個還是弄了我半天的一個東西,所以我建議初學者如果在淘寶上購買的話,最好買那些有提供技術客服的。(當我第一次拿到一個馬達的時候,我甚至不清楚如何驅動一個馬達,然後發現在馬達兩邊的耳朵接入正負極就能驅動發現就很牛逼,我就是這樣的基礎,最後還能夠完成小車的製作,可見堅持的重要性)對於一個基礎電路模塊,我覺得一個通用的辦法就是學會看他的數據手冊,再者便是百度它的使用方法,在明白它的使用方法之後便是使用單片機進行試用的時刻。對於我的小車,我所使用的單片機是市場上現成的一塊開發板,所以在連接的時候就出現了一種錯誤,便是讓它與單片機的IO口連接的時候,連接到了已經設置了驅動模塊的IO口,而沒有直接連接單片機兩旁的IO口,導致信號錯誤,這是我找了很久的錯誤,差點讓我放棄。
說到l298n百度上的使用方法已經很多了。當你連接好之後呢,就是面臨實現代碼的問題了,如下是我的代碼:
void left()
{
motorL1=0;
motorL2=1;
motorR1=1;
motorR2=0;
} //小車左轉;
void right()
{
motorR1=0;
motorR2=1;
motorL1=1;
motorL2=0;
} //小車右轉;
void GO()
{
motorR1=0;
motorR2=1;
motorL1=0;
motorL2=1;
} //小車直走;
void stop()
{
motorR1=0;
motorR2=0;
motorL1=0;
motorL2=0;
} //小車停止;
void back()
{
motorR1=1;
motorR2=0;
motorL1=1;
motorL2=0;
}
這是我把左輪,右輪分別連接到l298n上的IN1,IN2,IN3,IN4上所寫的代碼;
對於l298n的PWM方波輸入,我所採用的是單片機的定時器發生中斷的方式來實現;
void init0()
{
TMOD=0x11;
TH0=(65536-459)/256;
TL0=(65536-459)%256; //計0.5ms;
EA=1;
ET0=1;
ET1=1;
TR0=1;
} //定時器0初始化;
void timep1()interrupt 1
{
time1++;
TH0=(65536-459)/256;
TL0=(65536-459)%256;
if(time1==8)
{
PWML=~PWML;
PWMR=~PWMR;
}
if(time1==32)
{
time1=0;
PWML=~PWML;
PWMR=~PWMR; //輸出佔空比爲8/32,取反;
}
}
就是一個在一秒內一會輸出高電平,一會輸出低電平的方波。實測用這個頻率以及佔空比來實現對小車的控制還是比較穩的,不過就是稍微會慢了一些,可以根據自己的需要進性調整。
三、單片機控制模塊
這裏我是用的是我的51單片機開發板上所配備的HS0038來實現對小車的控制,HS0038可以通過按鍵然後紅外的方式與單片機進行通信,然後控制單片機的IO口。單片機通過開啓外部中斷的方式不斷的讀取由HS0038輸入的值(此代碼並不是我自己寫的)
uchar IRCOM[7];
uint jianzhi,a1,a2;//紅外遙控鍵值變量
void init2()
{
EA=1; //全局中斷開
EX1=1; //外部中斷1開
IT1=1; //邊沿觸發,爲0則爲低電平觸發
}
void delay0(unsigned char x) //x*0.14MS
{
unsigned char i;
while(x--)
{
for (i = 0; i<13; i++) {}
}
}
void ISR1_Key() interrupt 2
{
unsigned char j,k,N=0;
EX1 = 0;
delay0(15);
if (int1==1)
{ EX1 =1;
return;
}
//確認IR信號出現
while (!int1) //等IR變爲高電平,跳過9ms的前導低電平信號。
{delay0(1);}
for (j=0;j<4;j++) //收集四組數據
{
for (k=0;k<8;k++) //每組數據有8位
{
while (int1) //等 IR 變爲低電平,跳過4.5ms的前導高電平信號。
{delay0(1);}
while (!int1) //等 IR 變爲高電平
{delay0(1);}
while (int1) //計算IR高電平時長
{
delay0(1);
N++;
if (N>=30)
{ EX1=1;
return;} //0.14ms計數過長自動離開。
} //高電平計數完畢
IRCOM[j]=IRCOM[j] >> 1; //數據最高位補“0”
if (N>=8) {IRCOM[j] = IRCOM[j] | 0x80;} //數據最高位補“1”
N=0;
}//end for k
}//end for j
if (IRCOM[2]!=~IRCOM[3])
{ EX1=1;
return; }
IRCOM[5]=IRCOM[2] & 0x0F; //取鍵碼的低四位
IRCOM[6]=IRCOM[2] >> 4; //右移4次,高四位變爲低四位
if(IRCOM[5]>9)
{ IRCOM[5]=IRCOM[5]+0x37;}
else
IRCOM[5]=IRCOM[5]+0x30;
if(IRCOM[6]>9)
{ IRCOM[6]=IRCOM[6]+0x37;}
else
IRCOM[6]=IRCOM[6]+0x30;
a1= IRCOM[6];
a2= IRCOM[5];
EX1 = 1;
jianzhi=(a1*256)+a2;
}
當能夠讀取紅外遙控器的鍵值之後就可以通過如下的代碼實現單片機IO口的控制:
void yaokong()
{
if(jianzhi==12600)
GO();
else if(jianzhi==13633)
left();
else if(jianzhi==12611)
stop();
else if(jianzhi==13618)
back();
else if(jianzhi==12344)
right();
}
我覺得坐這輛小車關鍵在於代碼模塊,至於實現遙控,只需要一塊遙控模塊以及遙控的代碼便可以實現。
在這裏還有一點那就是開發板的單片機IO口必須接在CPU兩邊,不然會發現信號錯亂。
四、機械結構部分
我們這裏採用的是三個輪子的方式,用泡沫板做它的輪子與車體,這些都是比較容易實現的,如果對於材料沒有要求的話,還是儘量在淘寶上找那些底盤直接使用控制起來纔是最方便的。
附加:
1、在我們做的小車中呢,還有一個抓取裝置,抓取裝置是通過兩個舵機來實現的,用3D打印的手臂貼緊在舵機上。舵機可以根據你所寫的代碼轉固定的角度,至於連接在百度上很多,以下是代碼模塊:
void init1()
{
TH1=(65536-459)/256;
TL1=(65536-459)%256; //計50ms;
} //定時器1初始化;
void timep2()interrupt 3
{
time2++;
TH1=(65536-459)/256;
TL1=(65536-459)%256;
if(time2==a)
{
duoji1=~duoji1;
duoji2=~duoji2;
}
if(time2==40)
{
time2=0;
duoji1=~duoji1;
duoji2=~duoji2;
}
}
我使用了單片機的另外一個定時器來作爲舵機的PWM方波輸出;這裏的抓取裝置也是通過上面的遙控方式改變a值來實現開與關。
2、紅外巡線模塊:
在一開始有想過要做這個模塊,不過因爲小車是要去比賽的,巡線速度要快,比起遙控小車要慢許多,所以就改掉了這個方案。
注意:
1、無論做什麼事情,都必須小心,電路的連接不是兒戲,隨時都可能燒壞電路。
2、做電控要有耐心,排除一個一個不可能的因素,就可以得到答案。
3、上述單片機還是可以大大簡化的,沒有開發板的可以考慮使用單個單個模塊。