STC51控制的超声波HY-SRF05测距、红外接收小车代码

 /*******************************************************************************
* 程序  名         : 超声波HY-SRF05测距、红外接收控制小车
* 程序功能         : 测量距离、红外控制、自动巡航
* 备注             : 130直流电机、L298N电机驱动、HY-SRF05超声波测距模块、红外收发模块
* 作者             : Silencht 
*******************************************************************************/
// --头文件声明 --//
#include<reg51.h>
#include <intrins.h>

//--声明超声波引脚对应--//
sbit TRIG=P3^7;    //TRIG是触发信号
sbit ECHO=P3^6;   //ECHO是测距的持续信号

//--声明电机驱动引脚对应--//
sbit ZUO1 =P2^6;      //左转控制口1
sbit ZUO2 =P2^7; //左转控制口2
sbit YOU1 =P1^3;   //右转控制口1
sbit YOU2 =P1^4; //右转控制口2

//--声明蜂鸣器驱动引脚对应--//
sbit BEE =P2^1; //蜂鸣器控制引脚
//--定义全局变量--//
unsigned long S=0;      //距离初始化
unsigned int time=0; //超声波往返时间寄存变量
unsigned char receiveData;      //用来保存红外模块串口接收的数据
unsigned int flag=0;//运动模式转动方向标志

//--声明全局函数--//
void Delay10ms(unsigned int c); //延时10ms函数
void system_Ini();//定时器系统、中断初始化函数
void Conut(void);//距离计算函数
void movemode();//选择运动模式
void StartModule();    //采集信号初始化函数   
void UsartConfiguration();      //红外串口函数
void redreceive();    //红外遥控信息接收函数
void qianjin();//控制电机前进
void houtui();//控制电机后退
void houtui3s();    //控制电机后退3s
void lefturn1s();   //控制电机左转1s
void zuozhuan();//控制电机左转
void righturn1s();   //控制电机右转1s
void youzhuan();//控制电机右转
void pause();     //控制电机停止
void Bee();//蜂鸣器响一声 
 
