keil+proteus 智能巡检测温机器人

实现机器人避障,测温。

并显示障碍物距离和温度。

超温停止机器人,障碍物距离过小则避障。


Proteus仿真图如下:

在这里插入图片描述物料清单:
在这里插入图片描述


Keil代码如下:

#include <reg52.h>
#include <stdio.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int

//  I/o声明及位、变量定义
sbit L293D_IN1=P0^0; 
sbit L293D_IN2=P0^1;
sbit L293D_IN3=P0^2;
sbit L293D_IN4=P0^3;
sbit L293D_EN1=P0^4;
sbit L293D_EN2=P0^5;
sbit key= P3^3; 
sbit RX = P1^2; 
sbit TX = P1^3;
sbit DQ=P1^5;
sbit led=P1^0;
sbit led1=P3^4;
sbit rs=P3^0;
sbit rw=P3^1;
sbit e=P3^2;
sbit beep=P0^7;
bit  flag =0;//量程溢出标志位
int temp=0,temp1=0;//temp为温度的整数部分,temp1为温度的小数部分
uint  time=0;//用于存放定时器的时间值
unsigned long S=0;//用于存放距离的值


//函数声明
void delay(uint t);
uchar init_ds18b20();
void write_byte(uchar dat);
uchar read_byte(void);
char read_tem(void);
void write_com(uchar com);
void write_dat(uchar dat);
void lcdinit();
void Count(void);//距离计算函数
void Delay1ms(uint i);
void Delay10us(uchar i);
void Forward();//前进
void Stop(void);//刹车
void Turn_Retreat();//后
void Turn_left();//左转
void Turn_right();//右转
void Timer_Count(void);
void StartModule();//启动模块


//主函数
void main(void)
{
		uint a,bflag=0;
		uchar n;
		lcdinit();//屏幕初始化
		TMOD=0x01;//定时器初始化
		TX=0;
    EA=1;
    TH0=0;
    TL0=0;          
    ET0=1;
		n=init_ds18b20();	//18b20初始化
		if(n)
		led=0;		
		temp=read_tem();

		while(temp==85) 
		{
			temp=read_tem();
		}
		temp=0;
	
		
		while(1)
		{

			if(key==0)
			{
				led=1;	
				led1=1;				
				RX=1;
				StartModule();
				for(a=951;a>0;a--)
				{
					if(RX==1)
					{
					 Timer_Count();
					}
				}
											
			temp=read_tem();      //温度值的整数部分,显示温度										
			if(temp>=0)		//正温度+0
			{
				write_com(0x80+8);
				write_dat(0xdf);    //显示温度符号
				write_dat(0x43);     //显示温度符号
				Delay1ms(5);
				write_com(0x80+3);
				write_dat(' '); 
				write_dat(0x30+temp/10);     //显示温度的十位
				write_dat(0x30+temp%10);     //显示温度的个位
				write_com(0x80+6);
				write_dat('.');
				write_dat(0x30+temp1);      //显示小数部分
			}
			else	 		//负温度
			{
				write_com(0x80+8);
				write_dat(0xdf);    //显示温度符号
				write_dat(0x43);     //显示温度符号
				Delay1ms(5);
				write_com(0x80+3);
				write_dat('-'); 
				write_dat(0x30+(-1*temp)/10);     //显示温度的十位
				write_dat(0x30+(-1*temp)%10);     //显示温度的个位
				write_com(0x80+6);
				write_dat('.');
				write_dat(0x30+temp1);      //显示小数部分
			}
				
			//距离显示		
			write_com(0x40+0x80+8); //显示超声波距离
			write_dat(0x43);    //显示距离符号
			write_dat(0x4D);    //显示距离符号
			Delay1ms(5);
			write_com(0x40+0x80+4);
			write_dat(0x30+S/100);     //显示距离的百位
			write_dat(0x30+S/10%10);     //显示距离的十位
			write_dat(0x30+S%10);   //显示距离的个位
						
			if(temp<50 && temp>-10)
			{
				Forward();				//前进条件

				if(S<=20)		//设定超声波采集模块距离范围
				{
					beep=0;
					Stop();
					Delay1ms(2000);		  //停
					Turn_Retreat();		  
					Delay1ms(2000);		  //退
					Stop();
					Delay1ms(1500);		  //停
					Turn_left();		   
					Delay1ms(2000);		  //转 避障
					beep=1;
				}
			}				
			if(temp>=50||temp<=-10)    //判断采集到的温度是否达到上限或下限
			{
				bflag=1;
				if(bflag> 0)
				{
					beep=0;
					Delay1ms(500);
					beep=1;
					bflag=0;
				}
				Stop();
			}
		}		
		
		else
		{
			stop();
			led=0;
			led1=0;
			write_com(0x01);//设置位置			
		}
	}
}
		
