前幾天弄了個基於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
有任何問題可以找我