標題:
51單片機三路超聲波避障與仿真(proteus8.6)源碼
[打印本頁]
作者:
慕斯雪芙
時間:
2020-4-13 13:12
標題:
51單片機三路超聲波避障與仿真(proteus8.6)源碼
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei.png
(36.06 KB, 下載次數(shù): 38)
下載附件
2020-4-13 14:29 上傳
51hei.png
(18.82 KB, 下載次數(shù): 45)
下載附件
2020-4-13 14:29 上傳
單片機源程序如下:
//==============================================================================================================
//程序標題:基于51單片機的三路超聲波小車避障程序================================================================
//定稿日期:------- ====================================================================================
//作 者:------- ====================================================================================
//更新日期:2020.3.8 23:51====================================================================================
//最后撰寫人:張 虎 ==========================================================================================
//功 能:三方向避障 ====================================================================================
#include<reg51.h> //頭文件(定義了一些特殊的寄存器)
#include<intrins.h>
#include<stdio.h>
//==========3個超聲波模塊定義================================
sbit Trig_left = P1^0; //左邊超聲波模塊端口定義
sbit Echo_left = P1^1;
sbit Trig_mid = P1^2; //中間超聲波模塊端口定義
sbit Echo_mid = P1^3;
sbit Trig_right = P1^4; //右邊超聲波模塊端口定義
sbit Echo_right = P1^5;
//=========1個298模塊2路電機控制端設置=============================
sbit N1 = P2^0; //L298N模塊控制馬達,通過N1N2和N3N4端口輸出1、0控制電機正轉,反轉,急停
sbit N2 = P2^1;
sbit N3 = P2^2;
sbit N4 = P2^3;
sbit EN1 = P2^4; //L298N模塊使能端(利用PWM計數(shù)控制使能端可實現(xiàn)電機轉速控制,在本程序中沒有體現(xiàn))
sbit EN2 = P2^5; //
//============定義全局變量=======================================
unsigned int time=0; //定義time為十進制無負號整型變量(0-65535),用于讀取距離
unsigned long S_left=0; //左邊障礙距離
unsigned long S_mid=0; //中間障礙距離
unsigned long S_right=0; //右邊障礙距離
//==============================================================================================
void delayms(unsigned int ms) //延時子函數(shù)
{
unsigned char i;
while(ms--)
{
for(i=0;i<113;i++);
}
}
void delay_15us(void) //15us精準延時,誤差 0us,用于啟動超聲波模塊
{
unsigned char a;
for(a=6;a>0;a--);
}
//=========轉向函數(shù)=============================================================================
void turn_down() //向前
{
N1=1;
N2=0;
N3=1;
N4=0;
delayms(500);
}
void turn_back() //向后
{
N1=0;
N2=1;
N3=0;
N4=1;
delayms(500);
}
void turn_left() //向左
{
N1=0;
N2=1;
N3=1;
N4=0;
delayms(500);
}
void turn_right() //向右
{
N1=1;
N2=0;
N3=0;
N4=1;
delayms(500);
}
//==========啟動超聲波模塊完成測距并讀取數(shù)值(cm)===================================================================
void measure_left(void) //左模塊
{
EA=0; //關閉總中斷
Trig_left=1; //啟動一次模塊,信號時間應大于10us
delay_15us();
Trig_left=0;
TH1=0; //定時器1高8位寄存器清零
TL1=0; //定時器1低8位寄存器清零
TF1=0; //定時器1溢出位清零
while(Echo_left==0); //當echo為零時等待變?yōu)楦唠娖?等待波發(fā)出(Echo_lift為模塊發(fā)送超聲波到接受的時間標志,硬件自行設置,單片機檢測即可)
TR1=1; //波發(fā)出后立即啟動定時器1,讓TH1,TL1寄存器數(shù)值每1us增加1。
EA=1; //總中斷允許,開啟計數(shù)
while(Echo_left); // 等待反波Echo初始狀態(tài)為0,模塊聲波發(fā)送后(聲波離開發(fā)射器),硬件將其置位,當檢測到有聲波返回時(聲波由障礙物反射回到模塊,接收器已經(jīng)接受到聲波信號)硬件將其復位。Echo置位的時間的一半即超聲波從模塊發(fā)到障礙物止的時間S=Vt,將此時間乘以340m/s即可得到障礙物距離。
time=TH1*256+TL1; //取值讀取測距數(shù)值到time 將16進制數(shù)轉化為十進制
TH1=0; //清零
TL1=0;
TR1=0; //關閉定時器1
S_left=(time*17)/1000; //轉換,定時器每1us增加1,將數(shù)值取值到time中,若初始值為0也就是從定時器開到定時器關一共經(jīng)過了time個us,微秒除1000是毫秒再除以1000是秒再乘以聲速340m/s,理論上也就是:S=Vt=【(((time÷2)÷1000 000)×340)×100】厘米,即:[(time*170)÷10000]算出來是CM(厘米)
delayms(5); //延時
}
//========右邊距離測量(同左邊一樣)============================================================================================
void measure_right(void) //左模塊
{
EA=0;
Trig_right=1; //啟動一次模塊,信號時間應大于10us
delay_15us();
Trig_right=0;
TH1=0; //定時器1清零
TL1=0; //定時器1清零
TF1=0; //溢出位清零
while(Echo_right==0); //當RX為零時等待變?yōu)楦唠娖剑‥cho_lift為模塊發(fā)送超聲波到接受的時間標志,硬件自行設置,單片機檢測即可)
TR1=1; //啟動定時器1
EA=1; //開啟計數(shù) Echo初始狀態(tài)為0,模塊聲波發(fā)送后(聲波離開發(fā)射器),硬件將其置位,當檢測到有聲波返回時(聲波由障礙物反射回到模塊,接收器已經(jīng)接受到聲波信號)硬件將其復位。Echo置位的時間的一半即超聲波從模塊發(fā)到障礙物止的時間S=Vt,將此時間乘以340m/s即可得到障礙物距離。
while(Echo_right); //當RX為1計數(shù)并等待
time=TH1*256+TL1; //取值讀取測距數(shù)值 將16進制數(shù)轉化為十進制
TH1=0; //清零
TL1=0;
TR1=0; //關閉定時器1
S_right=(time*17)/1000; //轉換,定時器每1us增加1,將數(shù)值取值到time中,若初始值為0也就是從定時器開到定時器關一共經(jīng)過了time個us,微秒除1000是毫秒再除以1000是秒再乘以聲速340m/s,理論上也就是:S=Vt=【(((time÷2)÷1000 000)×340)×100】厘米,即:[(time*170)÷10000]算出來是CM(厘米)
delayms(5); //延時
}
//==============中間距離測量(同左邊,右邊一樣)============================================================================
void measure_mid(void) //左模塊
{
EA=0;
Trig_mid=1; //啟動一次模塊,信號時間應大于10us
delay_15us();
Trig_mid=0;
TH1=0; //定時器1清零
TL1=0; //定時器1清零
TF1=0; //溢出位清零
while(Echo_mid==0); //當RX為零時等待變?yōu)楦唠娖剑‥cho_lift為模塊發(fā)送超聲波到接受的時間標志,硬件自行設置,單片機檢測即可)
TR1=1; //啟動定時器1
EA=1; //開啟計數(shù) Echo初始狀態(tài)為0,模塊聲波發(fā)送后(聲波離開發(fā)射器),硬件將其置位,當檢測到有聲波返回時(聲波由障礙物反射回到模塊,接收器已經(jīng)接受到聲波信號)硬件將其復位。Echo置位的時間的一半即超聲波從模塊發(fā)到障礙物止的時間S=Vt,將此時間乘以340m/s即可得到障礙物距離。
while(Echo_mid); //當RX為1計數(shù)并等待
time=TH1*256+TL1; //取值讀取測距數(shù)值 將16進制數(shù)轉化為十進制
TH1=0; //清零
TL1=0;
TR1=0; //關閉定時器1
S_mid=(time*17)/1000; //轉換,定時器每1us增加1,將數(shù)值取值到time中,若初始值為0也就是從定時器開到定時器關一共經(jīng)過了time個us,微秒除1000是毫秒再除以1000是秒再乘以聲速340m/s,理論上也就是:S=Vt=【(((time÷2)÷1000 000)×340)×100】厘米,即:[(time*170)÷10000]算出來是CM(厘米)
delayms(5); //延時
}
//=========退出死區(qū)函數(shù),===================================================================================================
void move_left_or_right(void) //設置左右轉向函數(shù)
{
turn_back(); //退出死區(qū)
N1=N2=N3=N4=1; //前方有障礙物,立刻"急停"然后判斷距離
delayms(100); //減速延遲
measure_left(); //重新檢測左前方距離
measure_right(); //重新檢測右前方距離
if(S_left>=S_right) //左右距離不相等時,通過返回數(shù)據(jù)進行避障
{
turn_left(); //左轉
}
else //右邊距離大于左邊
{
turn_right(); //右轉
}
}
//=======判斷障礙物,選擇行進路線===================================================================================================
void move(void) //設置前進函數(shù)
{
if(S_mid>4) //判斷中間障礙物的距離,單位CM(不一定準)
// 如果中間障礙物距離均大于4
{
turn_down(); //前進
}
else //判斷中間距離小于等于4,
{
N1=N2=N3=N4=1; //前方有障礙物,立刻"急停"然后判斷距離
delayms(100); //減速延時
if(S_mid<=4&&S_right>4) //判斷右側距離是否大于4
{
turn_right(); //右轉
}
else //即判斷中間及其右側距離均小于等于4
{
if(S_mid<=4&&S_right<=4&&S_left>4) //判斷左側距離
// 如果左側障礙物距離大于4
{
turn_left(); //左轉
}
else //否則 即三側均小于等于4,進入死區(qū)模式
{
move_left_or_right(); //退出死區(qū)函數(shù)
}
}
}
}
//==========單片機定時器和計數(shù)器設置===============================================
void set(void)
{ delayms(10); //上電延時
TMOD=0x10; //設T0為方式1,GATE=0;
TH1=0x00; //T1高8位重裝初值
TL1=0x00; //T1低8位重裝初值
EA=1; //開啟總中斷(全局中斷)
Trig_left =0;
Trig_mid =0;
Trig_right =0;
EN1=1; //298模塊使能
EN2=1;
N1=N2=N3=N4=0; //開機先制動
}
//============主函數(shù)===============================================================
void main(void)
{
set(); //單片機及其298初始化
while(1)
{
measure_left(); //檢測前方距離
measure_mid(); //檢測前方距離
measure_right(); //檢測前方距離
move(); //根據(jù)檢測結果,避障前進
delayms(10); //延時
}
}
//==========================================================
//TH1=[(65536-設定中斷時間)/(機器運行周期數(shù)/晶振頻率MHZ)]/256; 高8位中斷初值計算公式
//TL1=[(65536-設定中斷時間)/(機器運行周期數(shù)/晶振頻率MHZ)]%256; 低8位中斷初值計算公式
復制代碼
所有資料51hei提供下載:
三路超聲波避障(OK).7z
(89.53 KB, 下載次數(shù): 73)
2020-4-13 14:31 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
作者:
songxia8013
時間:
2020-4-13 22:08
這狀態(tài)是怎么變換的呢?怎么一直在空擋呢?
作者:
YANJS
時間:
2020-11-24 11:06
這個怎么改變狀態(tài)
作者:
8556633
時間:
2020-11-24 16:54
先點贊 再慢慢看
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1