/*******************************************************************************
* 函 数 名        : main
* 函数功能        : 主函数
*******************************************************************************/
void main(void)
{
UsartConfiguration();       //串口函数初始化
system_Ini();     //定时器系统、中断初始化
pause();  //小车停止
BEE=0;
while(1)   //进入红外控制死循环
{
redreceive();                   //接收红外信息
if ( receiveData == 24)    //按键2按下
{
Bee();//蜂鸣器响一声
while( receiveData != 28 ) //当按键5没有按下时,一直前进,下同
{
qianjin(); //小车前进
   redreceive(); //前进的同时,持续进行是否有红外按键5——停止信号输入的扫描,下同
}
pause();             //停止
Bee();//蜂鸣器响一声
}
else if( receiveData == 82)      //按键8按下
{
Bee();//蜂鸣器响一声
while( receiveData != 28 )
{
houtui();        //后退
redreceive();
}
pause();          //停止
       Bee();//蜂鸣器响一声
}
else if( receiveData == 8)       //按键4按下
{
    Bee();//蜂鸣器响一声
lefturn1s();         //左转1s
receiveData=0;   //红外接收变量清零
}
else if( receiveData == 90)      //按键6
{
Bee();//蜂鸣器响一声
righturn1s();    //右转1s
receiveData=0;   //红外接收变量清零
}
else if (receiveData == 9)       //按键EQ,自动巡航,遇见障碍物过近,自动左转
{
Bee();//蜂鸣器响一声
while( receiveData != 28 )
{
StartModule();      //启动采集信号初始化模块,即进行一次数据采集,TRIG每隔一段时间输出一次高电平触发信号
while(!ECHO);       //当ECHO为0时等待信号到来,TRIG发出一段大于10us的高电平后,超声波模块会进行发送8段40khz周期电平
//然后检测回波信号,回波信号脉宽与ECHO信号高电平持续时间成正比,ECHO持续时间*声速再除以2,
//结果即为距离。此时为等待RX产生高电平,一旦产生后,后面定时器即开始计数,
TR0=1;              //打开定时器0,开启计数  
while(ECHO);        //当ECHO为1时计数进入循环等待,ECHO高电平不结束,计时不停止,一旦结束
TR0=0;              //关闭定时器0,停止计数 
Conut(); //通过计数来的时间在距离计算函数中计算距离S
movemode();     //选择运动模式
}
pause();      //停止
}
else continue;     //未接收到红外信息时,继续从头循环等待
}
}
/*******************************************************************************
* 函 数 名         : Delay10ms
* 函数功能        : 延时函数,延时10ms
*******************************************************************************/
void Delay10ms(unsigned int c)        //误差 0us
{
    unsigned char a, b;
    for (;c>0;c--)
{
for (b=38;b>0;b--)
{
for (a=130;a>0;a--);
}       
}       
}
/*******************************************************************************
* 函 数 名        :system_Ini
* 函数功能        :定时器T0系统/中断初始化
/******************************************************************************/
void system_Ini(void)
{  
TH0=0;
TL0=0;
    TMOD=0x21;         //设T0为方式1            
    ET0=1;             //允许T0中断  
    EA=1;              //开启总中断   
} 
/*******************************************************************************
* 函 数 名         : Conut
* 函数功能   : 测量超声波距离S
*******************************************************************************/
 void Conut(void)  
{  
     time=TH0*256+TL0; //时间等于高位信息+低位信息的和,读取测量得到的时间,单位是微秒,是超声波发送出去到反射回来的时间.
     TH0=0;     
     TL0=0;         //计算完成后,初始化定时器高低位信息 
S=time*0.017; //计算超声波距离
} 
/*******************************************************************************
* 函 数 名         : movemode
* 函数功能   : 选择运动模式
*******************************************************************************/
void movemode()
{
if(S<8)     //如果距离小于8CM,则
{
if(flag>=0&&flag<=2)
{
lefturn1s();//左转1s
flag=flag+1;
} 
else if(flag==3||flag==7)
{
houtui3s();//后退3s
flag=flag+1;
}
else if(flag>=4&&flag<=6)
{
righturn1s();   //右转1s
flag=flag+1;
}
else //标志位清零
flag=0;

}
else        //如果距离大于8CM,则
{
redreceive();       //接收红外信息
qianjin();    //小车持续前进
}
}


