51循迹小车-集成蓝牙控制,超声波避障,红外目标跟随,实时测距显示。


最近学校举办了个小比赛,使用51单片机集成 蓝牙控制,舵机摇头超声波避障,红外目标跟随,测距显示。来简单分享下。完整代码会在文末贴出。

在这里插入图片描述

定时器初始化

一开始直接让我疑惑的是51单片机只有两个定时器,而蓝牙通信波特率需要一个,超声波也需要一个,剩下舵机和PWM调速也要定时器明显不够用,
好在实际上比赛小车的芯片为52RC,拥有3个定时器,我的分配方案如下:

T0舵机和PWM调速共用;
T1给超声波使用;
T2给蓝牙使用;

定时器的初始化:

	void Init()
{
	/*T1和T0的初始化*/
	TMOD|=0x11;//定时器1工作方式1 (超声波),定时器0舵机
	TH1=0x00;    
	TL1=0x00;  //超声波
	TH0=(65536-100)/256;
	TL0=(65536-100)%256;
    ET1=1;
    ET0=1;
    EA=1;
    TR0=1;//定时器开始
    IE=0x92;//中断允许控制寄存亲
	
	/*T2的初始化*/
	T2MOD=0x01;//定时器1工作方式1 (超声波),定时器0舵机
	T2CON = 0x30;
	TH2=0xFd;    
	TL2=0xfd;  //蓝牙
	RCAP2H =0XFF;
	RCAP2L=0xDC;
	SCON=0x50;
	PCON=0x00;
	PS=1;//将蓝牙串行设置为高优先级
	TR2=1;
	PT1=0;
    EA=1;
	ES=1;    
}

蓝牙控制部分

蓝牙通信发送指定字符控制小车运行

	#define up       'A'//前进
    #define down     'B'//后退
	#define le     'C'//左转
    #define ri    'D'//右转
	#define stop     'F'//停止
	#define gx       'G'//跟随
	#define csb       'S'//超声波

发送信号蓝牙串行口产生中断写入数组buff[]
ON引导字符,例如前进需要发送“ONA”

if(buff[0]=='O'&&buff[1]=='N')	//第一个字节为O,第二个字节为N,第三个字节为控制码
		switch(buff[2])
	     {
		    case up :						    // 前进
			  send_str( );
			  run();
			  ShowPort=LedShowData[1]; 
			  break;
		    case down:						// 后退
			  send_str1( );
			  backrun();
			  ShowPort=LedShowData[2]; 
			  break;
		     case le:						// 左转
			   send_str3( );
			  leftrun();
			  ShowPort=LedShowData[3];  
			  break;
		      case ri:						// 右转
			  send_str2( );
			  rightrun();
			  ShowPort=LedShowData[4];
			  break;
		      case stop:						// 停止
			   send_str4( );
			  ShowPort=LedShowData[0];
			  stoprun();
			  break;
			  case  gx:						    //跟随
			   send_str5( );
               ShowPort=LedShowData[5];		    
			   GX();
			  break;
			  case  csb:						    //超声波
			   send_str6( );
               ShowPort=LedShowData[5];		    
			   CSB();
			  break;
			  

	     }

跟随

使用小车前面的两个红外避障传感器来跟随(有点傻)
代码:

void  GX(void)
{ 
	while(1)
	 {
	     if(Left_1_led==1&&Right_1_led==1)//
		stoprun();	 //调用停止函数
		else
		{			  
		if(Left_1_led==1&&Right_1_led==0)//右边检测到目标
	 	{
			rightrun();	 //调用小车右转函数
			delay(20);
		}
				   
	if(Right_1_led==1&&Left_1_led==0)		//左边检测到红外信号
		 {	  
			leftrun();	  //调用小车左转函数
			delay(20)}
	if(Right_1_led==0&&Left_1_led==0)//两边传感器同时检测到目标
		{	  
			run();		    //调用前进函数
			delay(20);
		}
	}	
	 if(buff[2]!=gx) return;//如果收到蓝牙不是gx则退出
	}		
 	return;  
 }

超声波

超声波和舵机是一起使用的
检测到前方有障碍后停车,舵机扭头判断左右的空间来转向
也顺便显示距离

void CSB()
{
	
	Delay1ms(5);//延时片刻
	angle=12;//舵机居中
    count=0;
	//Display_LCD();
    TIM0init();//初始化定时器
    while(1)
    {          
		chaoshengbo();
		Display_LCD();
		Front_Distance = S;
        DelayMs(20);
		
        if(Front_Distance > 30)//如果大于一定距离
        {run();}//前进
        
		if(Front_Distance < 30)//如果小于一定距离
        {
			stoprun();//停车
            
            angle=4;
            count=0;
            DelayMs(400);
            chaoshengbo();
			Display_LCD();
			Right_Distance= S;
            DelayMs(20);

            angle=12;
            count=0;
            DelayMs(400);

            angle=20;
            count=0;
            DelayMs(400);
            chaoshengbo();
			Display_LCD();
			Left_Distance = S;
            DelayMs(20);
          
			angle=12;
            count=0;	
            DelayMs(400);
 			
			
			 if((Left_Distance < 30 ) &&( Right_Distance < 30 ))  //左右两边距离都小于30
   		    {
        		backrun();//后退
        		DelayMs(80);
        		leftrun;//左转
        		DelayMs(40);
					}
				else 
				{
					
				if(Left_Distance < Right_Distance)	  //左边距离小于右边的距离
            {
            	rightrun();		   //调用小车右转	函数
            	DelayMs(100);
        	}
            
				if(Left_Distance >= Right_Distance)
            {
           		leftrun();		  //调用小车左转  函数
            	DelayMs(100);
            }
				
				}					
					
		}
	if(buff[2]!=csb) return;
	}
		return;
}

测距

测距放在了主函数里和蓝牙一起;实时显示障碍物距离
主函数:

/****************************/

	void main(void)
{
	TIM0init();//初始化定时器 
	Init(); 	 
	ShowPort=LedShowData[0];
	Delay1ms(400); //启动等待,等LCM讲入工作状态
	LCMInit(); //LCM初始化
	while(1)							/*无限循环*/
	{ 
		CSBCJ();
	  if(flag_REC==1)				    //
	   {
		flag_REC=0;
		if(buff[0]=='O'&&buff[1]=='N')	//第一个字节为O,第
		switch(buff[2])
	     {
		    case up :						    // 前进
			  send_str( );
			  run();
			  ShowPort=LedShowData[1]; 
			  break;
		    case down:						// 后退
			  send_str1( );
			  backrun();
			  ShowPort=LedShowData[2]; 
			  break;
		     case le:						// 左转
			   send_str3( );
			  leftrun();
			  ShowPort=LedShowData[3];  
			  break;
		      case ri:						// 右转
			  send_str2( );
			  rightrun();
			  ShowPort=LedShowData[4];
			  break;
		      case stop:						// 停止
			   send_str4( );
			  ShowPort=LedShowData[0];
			  stoprun();
			  break;
			  case  gx:						    //循迹
			   send_str5( );
               ShowPort=LedShowData[5];		    
			   GX();
			  break;
			  case  csb:						    //循迹
			   send_str6( );
               ShowPort=LedShowData[5];		    
			   CSB();
			  break;
	     }
		 }			 
	 }
	}	

完整代码和头文件

https://pan.baidu.com/s/1KwuljekV4HlLfgnRLmuShg

链接:https://pan.baidu.com/s/1KwuljekV4HlLfgnRLmuShg
提取码:e4if
复制这段内容后打开百度网盘手机App,操作更方便哦

  • 20
    点赞
  • 157
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值