所用模塊:
1.藍牙模塊
2.超聲波模塊
3.LCD1602模塊
4.L298N模塊
5.尋跡模塊
主要功能:
1.藍牙可以遙控小車
2.超聲波可以測距避障
3.小車可以尋黑線
使用邏輯:
串口初始化,上位機與藍牙模塊連接。超聲波模塊工作,將數據發送到單片機,單片機計算出距離,通過LCD1602顯示距離。上位機選擇工作模式進入超聲波避障還是紅外尋跡模式。超聲波模式:通過比對單片機計算出的數據,小于既定距離,則進行避障。紅外尋跡模式:左紅外對管沒有檢測到黑線則右轉,右邊同理。
模塊:
1.藍牙模塊藍牙模塊采用的是串口通信,使用的I/O口是TXD和RXD,采用的是串口方式1。使用藍牙模塊首先進行串口初始化,然后在上位機中發送信息。單片機讀取SBUF緩沖寄存器中的數據進行控制。2.超聲波模塊基本工作原理:(HC-SR04)
1.采用I/O口trig觸發測距,給至少10us的高電平信號2.模塊自動發送8個40kHZ的方波,自動檢測是否有信號返回。
3.有信號返回,通過I/O口echo輸出一個高電平,高電平持續的時間就是超聲波從發射到返回的時間4.測試距離=(高電平時間*聲速)/2
5.計算距離采用的是外部中斷03.LCD1602
1602可顯示2行,每行16個字符,不能顯示漢字。對1602的操作有兩種,寫命令和寫數據。寫命令是對光標有無,光標閃爍的控制。寫數據則是對顯示什么內容進行控制。
4.L298N模塊
L298N的實質是兩個單刀雙擲的開關,通過控制開關閉合,控制電機正轉反轉停止。通過單片機的I/O控制就能使小車前進后退左轉右轉。5.尋跡模塊
黑線的檢測原理是紅外發射管發射光線到路面,紅外光遇到白底則被反射,接收管接收到反射光,輸出低電平;當紅外光遇到黑線時則被吸收,接收管沒有接收到反射光,輸出高電平。通過高低電平控制小車運動。 代碼
單片機源程序如下:
#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";
//延時函數
void delayms(uchar x)
{
uint i,j;
for(i=0;i<x;i++)
{
for(j=0;j<110;j++);
}
}
//延時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;
}
//寫數據
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(計算距離)
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);
}
}
}
//返回數據,表示串口正常運行
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);
}
|