|
所用模塊:
1.藍(lán)牙模塊
2.超聲波模塊
3.LCD1602模塊
4.L298N模塊
5.尋跡模塊
主要功能:
1.藍(lán)牙可以遙控小車
2.超聲波可以測距避障
3.小車可以尋黑線
使用邏輯:
串口初始化,上位機(jī)與藍(lán)牙模塊連接。超聲波模塊工作,將數(shù)據(jù)發(fā)送到單片機(jī),單片機(jī)計(jì)算出距離,通過LCD1602顯示距離。上位機(jī)選擇工作模式進(jìn)入超聲波避障還是紅外尋跡模式。超聲波模式:通過比對單片機(jī)計(jì)算出的數(shù)據(jù),小于既定距離,則進(jìn)行避障。紅外尋跡模式:左紅外對管沒有檢測到黑線則右轉(zhuǎn),右邊同理。
模塊:
1.藍(lán)牙模塊藍(lán)牙模塊采用的是串口通信,使用的I/O口是TXD和RXD,采用的是串口方式1。使用藍(lán)牙模塊首先進(jìn)行串口初始化,然后在上位機(jī)中發(fā)送信息。單片機(jī)讀取SBUF緩沖寄存器中的數(shù)據(jù)進(jìn)行控制。2.超聲波模塊基本工作原理:(HC-SR04)
1.采用I/O口trig觸發(fā)測距,給至少10us的高電平信號2.模塊自動發(fā)送8個(gè)40kHZ的方波,自動檢測是否有信號返回。
3.有信號返回,通過I/O口echo輸出一個(gè)高電平,高電平持續(xù)的時(shí)間就是超聲波從發(fā)射到返回的時(shí)間4.測試距離=(高電平時(shí)間*聲速)/2
5.計(jì)算距離采用的是外部中斷03.LCD1602
1602可顯示2行,每行16個(gè)字符,不能顯示漢字。對1602的操作有兩種,寫命令和寫數(shù)據(jù)。寫命令是對光標(biāo)有無,光標(biāo)閃爍的控制。寫數(shù)據(jù)則是對顯示什么內(nèi)容進(jìn)行控制。
4.L298N模塊
L298N的實(shí)質(zhì)是兩個(gè)單刀雙擲的開關(guān),通過控制開關(guān)閉合,控制電機(jī)正轉(zhuǎn)反轉(zhuǎn)停止。通過單片機(jī)的I/O控制就能使小車前進(jìn)后退左轉(zhuǎn)右轉(zhuǎn)。5.尋跡模塊
黑線的檢測原理是紅外發(fā)射管發(fā)射光線到路面,紅外光遇到白底則被反射,接收管接收到反射光,輸出低電平;當(dāng)紅外光遇到黑線時(shí)則被吸收,接收管沒有接收到反射光,輸出高電平。通過高低電平控制小車運(yùn)動。 代碼
單片機(jī)源程序如下:
#include<reg52.h>
#include<intrins.h>
#define L_go IN1=0;IN2=1
#define L_back IN1=1;IN2=0
#define L_stop IN1=0;IN2=0
#define R_go IN3=0;IN4=1
#define R_back IN3=1;IN4=0
#define R_stop IN3=0;IN4=0
typedef unsigned char uchar;
typedef unsigned int uint;
sbit Echo=P3^2;
sbit Trig=P3^3;
sbit IN1 =P3^4;
sbit IN2 =P3^5;
sbit IN3 =P3^6;
sbit IN4 =P3^7;
sbit lcdrs=P1^0;
sbit lcdrw=P1^1;
sbit lcden=P2^5;
sbit dula=P2^6;
sbit wela=P2^7;
sbit STA7=P0^7;
float dis;
float jl;
uchar flag;
char code table[]="distance:";
char code table1[]="cm";
//延時(shí)函數(shù)
void delayms(uchar x)
{
uint i,j;
for(i=0;i<x;i++)
{
for(j=0;j<110;j++);
}
}
//延時(shí)10us
void nops()
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
//超聲波工作
void distance()
{
Trig=0;
nops();
Trig=1;
nops();
nops();
Trig=0;
TR0=1;
EX0=1;
delayms(1);
if(flag==1)
{
flag=0;
}
}
void wait()
{
P0=0xff;
do
{
lcdrs=0;
lcdrw=1;
lcden=0;
lcden=1;
}while(STA7==1);
lcden=0;
}
//寫命令
void write_com(uchar com)
{
wait();
lcdrs=0;
P0=com;
lcdrw=0;
delayms(5);
lcden=1;
delayms(5);
lcden=0;
}
//寫數(shù)據(jù)
void write_date(uchar date)
{
wait();
lcdrs=1;
P0=date;
lcdrw=0;
delayms(5);
lcden=1;
delayms(5);
lcden=0;
}
//LCD1602初始化
void init()
{
wait();
dula=0;
wela=0;
lcden=0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
TMOD=0x21;
TH0=0;
TL0=0;
IT0=1;
EA=1;
}
//顯示距離
void display(float dis)
{
uint bai,shi,ge,p1,p2;
bai=dis/100;
shi=(dis-bai*100)/10;
ge=dis-bai*100-shi*10;
p1=(dis*10)-bai*1000-shi*100-ge*10;
p2=(dis*100)-bai*10000-shi*1000-ge*100-p1*10;
write_date(0x30+bai);
write_date(0x30+shi);
write_date(0x30+ge);
write_date('.');
write_date(0x30+p1);
write_date(0x30+p2);
}
//超聲波測距顯示
void csbcj()
{
uchar i=0;
init();
write_com(0x80);
while(table[ i]!='\0')
{
write_date(table[ i]);
i++;
delayms(5);
}
i=0;
write_com(0x80+0x40+6);
while(table1[ i]!='\0')
{
write_date(table1[ i]);
i++;
delayms(5);
}
while(1)
{
distance();
write_com(0x80+0x40);
display(dis);
delayms(60);
}
}
//外部中斷0(計(jì)算距離)
void ex() interrupt 0
{
TR0=0;
dis=(TH0*256+TL0)*1.7/100;
jl=dis;
flag=1;
TH0=0;
TL0=0;
}
//串口中斷
void Com_Int(void) interrupt 4
{
uchar i;
uchar receive_data;
EA = 0;
if(RI == 1)
{
RI = 0;
receive_data = SBUF;
if(receive_data == 'A')
{
L_go;
R_go;
}
if(receive_data == 'B')
{
R_back;
L_back;
}
if(receive_data == 'C')
{
L_stop;
R_stop;
}
if(receive_data == 'D')
{
L_back;
R_go;
}
if(receive_data == 'E')
{
L_go;
R_back;
}
if(receive_data=='F')
{
if(dis>15)
{
L_go;
R_go;
}
else
{
R_back;
L_back;
delayms(5000);
L_back;
R_go;
delayms(5000);
}
}
}
//返回?cái)?shù)據(jù),表示串口正常運(yùn)行
for(i=0; i<36; i++)
{
SBUF = '1';
while(!TI);
TI=0;
delayms(1);
}
EA = 1;
}
//初始化串口
void UsartConfiguration()
{
SCON=0X50;
TMOD=0X21;
PCON=0X00;
TH1=0XFd;
TL1=0XFd;
TR1=1;
ES = 1;
EA = 1;
}
void main()
{
//PS=1;
//PX0=0;
UsartConfiguration();
csbcj();
while(1);
}
|
評分
-
查看全部評分
|