/***********************************************************
* 函 数 名         :StartModule()
* 函数功能   :超声波采集信号初始化函数
/**********************************************************/ 
 void  StartModule()    //启动模块  
{  
      TRIG = 1;         //启动一次模块  
      _nop_();   
      _nop_();   
      _nop_();   
      _nop_();   
      _nop_();   
      _nop_();   
      _nop_();   
      _nop_();   
      _nop_();   
      _nop_();   
      _nop_();   
      _nop_();   
      _nop_();   
      _nop_();   
      _nop_();   
      _nop_();   
      _nop_();  
      _nop_();   
      _nop_();   
      _nop_();   
      _nop_();  
      TRIG = 0;  
}  
/*******************************************************************************
* 函 数 名         :UsartConfiguration()
* 函数功能   :设置红外接收串口
*******************************************************************************/
void UsartConfiguration()
{
SCON=0X50;//设置为工作方式1
TMOD=0X20;//设置计数器工作方式2
PCON=0X80;//波特率加倍
TH1=0XF3;    //计数器初始值设置,注意波特率是4800
TL1=0XF3;
TR1=1;//打开计数器
}
/*******************************************************************************
* 函 数 名         : redreceive()
* 函数功能         : 红外接收
*******************************************************************************/
void redreceive()
{
if(RI == 1)    //查看红外是否接收到数据,如果接受到
{
receiveData = SBUF;//读取数据,存至变量receiveData
RI = 0;//清除串口接收标志位
}
}
/*******************************************************************************
* 函 数 名         : qianjin
* 函数功能         : 控制电机前进
*******************************************************************************/
void qianjin()
{
ZUO1=1;ZUO2=0;
YOU1=1;YOU2=0; //前进
}
/*******************************************************************************
* 函 数 名         : houtui
* 函数功能         : 控制电机后退
*******************************************************************************/
void houtui()
{
ZUO1=0;ZUO2=1;
YOU1=0;YOU2=1; //后退
}
/*******************************************************************************
* 函 数 名         : houtui3s
* 函数功能         : 控制电机后退3s
*******************************************************************************/
void houtui3s()
{
unsigned char a,b,c=20;  //后退3秒钟=
ZUO1=0;ZUO2=1;
YOU1=0;YOU2=1;     //左转
for (;c>0;c--)
{
for (b=38;b>0;b--)
{
for (a=130;a>0;a--)
{
redreceive();
}
}       
}
pause();

}
/*******************************************************************************
* 函 数 名         : void lefturn1s()
* 函数功能         : 控制电机左转1s
*******************************************************************************/
void lefturn1s()
{
unsigned char a, b,c=5; 
ZUO1=0;ZUO2=0;
YOU1=1;YOU2=0; //左转
for (;c>0;c--)
{
for (b=38;b>0;b--)
{
for (a=130;a>0;a--)
{
redreceive();
}
}       
}
pause();
}
/*******************************************************************************
* 函 数 名         : zuozhuan
* 函数功能         : 控制电机左转
*******************************************************************************/
void zuozhuan()
{
ZUO1=0;ZUO2=0;
YOU1=1;YOU2=0;      //左转
redreceive();
}

/*******************************************************************************
* 函 数 名         : void righturn1s()
* 函数功能         : 控制电机右转1s
*******************************************************************************/
void righturn1s()
{
unsigned int  a, b,c=5;  //右转1秒钟
ZUO1=1;ZUO2=0;
YOU1=0;YOU2=0; //右转
for (;c>0;c--)
{
for (b=38;b>0;b--)
{
for (a=130;a>0;a--)
{
redreceive();
}
}       
}
pause();    //电机停止
}  
/*******************************************************************************
* 函 数 名         : youzhuan
* 函数功能         : 控制电机右转
*******************************************************************************/
void youzhuan()
{
ZUO1=1;ZUO2=0;
YOU1=0;YOU2=0; //右转
redreceive();
}
/*******************************************************************************
* 函 数 名         : pause
* 函数功能         : 控制电机停止
*******************************************************************************/ 
void pause()
{
     ZUO1=0;ZUO2=0;
YOU1=0;YOU2=0; //电机停止
}
/*******************************************************************************
* 函 数 名         : Bee
* 函数功能         : 蜂鸣器响一声
*******************************************************************************/ 
void Bee()
{
BEE=1;
Delay10ms(200);
BEE=0;             //蜂鸣器响一声
} 






 
 /*******************************************************************************
* 程序  名         : 超声波HY-SRF05测距、红外接收控制小车3.0
* 程序功能         : 测量距离、红外控制、自动巡航
* 备注	      : 130直流电机.L298N电机驱动、HY-SRF05超声波测距模块、红外收发模块 ,蜂鸣器,LED灯
*******************************************************************************/
// --头文件声明 --//
#include<reg51.h>
#include <intrins.h>

//--声明超声波引脚对应--//
sbit TRIG=P2^3;					  			  //TRIG是触发信号
sbit ECHO=P2^4;					 			  //ECHO是测距的持续信号

//--声明LED灯驱动引脚对应--//
sbit ZLED=P0^6;
sbit YLED=P0^7;
sbit HLED=P3^6;
//--声明电机驱动引脚对应--//
sbit ZUO1 =P2^6;     	 //左转控制口1
sbit ZUO2 =P2^7;		 //左转控制口2
sbit YOU1 =P1^3; 	 	 //右转控制口1
sbit YOU2 =P1^4;		 //右转控制口2

