51單片機-藍牙遙控智能小車-紅外循跡(代碼+硬件連接)

  前幾天弄了個基於51芯片的藍牙紅外小車,因爲是新手也沒有人教,網上的資料也不夠齊全(很多都是跳過新手那一步,比如說接線),做的過程中遇到很多問題,做的比較艱難,因而寫一篇記錄整個過程的文章,希望能夠給新手提供一些幫助同時也做一個總結。

組裝完成的小車,比較醜。

 

 

1.材料(可以在淘寶上買得到)

  1.4wd小車一臺,包含馬達,兩個底盤,和螺絲等(要自己組裝,)

  

 

 

 

  2.  L298N電機驅動模塊兩個,用來控制馬達的轉速,方向,停止與否。

    

 

  3. 51單片機最小系統板一個和STC89C52RC芯片一個

 

   

 

  4.HC-05藍牙模塊一個(藍牙遙控)和usb轉TTL轉接模塊一個(用於設置和調試藍牙模塊)

  

  

 

 

   5. 4路紅外循跡模塊(黑白循跡)

  

 

 

   6. 18650電池四個和18650電池盒和杜邦線若干。

我用的材料就是以上這些。

2. 組裝

  第二個難點就是組裝,難在如何接線。

  1.先把四個馬達和車輪裝在一起,組裝成一個小車框架。

  2.L298N電機的接線

  

 

 

   一個L298N有四個輸出口(out1,out2,out3,out4)接馬達,每兩個輸出口控制一個馬達,因此可以控制兩個馬達,12v接口接電源正極,5v接口是給最小系統板供電,所以5v接系統板5v口。四個IO輸入口(in1,in2,in3,in4)通過芯片控制輸出口。兩個使能端口(A,B),只有高電平時電機纔有有效,低電平時電機不轉

轉。因爲有兩個電機只有一個供電源所以兩個電機要並聯連接在一起。

下面是電機的控制表,當使能端位低電平(0)時電機處於停止狀態,當輸出口爲(00或11)時處於制動狀態,阻止電機轉動。

 

 

   L298N無效,無法驅動馬達的原因(1.電壓不夠,起碼要7v以上。2.使能端沒有處於高電平狀態 。3.L298N或馬達壞了).

  3.藍牙的接線

  藍牙接在最小系統板,藍牙的TXD(發送口)口接系統板的RXD(接收口)口,RXD口接TXD口也就是交叉連接,發送口對接收口。

  在接在系統板之前,要對藍牙進行一些設置(名稱,密碼,波特率),這時就要用到usb轉TTL模塊。

  

  接在電腦上,打開串口調試助手(軟件在後面的鏈接),進入AT模式 (進入方法,藍牙模塊上面有個按鈕,在usb口插入電腦前,長按不放,插入電腦即可,如果看到藍牙模塊上的燈在快速閃爍,說明已經進入AT模式,慢閃是工作模式)。

  

  

 

 

  比如設置名字hello,密碼123456

  AT+NAME=hello

  AT+PSWD=123456

  發送以上兩個命令即可,之後打開手機的藍牙試試能不能連接成功。

  4.紅外的接線

  紅外模塊的接線很簡單,按照引腳上的說明,一一對應接在系統板上即可。

