超声波避障小车,1602显示超声波距离;

/********************超声波,舵机控制*****************************
***平台: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;
}

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

懿761

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值