標題:
51單片機尋跡避障小車源程序
[打印本頁]
作者:
augestclown
時間:
2018-7-16 08:21
標題:
51單片機尋跡避障小車源程序
單片機避障程序源程序如下:
/*
* 作者:趙新
* 功能:實現(xiàn)小車躲避障礙,通過檢測三個方向的距離,選擇最大距離轉(zhuǎn)彎
* 日期:3/14
* 說明:STC89c52RC,12MHz
* 注意:1000ms和100ms待測,完成后刪除此行
*—————————————————管腳說明——————————————
* Trig = P1^0
* Echo = P3^2
* PWM_OUT = P0^4
*————————————————————————————————————————
*/
#include "stc89c5x.h"
#include "intrins.h"
#include "Motor.h"
#define X 20 //最短距離參考值 約為12厘米 受溫度影響,會存在10%左右的誤差
sbit Trig = P1^0;//發(fā)送端
sbit Echo = P3^2;//接收端 若用外部中斷0,則此引腳必須是P3.2
sbit PWM_OUT = P0^4;//PWM信號輸出端
u8 counts = 0; //設置初值
u8 PWM =6; //設置初值,任意值也可不設
u8 Flag_Angle = 1; //0 左45度 1 右45度 在函數(shù)Scan()中調(diào)用
u8 Distance_Middle;
u8 Distance_Temp[2];//0 左45度 1 右45度
void Delay20us();
void Delay100ms();
void Delay1000ms(); //@12.000MHz 用于等待
u8 Compute(u8 th,u8 tl);
void Scan_Around(); //掃描左右
void Scan_Middle(); //掃描正中前進方向距離
void main()
{
TMOD = 0x11;//設置T0,T1 T0用于電平檢測 T1用于產(chǎn)生舵機需要的PWM信號
TH0 = 0x00; //轉(zhuǎn)載初值
TL0 = 0x00;
ET0 = 1; //打開定時器中斷
TF0 = 0; //失能定時器中斷標志,也可忽略此語句
TR0 = 0; //開始時T0關(guān)閉
TH1 = 0xff; //產(chǎn)生時基100us定時,用于組成舵機各個角度的信號
TL1 = 0x9c;
ET1 = 1;
TF0 = 0; //可忽略此語句,51復位此位為0
TR1 = 0; //暫時關(guān)閉T1
EX0 = 1; //開外部中斷
IT0 = 1; //下降沿觸發(fā)中斷
EA = 1; //全局中斷開
Trig = 0; //觸發(fā)端拉低
Echo = 0;
while(1)
{
//Scan_Around();
Scan_Middle();
if(Distance_Middle<=X)
{
Stop();
Scan_Around();
if((Distance_Temp[0]>Distance_Temp[1])&&Distance_Temp[0]>=X)
{
Turn_Left(0);
Delay100ms();
//Delay100ms();
}else
if((Distance_Temp[0]<Distance_Temp[1])&&Distance_Temp[1]>=X)
{
Turn_Right(0);
Delay100ms();
//Delay100ms();
}else
if((Distance_Temp[0]==Distance_Temp[1])&&Distance_Temp[0]>=X)
{
Turn_Right(0);
Delay100ms();
//Delay100ms();
}else
{
Back();
Delay100ms();
Delay100ms();
Delay100ms();
Delay100ms();
Delay100ms();
Turn_Right(0);
Delay100ms();
//Delay100ms();
}
}else
{
Go();
}
}
}
void Timer1(void) interrupt 3 //PWM產(chǎn)生
{
TH1 = 0xff;
TL1 = 0x9c;
if(counts<PWM)
{
PWM_OUT = 1;
}
else
{
PWM_OUT = 0;
if(counts==200)
{
counts = 0;
}
}
++counts;
}
void Timer0(void) interrupt 1 //T0溢出中斷函數(shù),一般來說T0溢出是不可能發(fā)生的,原因是傳感器最大探測距離為4m左右,所用時間不會超過65536us
{
}
void INT0_Test(void) interrupt 0 //下降沿到來之后,進入外部中斷函數(shù),停止T0計數(shù),計算并發(fā)送計算值到計算機
{
TR0 = 0;
switch(Flag_Angle)
{
case 0:Distance_Temp[0]=Compute(TH0,TL0);TH0 = TL0 = 0x00;break; //左
case 1:Distance_Temp[1]=Compute(TH0,TL0);TH0 = TL0 = 0x00;break; //右
default:break;
}
//為了下一次準確計數(shù),必須清空
}
void Scan_Around() //掃描左右
{
Flag_Angle = 0;
PWM = 17;//左轉(zhuǎn)45度
TR1 = 1;
Delay1000ms();
TR1 = 0;
Trig = 1; //觸發(fā)一次檢測
Delay20us();
Trig = 0;
while(!Echo); //如果沒有檢測到返回信號,等
TR0 = 1; //檢測到高電平,開T0計數(shù),一直計到下降沿到來
Delay100ms();
Flag_Angle = 1;
PWM = 8; //右轉(zhuǎn)45度
TR1 = 1;
Delay1000ms();
TR1 = 0;
Trig = 1; //觸發(fā)一次檢測
Delay20us();
Trig = 0;
while(!Echo); //如果沒有檢測到返回信號,等
TR0 = 1; //檢測到高電平,開T0計數(shù),一直計到下降沿到來
Delay100ms();
PWM = 12; //測完回到正中
TR1 = 1;
Delay1000ms();
TR1 = 0;
}
void Scan_Middle() //掃描正中前進方向距離
{
//Stop();
Flag_Angle = 3;
Trig = 1; //觸發(fā)一次檢測
Delay20us();
Trig = 0;
while(!Echo); //如果沒有檢測到返回信號,等
TR0 = 1; //檢測到高電平,開T0計數(shù),一直計到下降沿到來
Delay100ms();
Distance_Middle = Compute(TH0,TL0);
TH0 = TL0 = 0x00;
//Go();
}
u8 Compute(u8 th,u8 tl)
{
u16 times = 0x0000;
times = th;
times = times<<8;
times |= tl;
return (times/58);
}
void Delay20us() //@12.000MHz 用于產(chǎn)生超聲波觸發(fā)信號
{
unsigned char i;
_nop_();
i = 7;
while (--i);
}
void Delay100ms() //@12.000MHz
{
unsigned char i, j;
i = 195;
j = 138;
do
{
while (--j);
} while (--i);
}
void Delay1000ms() //@12.000MHz 用于等待
{
unsigned char i, j, k;
_nop_();
i = 8;
j = 154;
k = 122;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
復制代碼
/*
* 作者:趙新
* 功能:尋跡小車主函數(shù)
* 日期:2015/3/10 進行PWM的修改
* 說明:編譯器會有一些警告,主要是定義的一些函數(shù)在這里沒有用到,可以注釋掉或者寫成條件編譯 2015/9/15
*/
#include "reg51.h"
#include "intrins.h"
#include "Motor.h"
#define LEFT 0 //左側(cè)觸到黑線
#define RIGHT 1 //右側(cè)觸到黑線
#define ALL 2 //同時觸到黑線
#define NONE 3 //正常運行沒有觸到黑線
u8 i = 0;
sbit Left = P0^4;
sbit Right = P0^5;
sbit PWM_LEFT = P1^0;
sbit PWM_RIGHT = P1^1;
u8 JudgeMode();
//void Delay100ms();
void main()
{
TMOD = 0x01;//定時器0,2工作在模式1 50ms時基
TH0 = 0xfc;
TL0 = 0x18;
ET0 = 1;
EA = 1;
TR0 = 1;
Go();
while(1)
{
switch(JudgeMode())
{
case 0: {
Turn_Left(0);
//Delay100ms();
}break;
case 1: {
Turn_Right(0);
//Delay100ms();
}break;
case 2: Stop(); break;
case 3: Go(); break;
}
}
}
u8 JudgeMode()//用于判斷小車此時狀態(tài)
{
if(Left==0&&Right==1)//左側(cè)觸到黑線,應向左轉(zhuǎn)
return LEFT;
if(Left==1&&Right==0)//右側(cè)觸到黑線,應向右轉(zhuǎn)
return RIGHT;
if(Left==0&Right==0)//同時觸到黑線,應進一步判斷是‘T’型還是‘十’型路況
return ALL;
if(Left==1&&Right==1)//沒有觸到黑線,可能正常運行,可能小車跑偏了
return NONE;
}
void Time0(void) interrupt 1 //初定周期200ms,空占比50%
{
TH0 = 0xfc;
TL0 = 0x18;
++i;
if(i>=2) //>=2 1/4空占比
{
PWM_LEFT = 1;
……………………
…………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
循跡避障小車.rar
(58.16 KB, 下載次數(shù): 121)
2018-7-16 08:20 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
作者:
1115204179
時間:
2018-10-27 23:06
你好,能私發(fā)程序給我嗎,我沒黑幣下載不了,
1115204179@qq.com
謝謝
作者:
1115204179
時間:
2018-10-27 23:17
樓主可以私發(fā)給我嗎,
1115204179@qq.com
謝謝
作者:
啊哈?
時間:
2018-12-20 20:53
可以私法嗎?
1173459156@qq.com
作者:
51dian
時間:
2019-3-17 14:27
非常不錯,感謝分享!
作者:
990722
時間:
2021-6-29 09:12
能用嗎正常使用嗎?
作者:
碎碎平安
時間:
2021-11-12 00:08
請問可以正常使用嗎?
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1