很有用!
匯編程序僅僅可以進入一號庫
C語言通過調節參數可以進入不同車庫
引腳: P2.0超聲接收
P2.1超聲發射
P1.2-P1.7步進電機
下面是自動入庫避障智能小車視頻截圖:
0.png (279.2 KB, 下載次數: 71)
下載附件
2018-5-30 00:04 上傳
0.png (295.81 KB, 下載次數: 73)
下載附件
2018-5-30 00:03 上傳
車庫圖:
0.png (12.46 KB, 下載次數: 74)
下載附件
2018-5-30 00:04 上傳
單片機源程序如下:
- /*
- * 【實驗平臺】: QX-MCS51 單片機開發板 & QX-A51智能小車
- * 【外部晶振】: 11.0592mhz
- * 【主控芯片】: STC89C52
- * 【編譯環境】: Keil μVisio4
- * ********************************【接線說明】********************************
- 以下"A_"表示智能小車底板~~~"B_"表示開發板
- *開發板供電線 :A_J5-VCC~~~B_VCC或5V0 A_J6-GND~~~B_GND (一共使用2根杜邦線)
- *電機控制線 :A_J10-P1.2至P1.7 對應接到B_P1.2至P1.7 (一共使用6根杜邦線)
- *超聲波模塊反饋線:A_J2-P20~~~B_P20 A_J2-P21~~~B_P21 (一共使用2根杜邦線)
- 使用前請先以正確方式接上超聲波模塊與1602液晶
- ******************************************************************************
- * 【程序功能】:QX-A51智能小車超聲波避障實驗
- * 【使用說明】:接線無誤后,燒寫程序打開電源開、按下S2按鍵后蜂鳴器發出提示音1秒后啟動小車
- * 【注意事項】:避免小車撞向障礙物或小車輪子堵轉,小車電壓不能低于6V
- 此程序只做參考,實際運行效果需根據不同實驗場地進行不同調試
- 使用前請插接上1602液晶。如果液晶上無顯示字符,請順時針調節液晶對比度電位器。
- 如果顯示字符過濃,請逆時針調節液晶對比度電位器
- ☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
- ☆☆☆☆☆☆☆☆☆☆ 如果沒有使用1602液晶,請把P07接到GND上,否則無法運行☆☆☆☆☆☆☆☆☆☆
- ☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
- **********************************************************************************/
- #include <reg52.h> //51頭文件
- #include <intrins.h> //包含nop等系統函數
- #include <QXA51.h>//QX-A51智能小車配置文件
- sbit DU = P2^6;//數碼管段選
- sbit RX = P2^0;//ECHO超聲波模塊回響端
- sbit TX = P2^1;//TRIG超聲波模塊觸發端
- sbit LCM_RW = P3^6; //定義LCD引腳
- sbit LCM_RS = P3^5;
- sbit LCM_E = P3^4;
- #define LCM_Data P0 //定義液晶屏數據口
- #define Busy 0x80 //用于檢測LCM狀態字中的Busy標識
- unsigned char pwm_left_val = 150;//左電機占空比值 取值范圍0-170,0最快
- unsigned char pwm_right_val = 150;//右電機占空比值取值范圍0-170 ,0最快
- unsigned char pwm_t;//周期
- unsigned int time = 0;//傳輸時間
- unsigned long S = 0;//距離
- bit flag = 0;//超出測量范圍標志位
- unsigned char code Range[] ="==Range Finder==";//LCD1602顯示格式
- unsigned char code ASCII[13] = "0123456789.-M";
- unsigned char code table[]="Distance:000.0cm";
- unsigned char code table1[]="!!! Out of range";
- unsigned char disbuff[4] = { 0,0,0,0};//距離顯示緩存
- unsigned int q=0;
- unsigned int w;
- unsigned int z=1;
- unsigned int u=0;
- unsigned int o=1;
- unsigned int v=0;
- void delay(unsigned int z)//毫秒級延時
- {
- unsigned int x,y;
- for(x = z; x > 0; x--)
- for(y = 114; y > 0 ; y--);
- }
- void Delay10us(unsigned char i) //10us延時函數 啟動超聲波模塊時使用
- {
- unsigned char j;
- do{
- j = 10;
- do{
- _nop_();
- }while(--j);
- }while(--i);
- }
-
- void cmg88()//關數共陰極碼管
- {
- DU=1;
- P0=0X00;//共陰極數碼管陽極給低電平,全部熄滅
- DU=0;
- }
- /************************************LCD1602液晶屏驅動函數************************************************/
- //*******************讀狀態*************************//
- unsigned char ReadStatusLCM(void)
- {
- LCM_Data = 0xFF;
- LCM_RS = 0;
- Delay10us(1);
- LCM_RW = 1;
- Delay10us(1);
- do{
- LCM_E = 0;
- Delay10us(1);
- LCM_E = 0;
- Delay10us(1);
- LCM_E = 1;
- Delay10us(1);
- }
- while (LCM_Data & Busy); //檢測忙信號
- return(LCM_Data);
- }
- /****************寫數據************************/
- void WriteDataLCM(unsigned char WDLCM)
- {
- ReadStatusLCM(); //檢測忙
- LCM_Data = WDLCM;
- LCM_RS = 1;
- Delay10us(1);
- LCM_RW = 0;
- Delay10us(1);
- LCM_E = 0; //若晶振速度太高可以在這后加小的延時
- Delay10us(1);
- LCM_E = 0; //延時
- Delay10us(1);
- LCM_E = 1;
- Delay10us(1);
- }
- //****************寫指令*************************//
- void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC為0時忽略忙檢測
- {
- if (BuysC) ReadStatusLCM(); //根據需要檢測忙
- LCM_Data = WCLCM;
- LCM_RS = 0;
- Delay10us(1);
- LCM_RW = 0;
- Delay10us(1);
- LCM_E = 0;
- Delay10us(1);
- LCM_E = 0;
- Delay10us(1);
- LCM_E = 1;
- Delay10us(1);
- }
- //*******************LCM初始化**********************//
- void LCMInit(void)
- {
- LCM_Data = 0;
- WriteCommandLCM(0x38,0); //三次顯示模式設置,不檢測忙信號
- delay(5);
- WriteCommandLCM(0x38,0);
- delay(5);
- WriteCommandLCM(0x38,0);
- delay(5);
- WriteCommandLCM(0x38,1); //顯示模式設置,開始要求每次檢測忙信號
- WriteCommandLCM(0x08,1); //關閉顯示
- WriteCommandLCM(0x01,1); //顯示清屏
- WriteCommandLCM(0x06,1); // 顯示光標移動設置
- WriteCommandLCM(0x0c,1); // 顯示開及光標設置
- }
- //*********************按指定位置顯示一個字符***********************//
- void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
- {
- Y &= 0x1;
- X &= 0xF; //限制X不能大于15,Y不能大于1
- if (Y) X |= 0x40; //當要顯示第二行時地址碼+0x40;
- X |= 0x80; //算出指令碼
- WriteCommandLCM(X, 1); //發命令字
- WriteDataLCM(DData); //發數據
- }
- //**********************按指定位置顯示一串字符*************************//
- void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
- {
- unsigned char ListLength;
- ListLength = 0;
- Y &= 0x1;
- X &= 0xF; //限制X不能大于15,Y不能大于1
- while (DData[ListLength]>0x19) //若到達字串尾則退出
- {
- if (X <= 0xF) //X坐標應小于0xF
- {
- DisplayOneChar(X, Y, DData[ListLength]); //顯示單個字符
- ListLength++;
- X++;
- }
- }
- }
- /***************************************************************************/
- /*定時器0中斷*/
- void timer0() interrupt 1 //T0中斷用來計數器溢出,超過測距范圍
- {
- flag=1; //中斷溢出標志
- }
- void StartModule() //啟動超聲波模塊
- {
- TX=1; //啟動一次模塊
- Delay10us(2);
- TX=0;
- }
-
- /*小車前進*/
- void forward()
- {
- left_motor_go; //左電機前進
- right_motor_go; //右電機前進
- }
- /*PWM控制使能 小車后退*/
- void backward()
- {
- left_motor_back; //左電機后退
- right_motor_back; //右電機后退
- }
- /*小車左轉*/
- /*小車停止*/
- void stop()
- {
- right_motor_stops;//右電機停止
- left_motor_stops; //左電機停止
- }
- /*PWM控制使能 小車高速左轉*/
- void left_rapidly()
- {
- left_motor_back;
- right_motor_go;
- }
- void right_rapidly()
- {
- left_motor_go;
- right_motor_back;
- }
- /*定時器1中斷輸出PWM信號*/
- void timer1() interrupt 3
- {
- pwm_t++;//周期計時加
- if(pwm_t == 255)
- pwm_t = EN1 = EN2 = 0;
- if(pwm_left_val == pwm_t)//左電機占空比
- EN1 = 1;
- if(pwm_right_val == pwm_t)//右電機占空比
- EN2 = 1;
- }
- /*判斷S2是否被按下*/
- void keyscan()
- {
- for(;;) //死循環
- {
- if(key_s2 == 0)// 實時檢測S2按鍵是否被按下
- {
- delay(5); //軟件消抖
- if(key_s2 == 0)//再檢測S2是否被按下
- {
- while(!key_s2);//松手檢測
- beep = 0; //使能有源蜂鳴器
- delay(200);//200毫秒延時
- beep = 1; //關閉有源蜂鳴器
- break; //退出FOR死循環
- }
- }
- }
- }
- /*計算超聲波所測距離并顯示*/
- void Conut(void)
- {
- time=TH0*256+TL0;
- TH0=0;
- TL0=0;
-
- S=(float)(time*1.085)*0.17; //算出來是MM
- if((S>=7000)||flag==1) //超出測量范圍
- {
- flag=0;
- DisplayListChar(0, 1, table1);//1602顯示數組table1
- }
- else
- {
- disbuff[0]=S/1000; //距離數值千位
- disbuff[1]=S%1000/100;//距離數值百位
- disbuff[2]=S%100/10;//距離數值十位
- disbuff[3]=S%10; //距離數值個位
- DisplayListChar(0, 1, table); //顯示:Distance:000.0cm
- DisplayOneChar(9, 1, ASCII[disbuff[0]]); //顯示千位
- DisplayOneChar(10, 1, ASCII[disbuff[1]]);
- DisplayOneChar(11, 1, ASCII[disbuff[2]]);
- DisplayOneChar(12, 1, ASCII[10]); //顯示 .
- DisplayOneChar(13, 1, ASCII[disbuff[3]]);
- }
- }
- /*超聲波避障*******************************************************************/
- void Avoid()
- {
- if(u==0)
- {
- if(S <180)//設置避障距離 ,單位毫米 剎車距離
- {
- //beep = 0;//使能蜂鳴器
- stop();//停車
- backward();//后退
- delay(100);//后退時間越長、距離越遠。后退是為了留出車輛轉向的空間
-
- do{
-
- right_rapidly();//高速右轉
- delay(200);//時間越長 轉向角度越大,與實際行駛環境有關
- stop();//停車
- delay(100);//時間越長 停止時間越久
- StartModule(); //啟動模塊測距,再次判斷是否
- while(!RX); //當RX(ECHO信號回響)為零時等待
- TR0=1; //開啟計數
- while(RX); //當RX為1計數并等待
- TR0=0; //關閉計數
- Conut(); //計算距離
- if(S<200) /**************************小車左掉頭180*********************************************/
- {
- left_rapidly();//高速左轉
- delay(310);//時間越長 轉向角度越大,與實際行駛環境有關
- stop();//停車
- delay(100);//時間越長 停止時間越久長
- z=z+1;
- }
- if(z>=3)
- {
- forward();//前進
- u=1;
- }
- StartModule(); //啟動模塊測距,再次判斷是否
- while(!RX); //當RX(ECHO信號回響)為零時等待
- TR0=1; //開啟計數
- while(RX); //當RX為1計數并等待
- TR0=0; //關閉計數
- Conut();
- }while(S < 140);//判斷前面障礙物距離
- beep = 1;//關閉蜂鳴器
- }
- else
- {
- forward();//前進
- }
- }
- else
- {
- if(v==0)
- {
- if(S<530)
- {
- u=1; /********************************************************************/
- stop();//停車
- backward();//后退
- delay(100);//后退時間越長、距離越遠。后退是為了留出車輛轉向的空間
- left_rapidly();//高速左轉
- delay(200);//時間越長 轉向角度越大,與實際行駛環境有關
- stop();//停車
- delay(100);//時間越長 停止時間越久
- v=1;
- }
- else
- forward();//前進
-
- }
- else
- {
- if(S < 500)//設置避障距離 ,單位毫米 剎車距離
- {
- //beep = 0;//使能蜂鳴器
- stop();//停車
- backward();//后退
- delay(100);//后退時間越長、距離越遠。后退是為了留出車輛轉向的空間
- do{
- right_rapidly();//高速右轉
- delay(200);//時間越長 轉向角度越大,與實際行駛環境有關
- stop();//停車
- delay(100);//時間越長 停止時間越久
- forward();//前進
- delay(400);
- left_rapidly();//高速左轉
- delay(310);//時間越長 轉向角度越大,與實際行駛環境有關
- stop();//停車
- delay(100);//時間越長 停止時間越久長
- o=0;
- }while(S < 140);//判斷前面障礙物距離
- }
- else
- {
- forward();//前進
- }
- }
- }
- }
- void main()
- {
-
- cmg88();//關數碼管
- LCMInit(); //LCM初始化
- delay(5);//延時片刻
- DisplayListChar(0, 0, Range);//1602第一行顯示Range數組內容
- DisplayListChar(0, 1, table);//1602第二行顯示table數組內容
- keyscan();//等待按下S2啟動小車
- delay(1000);//延時1秒
- TMOD |= 0x20;//定時器1工作模式2,8位自動重裝。用于產生PWM
- TMOD |= 0x01;//定時器0工作模塊1,16位定時模式。T0用測ECH0脈沖長度
- TH1 = 220; //
- TL1 = 220; //100HZ T1
- TH0 = 0;
- TL0 = 0;//T0,16位定時計數用于記錄ECHO高電平時間
- ET1 = 1;//允許T1中斷
- ET0 = 1;//允許T0中斷
- TR1 = 1;//啟動定時器1
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
0.png (47.92 KB, 下載次數: 81)
下載附件
2018-5-30 00:05 上傳
所有資料51hei提供下載:
智能小車.rar
(11.62 MB, 下載次數: 49)
2018-5-29 18:32 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|