//--声明蜂鸣器驱动引脚对应--//
sbit BEE =P2^1;			 //蜂鸣器控制引脚
//--定义全局变量--//
unsigned long S=0;  		    //距离初始化
unsigned int time=0; 			//超声波往返时间寄存变量
unsigned char receiveData;      //用来保存红外模块串口接收的数据
unsigned int flag=0;			//运动模式转动方向标志
unsigned int t=0;
//--声明全局函数--//
void Delay10ms(unsigned int c); //延时10ms函数
void system_Ini();				//定时器系统、中断初始化函数
void Conut(void);				//距离计算函数
void movemode();				//选择运动模式
void StartModule();			    //采集信号初始化函数	   
void UsartConfiguration();      //红外串口函数
void redreceive();			    //红外遥控信息接收函数
void qianjin();					//控制电机前进		
void houtui();					//控制电机后退
void houtui3s();			    //控制电机后退3s
void lefturn1s();   			//控制电机左转1s
void righturn1s();   			//控制电机右转1s
void pause(); 				    //控制电机停止
void Bee();						//蜂鸣器响一声	 
void delayus(unsigned int x) ;
/*******************************************************************************
* 函 数 名        : main
* 函数功能        : 主函数
*******************************************************************************/
void main(void)
{
	UsartConfiguration();  		 	  		  //串口函数初始化
	system_Ini();			 			  	  //定时器系统、中断初始化
	pause();								  //小车停止
	BEE=1;

	while(1)						 	  //进入红外控制死循环
	{
		ZLED=1;
		YLED=1;
		HLED=1;
		redreceive();                   //接收红外信息
		if		 ( receiveData == 24)    //按键2按下
		{
				Bee();					//蜂鸣器响一声
				while( receiveData != 28 ) //当按键5没有按下时,一直前进,下同
				{
					qianjin();			 //小车前进
				    redreceive();		 //前进的同时,持续进行是否有红外按键5——停止信号输入的扫描,下同
				}
				pause();            	 //停止
				receiveData=0; 
		}
		else if( receiveData == 82)      //按键8按下
		{
				Bee();					//蜂鸣器响一声
				while( receiveData != 28 )
				{
					houtui();     	  	 //后退
					redreceive();
				}
				pause();         		 //停止
			    receiveData=0; 
		}
		else if( receiveData == 8)       //按键4按下
		{
		     Bee();					//蜂鸣器响一声
	
					lefturn1s();    		     //左转
					redreceive();
			       receiveData=0; 
		}
		else if( receiveData == 90)      //按键6
		{
			 Bee();					//蜂鸣器响一声
					righturn1s();    		     //右转
					redreceive();
			       receiveData=0; 
		}
		else if (receiveData == 74)       //按键9,自动巡航,遇见障碍物过近
		{
				Bee();					//蜂鸣器响一声
				while( receiveData != 28 )
				{
					 StartModule();      //启动采集信号初始化模块,即进行一次数据采集,TRIG每隔一段时间输出一次高电平触发信号
					 while(!ECHO);       //当ECHO为0时等待信号到来,TRIG发出一段大于10us的高电平后,超声波模块会进行发送8段40khz周期电平
										 //然后检测回波信号,回波信号脉宽与ECHO信号高电平持续时间成正比,ECHO持续时间*声速再除以2,
										 //结果即为距离。此时为等待RX产生高电平,一旦产生后,后面定时器即开始计数,
					 TR0=1;              //打开定时器0,开启计数  
					 while(ECHO);        //当ECHO为1时计数进入循环等待,ECHO高电平不结束,计时不停止,一旦结束
					 TR0=0;              //关闭定时器0,停止计数 
					 Conut();			 //通过计数来的时间在距离计算函数中计算距离S
					 movemode();	     //选择运动模式
				}
				pause();     			 //停止
				receiveData=0; 
			}
		 else {ZLED=1;YLED=1;HLED=1;receiveData=0; continue;	}			     //未接收到红外信息时,继续从头循环等待
	}
}
/*******************************************************************************
* 函 数 名         : Delay10ms
* 函数功能        : 延时函数,延时10ms
*******************************************************************************/
void Delay10ms(unsigned int c)      	  //误差 0us
{
    unsigned char a, b;
    for (;c>0;c--)
	{
		for (b=38;b>0;b--)
		{
			for (a=130;a>0;a--)redreceive();
		}       
	}       
}
/*******************************************************************************
* 函 数 名        :system_Ini
* 函数功能        :定时器T0系统/中断初始化
/******************************************************************************/
void system_Ini(void)
{  
	TH0=0;
	TL0=0;
    TMOD=0x21;         //设T0为方式1            
    ET0=1;             //允许T0中断  
    EA=1;              //开启总中断   
} 
/*******************************************************************************
* 函 数 名         : Conut
* 函数功能		   : 测量超声波距离S
*******************************************************************************/
 void Conut(void)  
{  
     time=TH0*256+TL0;						 //时间等于高位信息+低位信息的和,读取测量得到的时间,单位是微秒,是超声波发送出去到反射回来的时间.
     TH0=0;  					   
     TL0=0;  			  				     //计算完成后,初始化定时器高低位信息		 
	 S=time*0.017;							 //计算超声波距离
} 
/*******************************************************************************
* 函 数 名         : movemode
* 函数功能		   : 选择运动模式
*******************************************************************************/
void movemode()
{
	if(S<23)     //如果距离小于23CM,则
	{
		pause();
		Bee();
		redreceive();
		if(flag>=0&&flag<=2)
		{
		lefturn1s();	//左转1s
		flag=flag+1;
		Delay10ms(40);
		} 
		else if(flag==3)
		{
		houtui3s();		//后退
		flag=flag+1;
		Delay10ms(50);
		righturn1s();
		Delay10ms(50);
		}
		else if(flag==7)
		{
		houtui3s();		//后退
		flag=flag+1;
		Delay10ms(50);
		lefturn1s();
		Delay10ms(50);
		}
		else if(flag>=4&&flag<=6)
		{
		righturn1s();   //右转1s
		flag=flag+1;
		Delay10ms(40);
		}
		else 			//标志位清零
		flag=0;
		

	}
	else		//如果距离大于8CM,则
	{
	ZUO1=1;ZUO2=0;
	YOU1=1;YOU2=0; 				
	delayus(50);
	ZUO1=0;ZUO2=0;
	YOU1=0;YOU2=0; 		//前进
	delayus(2000);
	ZUO1=1;ZUO2=0;
	YOU1=1;YOU2=0; 	
	}
}


