所用模块:
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);
}
|