void Delay1ms(uint i) //延时ms
{ 
	uchar j,k; 
	do{ 
			j = 10; 
		do{ 
				k = 50; 
			do{ 
					_nop_(); 
				}while(--k);     
      }while(--j); 
    }while(--i); 
} 

void Delay10us(uchar i) //延时10us
{ 
   uchar j; 
   do{ 
		  j = 10; 
		do{ 
				_nop_(); 
      }while(--j); 
		 }while(--i); 
}

void delay(uint t)//延时
{
     while(t--);
}


void Forward()//前进
{
  L293D_IN1=1; 
  L293D_IN2=0;
  L293D_IN3=1;
  L293D_IN4=0;
}

void Stop()//刹车
{
  L293D_IN1=0; 
  L293D_IN2=0;
  L293D_IN3=0;
  L293D_IN4=0;
}

void Turn_Retreat()//后退
{
 L293D_IN1=0; 
 L293D_IN2=1;
 L293D_IN3=0;
 L293D_IN4=1;
}

void Turn_left()//左转
{
 L293D_IN1=0; 
 L293D_IN2=1;
 L293D_IN3=1;
 L293D_IN4=0;
}

/*
void Turn_right()//右转
{
 L293D_IN1=1; 
 L293D_IN2=0;
 L293D_IN3=0;
 L293D_IN4=1;
}
*/




void Conut(void)//计算距离
{
  time=TH0*256+TL0;
  TH0=0;
  TL0=0;
  S=time*1.7/100+1;

}

void zd0() interrupt 1//T0中断用来计数器溢出,超过测距范围
{
		flag=1;
		RX=0;
}

void Timer_Count(void)
{
	 TR0=1;			//开启计数
 	 while(RX);		//当RX为1计数并等待
 	 TR0=0;			//关闭计数
 	 Conut();		//计算
}

 void  StartModule()//启动模块
 {
 	TX=1;//启动一次模块
 	Delay10us(2);
 	TX=0;
 }

 


uchar init_ds18b20()//ds18b20复位初始化
{
     uchar n=0;
     DQ=1;//DQ复位
     delay(8);//稍做延时
     DQ=0;//单片机将DQ拉低
     delay(80);//600us  精确延时,大于480us
     DQ=1;//拉高总线
     delay(8);//15us~60us
     n=DQ;//初始化成功n=0,失败n=1
     delay(4);
     return 0;
}
void write_byte(uchar dat)//写字节
{
    uchar i;
    for(i=0;i<8;i++)
    {
       DQ=0;//给脉冲信号
       DQ=dat&0x01;
       delay(4);
       DQ=1;
       dat=dat>>1;
    }
    delay(4);
}
uchar read_byte(void)//读字节
{
   uchar i,value;
   for(i=0;i<8;i++)
   {
       DQ=0;
       value>>=1;
		  
       DQ=1; //
       if(DQ)
         value|=0x80;
       delay(4);
   }
   return value;
}
char read_tem(void)//读取ds18b20当前温度
{
    uchar a=0,b=0,temp0=0;   
    init_ds18b20();
    write_byte(0xcc);//跳过读序号列号的操作
    write_byte(0x44);//启动温度转换
    delay(500);
 
    init_ds18b20();
    write_byte(0xcc);
    write_byte(0xbe);//读取温度寄存器等(共可读9个寄存器)  前两个寄存器是温度

    a=read_byte();//读取温度值低位
    b=read_byte();//读取温度值高值
  
    b<<=4;
		temp1=(a&0x0f);
		temp1=temp1*0.625+0.5;
    a>>=4;
    temp0=b|a;
    return temp0;
}

void write_com(uchar com)   //LCD的写指令
{
   rs=0;
   rw=0;
   P2=com;
   e=1;
   Delay1ms(5);
   e=0;
}
void write_dat(uchar dat)  //LCD的写数据
{
   rs=1;
   rw=0;
   P2=dat;
   e=1;
   Delay1ms(5);
   e=0;
}
void lcdinit()  //1602初始化最大化最小化调整界面

{
   Delay1ms(15);
   write_com(0x38);//屏幕初始化
   Delay1ms(6);
   write_com(0x38);
   Delay1ms(6);
   write_com(0x38);
   write_com(0x38);
   write_com(0x0c); 
   write_com(0x06);//当读或写一个字符是指针后一位
   write_com(0x01);//设置位置
  
}

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Cyril-zxy

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

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

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

打赏作者

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

抵扣说明:

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

余额充值