/***********************************************************
* 函 数 名         :StartModule()
* 函数功能		   :超声波采集信号初始化函数
/**********************************************************/ 
 void  StartModule()    //启动模块  
{  
      TRIG = 1;         //启动一次模块  
      _nop_();   
      _nop_();   
      _nop_();   
      _nop_();   
      _nop_();   
      _nop_();   
      _nop_();   
      _nop_();   
      _nop_();   
      _nop_();   
      _nop_();   
      _nop_();   
      _nop_();   
      _nop_();   
      _nop_();   
      _nop_();   
      _nop_();  
      _nop_();   
      _nop_();   
      _nop_();   
      _nop_();  
      TRIG = 0;  
}  
/*******************************************************************************
* 函 数 名         :UsartConfiguration()
* 函数功能		   :设置红外接收串口
*******************************************************************************/
void UsartConfiguration()
{
	SCON=0X50;			//设置为工作方式1
	TMOD=0X20;			//设置计数器工作方式2
	PCON=0X80;			//波特率加倍
	TH1=0XF3;		    //计数器初始值设置,注意波特率是4800
	TL1=0XF3;
	TR1=1;				//打开计数器
}
/*******************************************************************************
* 函 数 名         : redreceive()
* 函数功能         : 红外接收
*******************************************************************************/
void redreceive()
{
		if(RI == 1)						    //查看红外是否接收到数据,如果接受到
		{
			receiveData = SBUF;				//读取数据,存至变量receiveData
			RI = 0;							//清除串口接收标志位
		}
}
/*******************************************************************************
* 函 数 名         : qianjin
* 函数功能         : 控制电机前进
*******************************************************************************/
void qianjin()
{

	ZUO1=1;ZUO2=0;
	YOU1=1;YOU2=0; 				
	delayus(98);
	ZUO1=0;ZUO2=0;
	YOU1=1;YOU2=0; 				//前进
	delayus(2);
	ZUO1=0;ZUO2=0;
	YOU1=0;YOU2=0; 				
	delayus(100);
}
/*******************************************************************************
* 函 数 名         : houtui
* 函数功能         : 控制电机后退
*******************************************************************************/
void houtui()
{
	 ZUO1=0;ZUO2=1;
	 YOU1=0;YOU2=1; 				//后退
}
/*******************************************************************************
* 函 数 名         : houtui3s
* 函数功能         : 控制电机后退3s
*******************************************************************************/
void houtui3s()
{				
	unsigned char a,b,c=10;  			//后退3秒钟=
	HLED=0;
	ZUO1=0;ZUO2=1;
	YOU1=0;YOU2=1; 			    	//左转
	for (;c>0;c--)
	{
		for (b=38;b>0;b--)
		{
			for (a=130;a>0;a--)
			{
			redreceive();
			}
		}       
	}
	HLED=1;
	pause();

}
/*******************************************************************************
* 函 数 名         : lefturn1s()
* 函数功能         : 控制电机左转some time
*******************************************************************************/
void lefturn1s()
{				
	unsigned char a, b,c=3;
	ZLED=0; 	 	
	ZUO1=0;ZUO2=0;
	YOU1=1;YOU2=0; 				//左转
	for (;c>0;c--)
	{
		for (b=38;b>0;b--)
		{
			for (a=130;a>0;a--)
			{
			redreceive();
			}
		}       
	}
	ZLED=1;
	pause();
}


