/********************超声波,舵机控制*****************************
***平台:Keil U5 + STC89C52***************************************
***程序名称:超声波避障程序+舵机转向摇头+lcd1602显示超声波距离****
***日期:2022-2-13************************************************
***交流QQ:3064689599**********************************************
***晶振:11.0592MHZ*************************************************
******************************************************************/
#include "reg52.h"
#include "intrins.h"
#include "string.h"
#include "delay.h"
#define DB P2
sbit ECHO=P1^0;
sbit TRIG=P1^1;
sbit IN1=P3^5;
sbit IN2=P3^4;
sbit IN3=P3^3;
sbit IN4=P3^2;
sbit left_motor_pwm=P3^6;
sbit right_motor_pwm=P3^1;
sbit servo_pwm=P3^7;
sbit RS=P0^7;
sbit RW=P0^6;
sbit E=P0^5;
#define L_back IN1=0;IN2=1 //向后
#define L_go IN1=1;IN2=0 //向前
#define L_stop IN1=0;IN2=0 //停止
#define R_back IN3=0;IN4=1 //向后
#define R_go IN3=1;IN4=0 //向前
#define R_stop IN3=0;IN4=0 //停止
typedef unsigned char u1;
typedef unsigned int u4;
void Port_Init();
void Ultrasonic();
void Compare();
void Timer0_Init();
void information(char x,char y,char *str);
void lcd1602_init();
void check();
void write_cmd(char datashow);
void write_dizhi(char cmd);
void Distance();
void lcd1602_show();
u1 overflow=2;
u4 read,send,send1;
char buffer[4];
u1 buff[]={
0x00,0x00,0x00
};//缓冲区,0:正前方。2:左边。1:右边
/*******************************************************************************************************
主程序
*******************************************************************************************************/
void main()
{
P0=0x00;
Timer0_Init();
left_motor_pwm=1;
right_motor_pwm=1;
TRIG=0;
ECHO=0;
while(1)
{
Ultrasonic();
Distance();
lcd1602_init();
lcd1602_show();
}
}
/*******************************************************************************************************
1602液晶显示内容
*******************************************************************************************************/
void lcd1602_show()
{
buffer[0]=send/1000+'0';
buffer[1]=send/100%10+'0';
buffer[2]=send/10%10+'0';
buffer[3]='.';
buffer[4]=send%10+'0';
information(0,3,buffer);
information(1,1,"This is car");
information(0,8,"cm");
}
/*******************************************************************************************************
舵机中断0初始化
*******************************************************************************************************/
void Timer0_Init()
{
TMOD|=0x01;
EA=1;
TF0=0;
ET0=1;
TR0=1;
TH0 = 0xFE;
TL0 = 0x33;
}
/*******************************************************************************************************
若超声波的距离小于等于40cm,停止小车前进,然后转动舵机,使舵机获取左边与右边的超声波距离
若超声波距离大于40cm,小车继续前进;
*******************************************************************************************************/
void Distance()
{
if(send<=400)//小于等于40cm
{
R_stop;
L_stop;
overflow=1;
Delay100ms();
Port_Init();
Ultrasonic();
lcd1602_show();
buff[1]=send;//数组第一个缓冲区装载左边的距离
Delay20us();
overflow=3;
Delay100ms();
Port_Init();
Ultrasonic();
lcd1602_show();
buff[2]=send;//数组第二个缓冲区装载右边的距离
Delay20us();
overflow=2; //舵机回正
Delay100ms();
Compare(); //调用比较程序
}
if(send>400)//大于40cm
{
R_go;
L_go;
}
}
/*******************************************************************************************************
比较子程序,收集到的超声波值进行比较
*******************************************************************************************************/
void Compare()
{
if(buff[1]>buff[2])
{
L_back;
R_back;
Delay80ms();
R_back;
L_go;
Delay150ms();
R_go;
L_go;
}
if(buff[2]>=buff[1])
{
L_back;
R_back;
Delay80ms();
L_back;
R_go;
Delay150ms();
R_go;
L_go;
}
memset(buff,'\0',3);//将缓冲区数组中的三个数值全部清0
}
/*******************************************************************************************************
超声波初始化,配置为定时器1
*******************************************************************************************************/
void Timer1_Ultrasonic_Init()
{
TMOD|=0x10;
TR1=1;
TH1=0x00;
TL1=0x00;
}
void Port_Init()
{
TRIG=0;
ECHO=1;
Timer1_Ultrasonic_Init();
}
/*******************************************************************************************************
超声波测距离
*******************************************************************************************************/
void Ultrasonic()
{
Port_Init();
TRIG=1;
Delay20us();
TRIG=0;
while(!ECHO);
TR1=1;
TH1=0x00;
TL1=0x00;
while(ECHO);
TR1=0;
read=TH1*256+TL1;
Delay80ms();
send=read*0.172;//计算公式
lcd1602_init();
lcd1602_show();
}
/*******************************************************************************************************
写指令,控制在多少行多少列
*******************************************************************************************************/
void write_cmd(char datashow)
{
check();
RS=0;
RW=0;
E=0;
_nop_();
DB=datashow;
E=1;
_nop_();
_nop_();
E=0;
_nop_();
}
/*******************************************************************************************************
写地址控制在显示什么
*******************************************************************************************************/
void write_dizhi(char cmd)
{
check();
RS=1;
RW=0;
E=0;
_nop_();
DB=cmd;
E=1;
_nop_();
_nop_();
E=0;
_nop_();
}
/*******************************************************************************************************
检测忙信号
*******************************************************************************************************/
void check()
{
char tmp=0x80;
DB=0x80;
while(tmp&0x80)
{
RS=0;
RW=1;
E=0;
_nop_();
E=1;
_nop_();
_nop_();
tmp=DB;
_nop_();
E=0;
_nop_();
}
}
/*******************************************************************************************************
1602液晶初始化
*******************************************************************************************************/
void lcd1602_init()
{
Delay15ms();
DB=0x38;
Delay5ms();
write_cmd(0x38);
write_cmd(0x08);
write_cmd(0x01);
write_cmd(0x06);
write_cmd(0x0c);
}
/*******************************************************************************************************
选择x,y轴输出数字
*******************************************************************************************************/
void information(char x,char y,char *str)
{
switch(x)
{
case 0:
write_cmd(0x80+y);
while(*str)
{
write_dizhi(*str);
str++;
}
break;
case 1:
write_cmd(0x80+0x40+y);
while(*str)
{
write_dizhi(*str);
str++;
}
break;
}
}
/*******************************************************************************************************
中断1,控制舵机
*******************************************************************************************************/
void Timer0_Servo()interrupt 1
{
static u1 cnt;
TH0 = 0xFE;
TL0 = 0x33;
cnt++;
if(cnt==40)//溢出满40次清0
{
cnt=0;
}
if(cnt<=overflow)
{
servo_pwm=1;
}
else
servo_pwm=0;
}
超声波避障小车,1602显示超声波距离;
最新推荐文章于 2024-02-15 21:49:43 发布