3.代碼

  代碼大概分成三個模塊,藍牙遙控模塊,紅外循跡模塊,PWM調速模塊。

  1.藍牙那部分還需要在手機下載一個藍牙助手用來控制小車,我的是在小米商城下載的,有廣告,並不是很好用,但又找不到好的,只好將就一下。如果會android編程的,可以自己寫一個。下面那些命令都是自定義,你可以根據需要,自己定製,寫代碼的時候對應就行。
  

 

 

  代碼如下,已寫好註釋。

  

  1 #include<reg52.h>
  2 #include<intrins.h>
  3 
  4 sbit LEA=P1^0;//左邊輪的使能端A
  5 sbit LEB=P1^1;//左邊輪的使能端B
  6 //左前輪
  7 sbit LIN1=P1^2;//
  8 sbit LIN2=P1^3;//
  9 //左後輪
 10 sbit LIN3=P1^4;
 11 sbit LIN4=P1^5;
 12 
 13 sbit REA=P3^2;//右邊輪使能端A
 14 sbit REB=P3^3;//右邊輪使能端B
 15 //右前輪
 16 sbit RIN1=P3^4;
 17 sbit RIN2=P3^5;
 18 //右後輪
 19 sbit RIN3=P3^6;
 20 sbit RIN4=P3^7;
 21 
 22 //方向控制
 23 void delay(int time);//延時函數
 24 void forward();//前進
 25 void back();//後退
 26 void stop();//停止
 27 void start();//啓動
 28 void turnLeft();//左轉
 29 void turnRight();//右轉
 30 
 31 
 32 //藍牙模塊
 33 //定時器1用作串口發生器,用於與藍牙通信
 34 void time1Init();//定時器1的初始化
 35 void processMsg();//處理藍牙接收到的信息
 36 
 37 //紅外模塊
 38 //從右到左
 39 //in1是最右邊的紅外燈
 40 sbit in1=P2^0;
 41 sbit in2=P2^1;
 42 sbit in3=P2^2;
 43 sbit in4=P2^3;
 44 int isTrace=0;//是否開啓循跡功能
 45 void trace();//紅外循跡
 46 
 47 
 48 //PWM調速
 49 //通過控制使能端高低電平輸出的時間從而控制速度
 50 int count=0; //用於計數
 51 int pwm=20;      //表示啓動的時間,20表示啓動20ms
 52 void time0Init();//定時器0的初始化.
 53                 //用於控制高低電平的時間
 54                 //定時器比較準確
 55 void go();//啓動 使能端爲高電平 1
 56 void pause();//停止    使能端爲低電平 0
 57 void time0Fun();//定時器0的中斷函數
 58 
 59 
 60 
 61 
 62 int main()
 63 {
 64 
 65     EA=1;//打開總中斷
 66     time1Init();//定時器1初始化
 67     time0Init();//定時器0初始化
 68     start();//使車的方向一開始向前
 69 
 70     while(1)
 71     {
 72         if(isTrace)
 73             trace();
 74         if(count>=100) //100ms一個週期
 75             count=0;
 76         if(count<pwm) //pwm表示啓動的時間         
 77                       //pwm越大 速度越快
 78             go();
 79         else if(count>=pwm)
 80             pause();
 81     }
 82     return 0;
 83 }
 84 
 85 
 86 void delay(int time)//延時函數
 87 {
 88     int i;
 89     for(i=0;i<time;i++)
 90     {
 91         _nop_();//在晶振12M下
 92                 //一個nop函數延時1us
 93     }
 94 }
 95 void forward()//前進
 96 {
 97     //前進,所有輪正轉
 98     LIN1=0;
 99     LIN2=1;
100 
101     LIN3=0;
102     LIN4=1;
103 
104     RIN1=0;
105     RIN2=1;
106 
107     RIN3=0;
108     RIN4=1;
109 }
110 void back()//後退
111 {
112       //前進,所有輪反轉
113     LIN1=1;
114     LIN2=0;
115 
116     LIN3=1;
117     LIN4=0;
118 
119     RIN1=1;
120     RIN2=0;
121 
122     RIN3=1;
123     RIN4=0;
124 }
125 void turnLeft()//左轉
126 {
127     //左轉  左邊的輪正轉,右邊輪反轉
128     LIN1=0;
129     LIN2=1;
130 
131     LIN3=0;
132     LIN4=1;
133 
134     RIN1=1;
135     RIN2=0;
136 
137     RIN3=1;
138     RIN4=0;
139     delay(5000);//延時5ms 控制轉彎的角度
140 
141 }
142 void turnRight()//右轉
143 {
144     //右轉,左邊輪反轉,右邊輪正轉
145     LIN1=1;
146     LIN2=0;
147 
148     LIN3=1;
149     LIN4=0;    
150 
151     RIN1=1;
152     RIN2=0;
153 
154     RIN3=1;
155     RIN4=0;
156     delay(5000);//延時5ms 控制轉彎的角度
157 }
158 void stop()//停止
159 {
160     //停止,全部高電平或低電平
161     LIN1=0;
162     LIN2=0;
163 
164     LIN3=0;
165     LIN4=0;    
166 
167     RIN1=0;
168     RIN2=0;
169 
170     RIN3=0;
171     RIN4=0;
172 }
173 
174 void start()
175 {
176     forward();//一開始,前進方向
177 }
178 
179 //定時器1用作串口發生器,用於與藍牙通信
180 void time1Init()//定時器1的初始化
181 {
182     TMOD=0x20;//定時器1,工作模式2,8位自動重裝模式
183     TH1=0xfd;//9600波特率,要與藍牙的一致
184     TL1=0xfd;
185     //串口通信方式1
186     SM0=0;
187     SM1=1;
188     PCON=0x00;//波特率不加倍
189     SCON=0x50;//工作方式一
190     REN=1;//允許接收
191     ES=1;//開啓串口中斷
192     TR1=1;//啓動定時1
193 
194 }
195 void processMsg() interrupt 4 //中斷4
196 //處理藍牙接收到的信息
197 {
198     char ch;
199     //等待接收完畢
200     while(!RI)//當RI爲0時沒有接收完畢
201         ;        //爲1時接收完畢
202     //信息存存在sbuf中
203     ch=SBUF;//獲取接收的信息
204     switch(ch)
205     {
206         case 'f':  //前進
207             forward();
208             break;
209         case 'b': //後退
210             back();
211             break;
212         case 'l': //左轉
213             turnLeft();
214             break;
215         case 'r': //右轉
216             turnRight();
217             break;
218         case 's':    //停止
219             stop();
220             break;
221         case 'o':
222             start();
223             break;//啓動
224         case 't': //開啓循跡功能
225             isTrace=1;
226             break;
227         case '1':  //一檔
228             pwm=20;
229             break;
230         case '2':  //二檔
231             pwm=60;
232             break;
233         case '3': //三檔
234             pwm=100;
235             break;
236         default:
237             break;
238     }
239 }
240 void trace()//紅外循跡
241 {
242     //當紅外遇到黑線時吸收紅外光,輸出高電平
243     //遇到白線時反射紅外,輸出低電平
244 
245     int dir=0;//0表示直走
246                 //1 代表左轉
247                 //2 代表右轉
248     //0 0 0 0
249     if(in1==0&&in2==0&&in3==0&&in4==0)
250         dir=0;
251     //1 0 0 0
252     else if (in1==1&&in2==0&&in3==0&&in4==0)
253         dir=2;
254     //1 1 0 0
255     else if (in1==1&&in2==1&&in3==0&&in4==0)
256         dir=2;
257     //1 1 1 0
258     else if (in1==1&&in2==1&&in3==1&&in4==0)
259         dir=0;
260     //1 1 1 1
261     else if (in1==1&&in2==1&&in3==1&&in4==1)
262         dir=0;
263 
264     //0 1 0 0
265     else if (in1==0&&in2==1&&in3==0&&in4==0)
266         dir=2;
267     //0 1 1 0
268     else if (in1==0&&in2==1&&in3==1&&in4==0)
269         dir=0;
270     //0 1 1 1
271     else if (in1==0&&in2==1&&in3==1&&in4==1)
272         dir=1;
273     //0 0 1 0
274     else if (in1==0&&in2==0&&in3==1&&in4==0)
275         dir=1;
276     //0 0 1 1
277     else if (in1==0&&in2==0&&in3==1&&in4==1)
278         dir=1;
279 
280     //1 0 1 0
281     else if (in1==1&&in2==0&&in3==1&&in4==0)
282         dir=1;
283     //1 1 1 0
284     else if (in1==1&&in2==1&&in3==1&&in4==0)
285         dir=2;
286     //1 0 1 1
287     else if (in1==1&&in2==0&&in3==1&&in4==1)
288         dir=0;
289     //1 0 0 1
290     else if (in1==1&&in2==0&&in3==0&&in4==1)
291         dir=0;
292     //0 0 0 1
293     else if (in1==0&&in2==0&&in3==0&&in4==1)
294         dir=1;
295     //1 1 0 1
296     else if (in1==1&&in2==1&&in3==0&&in4==1)
297         dir=0;
298     switch(dir)
299     {
300         case 0:
301             forward();
302             break;
303         case 1:
304             turnLeft();
305             break;
306         case 2:
307             turnRight();
308             break;
309     }
310 }
311 
312 void time0Init()//定時器0的初始化.
313                 //用於控制高低電平的時間
314                 //定時器比較準確
315 {
316     TMOD|=0x01;//工作方式一
317                 //用或運算是爲了不改變
318                 //定時器1對應位的值。
319     TH0=0xfc;
320     TL0=0x66;  //定時1ms
321 
322     ET0=1;//開啓定時器0的中斷
323     TR0=1;//啓動定時器0
324 }
325 
326 void go()//啓動 使能端爲高電平 1
327 {
328     LEA=1;
329     LEB=1;
330     REA=1;
331     REB=1;
332 }
333 
334 void pause()//停止    使能端爲低電平 0
335 {
336     LEA=0;
337     LEB=0;
338     REA=0;
339     REB=0;
340 }
341 
342 void time0Fun() interrupt 1
343 {
344     TH0=0xfc;
345     TL0=0x66;
346     //1ms 中斷一次,count加一
347     count++;
348 }

 

下面是要用到的軟件,包括 串口調試助手,代碼編寫工具KEil, 燒錄軟件TCICP_V6.87

鏈接:https://pan.baidu.com/s/1aeZs1fKelqX3JohfM3qlGQ
提取碼:5151

有任何問題可以找我

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章