/*******************************************************************************
* 函 数 名         : void righturn1s()
* 函数功能         : 控制电机右转some time
*******************************************************************************/
void righturn1s()
{	
		
	unsigned int  a, b,c=2; 		 	//右转
	YLED=0;
	ZUO1=1;ZUO2=0;
	YOU1=0;YOU2=0; 				//右转
	for (;c>0;c--)
	{
		for (b=38;b>0;b--)
		{
			for (a=130;a>0;a--)
			{
			redreceive();
			}
		}       
	}
	YLED=1;
	pause();  	  //电机停止
}  

/*******************************************************************************
* 函 数 名         : pause
* 函数功能         : 控制电机停止
*******************************************************************************/ 
void pause()
{
     ZUO1=0;ZUO2=0;
	 YOU1=0;YOU2=0; 					//电机停止
	 HLED=0;
}
/*******************************************************************************
* 函 数 名         : Bee
* 函数功能         : 蜂鸣器响一声
*******************************************************************************/ 
void Bee()
{
	BEE=0;
	Delay10ms(3);
	BEE=1;		             //蜂鸣器响一声	
}
/*******************************************************************************
* 函 数 名         : delayus
* 函数功能         : pwm delay
*******************************************************************************/ 	
void delayus(unsigned int x)
{while(x--);	redreceive();}	

猜你喜欢

转载自blog.csdn.net/weixin_39222888/article/details/80372382
今日推荐