【IoT】红外循迹避障小车

本文介绍了一种使用红外传感器的智能小车设计,包括避障和循迹功能。小车采用STC89C52单片机为核心,通过红外传感器检测障碍物和路径,利用PWM技术控制电机转速以实现转向和速度调节。此外,文章还详细描述了硬件电路设计,包括电源、电机驱动和传感器接口等部分。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

说明

随着生产自动化的发展需要,机器人已经越来越广泛地应用到生产自动化上,随着科学技术的发展,机器人的传感器种类也越来越多,其中红外传感器已经成为自动行走和驾驶的重要部件。

红外的典型应用领域为自主式智能导航系统,机器人要实现自动避障功能就必须要感知障碍物,感知障碍物相当给机器人一个视觉功能。智能避障是基于红外传感系统,采用红外传感器实现前方障碍物检测,并判断障碍物远近。而利用红外对不同颜色物体反射强弱差别又可以实现循迹功能。

由于时间和水平有限,我们暂选最基本的避障,循迹功能作为此次设计的目标。

本设计通过小车这个载体再结合由STC89C52为核心的控制板可以达到其基本功能,再辅加由漫反射式光电开关组成的避障电路,基于PWM技术的转速控制、电源电路、电机驱动电路就可以完善整个设计。

功能概述

智能小车采用前轮驱动,前轮左右两边各用一个电机驱动,分别控制两个轮子的转动从而达到转向的目的,后轮是万向轮,起支撑的作用。

避障部分,将3个红外线光电传感器分别装在车体的左中右,当车的左边的传感器检测到障碍物时,主控芯片控制右轮电机停止左轮转动,车向右方转向,当车的右边传感器检测到障碍物时,主控芯片控制左轮电机停止转动,车向左方转向,当前面有障碍物时规定车右转。而当小车同时有两个传感器接收到信号时,采用倒退方式转弯以避免碰到障碍物,于此同时测定速度并显示,在避障小车前进的同时从LCD点阵液晶显示器上显示小车当时速度和行驶的路程。

循迹部分,采用七个红外传感器置于车身前下方,中间五个主要用于循迹普通道路,外边两个略比中间的靠前,主要用来检测直角弯道。

车向左偏时右拐,右偏时左拐,左右拐又分为校正和转弯两档。遇到直角时极易冲出跑道,故给车施加一个反向脉冲。行驶过程中显示屏显示车速及路程。

硬件设计

如下图所示,是本次设计智能小车的电路框图。

以STC89C52为电路的中央处理器,来处理传感器采集来的数据,处理完毕之后以便去控制电机驱动电路来驱动电机。电源部分是为整个电路模块提供电源,以便能正常工作。

在这里插入图片描述

避障电路

(1) 障碍物探测方案的选择

方案一:脉冲调制的反射式红外线发射接受器。由于采用该有交流分量的调制信号,则可大幅度减少外界干扰;另外红外线接受官的最大工作电流取决于平均电流。

如果采用占空比小的调制信号,再品均电流不变的情况下,顺势电流很大(50—100mA),则大大提高了信噪比。并且其反应灵敏,外围电路也很简单。它的优点是消除了外界光线的干扰提高了灵敏度。

方案二:采用超声波传感器,如果传感器接收到反射的超声波,则通知单片机前方有障碍物,如则通知单片机可以向前行驶。市场上很多红外光电探头也都是基于这个原理。这样不但能准确完成测量,而且能避免电路的复杂性

由以上两种方案比较可知。方案一要比方案二优势大,市场上很多红外观点探头也都基于这个原理。其电路简单,工作可靠,性能比较稳定。从而避免了电路的复杂性,因此我先用方案二作为小车的监测系统。

避障电路采用漫反射式光电开关进行避障。光电开关是集发射头和接收头于一体的检测开关,其工作原理是根据发射头发出的光束,被障碍物反射,接收头据此做出判断是否有障碍物。当有光线反射回来时,输出低电平;当没有光线反射回来时,输出高电平。单片机根据接收头电平的高低做出相应控制,避免小车碰到障碍物,由于接收管输出TTL电平,有利于单片机对信号的处理。

光电开关工作原理:

光电开关是通过把光强度的变化转换成电信号的变化来实现控制的。

光电开关在一般情况下,有三部分构成,它们分为:发送器、接收器和检测电路。

在这里插入图片描述
在这里插入图片描述
(2)信号检测模块

小车循迹原理是小车在画有黑线的白纸 “路面”上行驶,由于黑线和白纸对光线的反射系数不同,可根据接收到的反射光的强弱来判断“道路”—黑线。笔者在该模块中利用了简单、应用也比较普遍的检测方法——红外探测法。

红外探测法,即利用红外线在不同颜色的物理表面具有不同的反射性质的特点。在小车行驶过程中不断地向地面发射红外光,当红外光遇到白色地面时发生漫发射,反射光被装在小车上的接收管接收;如果遇到黑线则红外光被吸收,则小车上的接收管接收不到信号,再通过LM324作比较器来采集高低电平,从而实现信号的检测。

避障亦是此原理。电路图如图3.4。

市面上有很多红外传感器,在这里我选用TCRT5000型光电对管。

在这里插入图片描述

单片机电路

本设计的主控芯片选择STC89C52,负责检测传感器的状态并向电机驱动电路发出动作命令。

复位电路采用手动复位。

单片机电路如下:

在这里插入图片描述

电机转速控制电路

转速控制采用基于PWM技术的脉冲调制技术,通过单片机输出两列PWM信号,经过l298N对电机进行速度调控。

电源电路

本系统所有芯片都需要+5V的工作电压,而干电池只能提供的电压为1.5V的倍数的电压,并且随着使用时间的延长,其电压会逐渐下降,故采用了一个12v蓄电池,再用LM7805稳压芯片。

L7805能提供最大1A的电流,足以满足芯片供电的要求。虽然微处理器和微控制器不需要支持电路,功耗也很低,但必须要加以考虑。

电源电路拟定为:

在这里插入图片描述
电机驱动电路

市场上用很多种类的小电压直流电动机,很方便的选择到。主要有普通电动机、和步进电动机。

方案一:采用步进电机,步进电动机的一个显著的特点就是具有快速启动和停止能力,能够达到我们所要求的标准。如果负荷不超过步进电机所能提供的动态转矩值,就能够立即是步进电机启动或反转。其转换灵敏度比较高。正转、反转控制灵活。但是步进电机的价格比较昂贵,对于我们的现状相差太远。

方案二:采用普通的直流电机。直流电机具有优良的调速特性,调速平滑、方便。调整范围广;过载能力强,能承受频繁的冲击负载,可实现频繁的无极快速启动、制动和反转。能满足各种不容的特殊运行要求。
由于普通直流电机价格适宜,更易于购买,并且电路相对简单,因此采用直流电机作为动力源

本设计采用L298N驱动使电机正反转从而做到前进,左转右转。

电机驱动一般采用H桥式驱动电路,L298N内部集成了H桥式驱动电路,从而可以采用L298N电路来驱动电机。通过单片机给予L298N电路PWM信号来控制小车的速度,起停。其引脚图如3.2,驱动原理图如图3.3。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

源码

#include<reg52.h>
#include <intrins.h>
#include <string.h>
#define Busy 0x80 //用于检测LCM状态字中的Busy标识
#define LCM_Data P0
#define uchar unsigned char
sbit LCM_RS=P2^2;             //1602寄存器选择
sbit LCM_RW=P2^1;          //读/写控制
sbit LCM_E=P2^0;

sbit LLT=P1^7;//避障口
sbit RLT=P2^7;
sbit MLT=P3^4;

sbit S1=P1^0;	  //传感器信号输入端口
sbit S2=P1^1;
sbit S3=P1^3;//INT
sbit S4=P1^5;//LLT
sbit S5=P1^6;//RLT
sbit S6=P1^2;
sbit S7=P1^4;//OUT

sbit LH=P2^3;	   //电机1		左轮
sbit LL=P2^4;

sbit RH=P2^5;	   //电机2		右轮
sbit RL=P2^6;

sbit ENA=P3^6;//电机左轮使能
sbit ENB=P3^7;//电机右轮使能


sbit key1=P3^0;
sbit key2=P3^1;	  
sbit key3=P3^2;
sbit key4=P3^3;
/******************************************************
* 名    称:引脚定义
* 功    能:引脚定义
* 入口参数:无
* 出口参数:无
*******************************************************/



unsigned char 
character1[][8]={{0x2,0x02,0x2,0x02,0x1F,0x02,0x06,0x7},{0x00,0x0F,0x8,0x08,0xF,0x08,0x08,0x0F},
{0x00,0x1C,0x4,0x4,0x1C,0x4,0x4,0x1C},{0xA,0xA,0x2,0x02,0x02,0x02,0x02,0x2},{0x19,0x09,0x8,0x08,0x8,0x0A,0x0C,0x08},
{0x2,0x4,0x18,0x10,0x8,0x4,0x2,0x03}};


int C1=0,C2=0,C3;//计数单位
static int SU0=0,SU1=0,SU2=0,SU=0;
static int  SU3=0,V=0,V0=0,V1=0;



int tmp1=0,tmp2=0;//左右占空比调整tmp/T
int SPEED1,SPEED2;

uchar count=0;		//初始化计数变量
uchar T=90;		//pwm信号周期T*100us
/***********************************************************************
测距模块儿
***********************************************************************/

void delay10us()				//延时,>10us
	{
		_nop_( ); 
		_nop_( ); 
		_nop_( ); 
		_nop_( ); 
		_nop_( ); 
		_nop_( ); 
		_nop_( ); 
		_nop_( ); 	
	}

int mainceju()
{

	char T;
	int START,END,longth;
	S3=0;S4=0;//初始化接口值
	S4=1;				//开始发射脉冲
	delay10us();			//延时
	while(!S3);		//等待返回信号
	START=(TH2*256+TL2);//开始计时
	while(S3);			//等待返回信号结束
	END=(TH2*256+TL2);//关闭计时器

	T=(TH0*256+TL0);	//计算返回脉冲时间
	longth=340*T/20000;//计算测距结果厘米
	
	
	
	return(longth);

	
		
}



/*****************************************************************************************************
循迹模块儿
****************************************************************************************************/
/******************************************************
*名    称elay(long int Delay_time)
*功    能:延时
*入口参数:Delay_time
*出口参数:无、
*说    明: 延时
******************************************************/

void delay(long int Delay_time)//延时函数
 {
 	int i;
	 while(Delay_time)
		 
	 {
		 for(i=0; i<150;i++)
		  {
		   _nop_();	 
		   _nop_();
		   _nop_();
		   _nop_();
			}
		 Delay_time--;
	 }
}

//-----------------------------------------------
void correct_left()//向左校正,赋值
 {
   tmp1=T-30;
   tmp2=T-15;
   LH=1;
   LL=0;
   RH=1;
   RL=0;
 }
//------------------------------------------------
 void correct_right()//向右校正,赋值
 {
   tmp1=T-15;
   tmp2=T-30;
   LH=1;
   LL=0;
   RH=1;
   RL=0;
 }
//--------------------------------------------------
void turn_left()//左转,赋值
{
  tmp1=0;
  tmp2=T-25;
  LH=0;	 //转弯时一个正转,一个反转,
  LL=0;
  RH=1;
  RL=0; 		
}
//---------------------------------------------------
void turn_right()//右转,赋值
{
  tmp1=T-25;
  tmp2=0;
  LH=1;	  //转弯时一个正转,一个反转,
  LL=0;	
  RH=0;	
  RL=0; 
}
//-----------------------------------------------------
void straightL()	//慢直走,赋值
{
  tmp1=T-40;	//左右电机占空比初始化,调节直线运动速度
  tmp2=T-40;	
  LH=1;
  LL=0;
  RH=1;
  RL=0; 
}

//-----------------------------------------------------
void straight()	//直走,赋值
{
  tmp1=T-10;	//左右电机占空比初始化,调节直线运动速度
  tmp2=T-10;	
  LH=1;
  LL=0;
  RH=1;
  RL=0; 
}
//-----------------------------------------------------
void back()	//后退
{
  tmp1=T-20;	//左右电机占空比初始化,调节直线运动速度
  tmp2=T-20;	//鉴于左右轮电机内部阻力不同,故占空比取不同值,这组值需要单独写程序取值
  LH=0;
  LL=1;
  RH=0;
  RL=1; 
}

//-----------------------------------------------------
void stop()	//停车
{
	tmp1=0;
	tmp2=0;
    LH=0;
    LL=0;
    RH=0;
    RL=0;
    ENA=0;
	ENB=0;


}




		/******************************************************
		* 名    称:void turn()
		* 功    能:路径控制
		* 入口参数:int Position
		* 出口参数:无
		******************************************************/

void turn ()
{



	
		if(!(S1|S2|S3|S4|S5|S6|S7))
		{
		   _nop_();
		   _nop_();
			back();
			delay(20);
			if((!S1)&(!S2)&S4&(!S6)&(!S7))
			{
				if(S4&S5&S6);
				else 
				back();
			
			}
		
		
		}//后退寻线
			

	
	//全白后退寻线



		if(S1&S2&S3&S4&S5&S6&S7)
		{
			delay(1); 
			stop();
			back();
			delay(1);

	
		}//全黑,停止
	

					if( (S1&S3&(!S7))||(S1&S4&(!S7))||(S2&S4&(!S7)) )//遇到左直角
				{
					back();
					delay(5);

					turn_left();
					delay(5);
					while( (S1&S3&(!S7))||(S1&S4&(!S7))||(S2&S4&(!S7)) )
					turn_left();
					//delay(50);
				}
		
				if( (S5&S7&(!S1))||(S4&S7&(!S1))||(S4&S6&(!S1)) )//遇到右直角
				{
					back();
					delay(5);
					turn_right();
					delay(5);
					while( (S5&S7&(!S1))||(S4&S7&(!S1))||(S4&S6&(!S1)) )
					turn_right();
					//delay(50);
				
				}




	if((!S1)&(!S2)&S4&(!S6)&(!S7))
	{
	
			_nop_();
		    _nop_();
		    _nop_();
			_nop_();

	

	
		if(S3&S4&S5)//避免死循环
				{
					back();
					delay(20);
					if(S3&S4)
						{
							turn_left();
							delay(5);
						}
					if(S4&S5)
						{
							turn_right();
							delay(5);
						}


				}

			else
		 straight();

	}//全速速前行



	if(!(S4|S5|S6|S7))
	{
		
		 _nop_();
		   _nop_();
		   _nop_();

		if((!S1)&S3)
			correct_left();		//校正

		if( ((!S3)&S2)||(S1&(!S3)) )
			turn_left();		//左拐

		if(S1&S2&S3)//遇到左直角
		{
			back();
			delay(5);
			while(S1&S2&S3)
			turn_left();
			delay(5);
		
	
		}

		
	}					





	if( !(S1|S2|S3|S4))
	{
	
		
		
		_nop_();
		 _nop_();	
 	   _nop_();
		_nop_();			

		if(S5&(!S7))
			correct_right();//校正
			

		if( ( (!S5)&S6 )||((!S5)&S7) )
			turn_right();		//右拐

		if(S5&S6&S7)//遇到右直角
		{
			back();
			delay(5);
			while(S5&S6&S7)
			turn_right();
			delay(5);
		
	
		}

		

	}					
}

/****************************************************************************************************
避障模块儿
*****************************************************************************************************/

void Rback()
{

	RH=0;
	RL=1;
	LH=0;
	LL=0;
}
void Lback()
{

	RH=0;
	RL=0;
	LH=0;
	LL=1;
}
void mainbizhang()
{

	
	if((!LLT)&MLT&(!RLT))//010
		{
		Rback();
		delay(20);
		}
	if((LLT)&(!MLT)&(!RLT))//100
		turn_left();

	if((!LLT)&(!MLT)&(RLT))//001
		turn_right();

	if((!LLT)&(!MLT)&(!RLT))//000
		{
		Rback();
		delay(15);
		}

		

	if((!LLT)&(MLT)&(RLT))//011
		turn_right();

	if((LLT)&(!MLT)&(RLT))//101
		turn_left();

	if((LLT)&(MLT)&(!RLT))//110
		turn_left();

	if((LLT)&(MLT)&(RLT))//111
		straight();



}

/*****************************************************************************************************
测速显示子程序
*****************************************************************************************************/
		//=====================================================================================
			//延时程序
		//=====================================================================================
		void Delay5Ms()
		{
	 		unsigned long int TempCyc = 5000;
			 while(TempCyc--);
		}
			



			uchar ReadStatusLCM()

			{

				char i;
				uchar busy;
				LCM_RS = 0;
				LCM_RW = 1;
				LCM_E = 1;
				for(i=0;i<100;i++);
				busy=(P0&0x80);
				LCM_E = 0;
				return(busy);
			}
			
			
			//=====================================================================================
			//读写子程序
			//=====================================================================================
			
			//读数据
			unsigned char ReadDataLCM()
			{
				while (ReadStatusLCM());
				
				LCM_RS = 1; 
				LCM_RW = 1;
				LCM_E = 1;
				return(LCM_Data);
			}
			
			//读状态

			//写数据
			void WriteDataLCM(unsigned char WDLCM)
			{char i;
				while (ReadStatusLCM());
				
				LCM_Data = WDLCM;
				LCM_RS = 1;
				LCM_RW = 0;
				LCM_E=0;
				LCM_E = 1; 
				 //若晶振速度太高可以在这后加小的延时
				for(i=0;i<100;i++);//延时
				LCM_E =0;
			}
			
			//写指令
			void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测
			{
				char i;
				while(ReadStatusLCM());
				LCM_Data = WCLCM;
				LCM_RS = 0;
				LCM_RW = 0;
 				LCM_E = 0;
				LCM_E = 1;
				for(i=0;i<100;i++);
				LCM_E = 0;
				
			}
			
			//=====================================================================================
			//初始化子程序
			//=====================================================================================
			
			void LCMInit(void) //LCM初始化
			{
					
					LCM_Data = 0;
					WriteCommandLCM(0x38,0); // 三次显示模式设置,不检测忙信号
					Delay5Ms(); 
					WriteCommandLCM(0x38,0);
					Delay5Ms(); 
					WriteCommandLCM(0x38,0);
					Delay5Ms(); 
					WriteCommandLCM(0x38,1); // 显示模式设置,开始要求每次检测忙信号
					Delay5Ms();
					WriteCommandLCM(0x08,1); // 关闭显示
					Delay5Ms();
					WriteCommandLCM(0x01,1); // 清屏
					Delay5Ms();
					WriteCommandLCM(0x06,1); // 显示光标移动设置
					Delay5Ms();
					WriteCommandLCM(0x0c,1); // 显示开及光标设置
					Delay5Ms();
			}
			
			
			//=====================================================================================
			//按指定位置显示一个字符
			//=====================================================================================
			
			void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
			{
					Y &= 0x1;
					X &= 0xF; //限制X不能大于15,Y不能大于1
					if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
					X |= 0x80;	
				 //算出指令码
					WriteCommandLCM(X, Y); //这里不检测忙信号,发送地址码
					WriteDataLCM(DData);
			}
			
			//=====================================================================================
			//按指定位置显示一串字符
			//void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
			//说明:  x(0-15):x参数 y(0-1):y参数 DData(字符串):要显示的内容(英文、数字、符号)
			//=====================================================================================
			 
			void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
			{
			  unsigned char ListLength,j;
			  ListLength = strlen(DData);
			  Y &= 0x1;
			  X &= 0xF; //限制X不能大于15,Y不能大于1
			      if (X <= 0xF) //X坐标应小于0xF
			        { 
			      for(j=0;j<ListLength;j++)
			        {
			             DisplayOneChar(X, Y, DData[j]); //显示单个字符
			             X++;
			            }
			        }
			}
			
			//=====================================================================================
			//显示自定义字符
			//void mychar(char xx,char yy,unsigned char *character,unsigned char saveto)
			//说明:xx(0-15):为x参数.yy(0-1):y参数.character:要显示的字符的列表地址,在程序前面有定义
			//saveto(1-7)为字符保存的RAM,每屏最多显示7个自定义字符
			//(0x00-0x0h是自定义字符)
			//=====================================================================================
			
			
			//=====================================================================================
			//主函数
			//=====================================================================================
			void mychar(char xx,char yy,unsigned char *character,unsigned char saveto)
			{
					 unsigned char add = (saveto<<3) | 0x40;
					 unsigned char t,o;      //临时变量,每一行的值
					 for(o=0;o<8;o++)
					
					 {
						 t=*(character+o);
						 WriteCommandLCM(add+o, 0);    
						 WriteDataLCM(t);
					 }
					
					 DisplayOneChar(xx,yy,saveto);    //显示字符
			}//====
							

			
			void main1602()
			{

				char m,n;
				char k=0,l=1;
			
				LCMInit();//1602初始化
				delay(400);
				 for(m=0;m<2;m++)
					for(n=0;n<3;n++,k++,l++)
					 {

					  mychar(n+13,m, character1[k],l);
							 
					 }							 					
							 
				// WriteCommandLCM(0x01,1); //清屏*/
							
				DisplayListChar(0,0,"V=00.0m/s");
				DisplayListChar(0,1,"S=000.0m");
						
			}

			/

			void refresh()//刷新屏幕
			{
					
				
			
				//SU=(TH1*256+TL1)/1000;
				SU=(TH1*256+TL1)/100;
				
				if(SU!=0)			
				V=(TH1*256+TL1)/10-SU3;
				//if()
				//V=SU*10/C3;
				SU3=(TH1*256+TL1)/10;
				SU0=SU%10;
				SU1=(SU%100)/10;
				SU2=SU/100;
				V0=(V)%10;
				V1=(V)/10;
				SU0=SU0|0x30;;
				SU1=SU1|0x30;
				SU2=SU2|0x30;
				V0=V0|0x30;
				V1=V1|0x30;
	
				
				

				
				DisplayOneChar(2,0,V1);
				DisplayOneChar(3,0,V0);
				DisplayOneChar(3,1,SU2);
				DisplayOneChar(4,1,SU1);
				DisplayOneChar(6,1,SU0);
			
			}
			void averrage()
			{

				V=SU/C3;
				V0=(V)%10;
				V1=(V)/10;
				V0=V0|0x30;
				V1=V1|0x30;
				DisplayOneChar(2,0,V1);
				DisplayOneChar(3,0,V0);


			
			}


/*********************************************************************************************
1602测速模块儿子程序
***************************************************************************************************/


/******************************************************
*名    称:void begin()
*功    能:初始化
*入口参数:无
*出口参数:无
*说    明: 初始化各个参数
*******************************************************/


void begin()
{		

		key1=1;key2=1;
		key3=1;key4=1;
		TMOD=0X52; 
		
		TH1=0;			/* 装入定时器的初值,计数100次溢出 */ 
		TL1=0;
		TH0=0x9B;			/* 装入定时器的初值,计数100次溢出 */ 
		TL0=0x9B;			/*装入时间常数*/

		EA=1;				/* 开中断 */ 
		ET1=1;
		ET0=1;/* 定时器1允许中断 */ 
		ET2=1;
		TR2=1;
		TR1=1;				/* 启动定时器1 */
	
						/* 定时器0允许中断 */ 
		TR0=1;
		RCAP2H=(65536-10000)/256;
		RCAP2L=(65536-10000)%256;		

		LH=0;
		LL=0;
		RH=0;
		RL=0;
		ENA=0;
		ENB=0;


}
/******void scan()
{
	if(!key1)
	{
		delay(15);
		if(!key1)
	//	while(1)
	//	{
			//begin();//初始化
			//main1602();
		
			do{turn();
			}	while(key1&key2&key3&key4);
		
	//	}			

	}

	
	if(!key2)
	{
		delay(15);
		if(!key2)
		//while(1)
		//{
			//begin();//初始化
			//main1602();			
			
			do{mainbizhang();
			}while(key1&key2&key3&key4);
		//}
	}
	
	if(!key3)
	{
		delay(15);
		if(!key3)
		
		//{
	//	ET0=0;
	//	ET1=0;
		do{averrage();
		}while(key1&key2&key3&key4);
	//	}

	}
	if(!key4)
	{
		delay(15);
		if(!key4)
	//	{
		do{stop();
		}while(key1&key2&key3&key4);

	//	ET0=0;
	//	ET1=0;
		//}
	}
}*/

/******************************************************
* 名    称:void timer0() interrupt 1
* 功    能: T0中断服务程序
* 入口参数:无
* 出口参数:无
*******************************************************/




void timer1() interrupt 5
{
	TF2=0;
	C2++;
	if((C2%100)==0)
	{
	C3++;//每秒刷新一次
	refresh();
	}
	//scan();

}


void timer0() interrupt 1		/* T0中断服务程序 */ 

{ 

	
		
	if(count==0)
	{
		SPEED1=tmp1;
		SPEED2=tmp2;
	}
	if(count<SPEED1) ENA=1;
		else ENA=0;			/* 产生电机1的PWM信号 */
	
	if(count<SPEED2) ENB=1;
	
	else ENB=0;				/* 产生电机2的PWM信号 */
	
	count++; 
	if(count>=T) count=0;				/* 1个PWM信号由100次中断产生 */ 
}

void count0() interrupt 3 
{
		TH1=0/256;			/* 装入定时器的初值,计数100次溢出 */ 
		TL1=0%256;			/*装入时间常数*/

		C1++;
		//s=x96000/48/4*3*13/2

}



void main()
{		

		begin();//初始化
		main1602();//显示模块儿初始化
		while(1)
		{
		if(key1==0)
		{delay(1);
		if(key1==0)
		
		do turn();while(key1&key2&key3&key4);}
		if(key2==0)
		{
			delay(1);
			if(key2==0)
		
			do mainbizhang();
			while(key1&key2&key3&key4);
		}
		if(key3==0)
		{
		delay(1);
		if(key3==0)
		
		do averrage();while(key1&key2&key3&key4);
		}
		if(key4==0)
		{
		delay(1);
		if(key3==0)

		
		do stop();
		while(key1&key2&key3&key4);
		}

		
		}

}
<think>好的,我现在需要帮助用户了解红外避障传感器的工作原理、应用以及电路图。首先,根据用户提供的引用内容,特别是引用[2],里面详细描述了传感器的工作方式。我需要先理解这些信息,再组织成用户容易理解的回答。 首先,用户的问题有三个部分:工作原理、应用、电路图。我需要逐一解答。从引用[2]来看,传感器通过发射红外线并接收反射信号来判断障碍物。这部分需要详细说明发射和接收的过程,以及信号处理的部分。比如,发射管发射特定频率的红外线,遇到障碍物反射后被接收管接收,然后通过比较器处理,输出数字信号。同时,电位器调节检测距离也是关键点。 然后是应用部分。引用[2]提到了机器人避障避障小车、流水线计数和黑白线循迹等应用场景。需要将这些例子具体化,说明传感器在这些场景中的作用,比如在避障小车中如何实时检测障碍物并调整路径。 关于电路图,引用[2]提到有电原理图,但用户可能无法直接看到图片。我需要根据文字描述构建一个简化的电路图,包括发射管、接收管、比较器电路、电位器和输出接口。可能还需要解释各部件的作用,比如比较器如何将模拟信号转为数字信号。 接下来要检查是否需要补充其他信息。比如,工作电压范围3.3V-5V,有效距离2-30cm,这些参数对用户来说可能很重要,需要包含在内。此外,传感器的特点,如抗干扰、便于安装,也应该提到,以帮助用户全面了解。 用户可能还会有深入的问题,比如如何调节距离,或者实际使用中的注意事项。因此在相关问题部分,可以提出关于调节方法、安装注意事项以及与其他传感器的比较,引导用户进一步探索。 最后,确保回答符合系统级指令:使用正确的中文,数学表达式用$...$,独立公式用$$...$$,但在这个问题中可能不需要数学公式。不过如果有涉及计算的地方,比如距离与电位器调节的关系,可能需要用公式,但根据引用内容,这里可能不需要。因此主要关注工作原理和应用的文字描述,以及电路图的文字构建。 总结回答结构:分三个部分,工作原理、应用、电路图说明,每部分引用引用[2]的内容,最后生成相关问题。需要保持语言简洁明了,结构清晰,帮助用户逐步理解。</think>### 红外避障传感器详解 #### 1. 工作原理 红外避障传感器通过**红外线发射与接收**实现障碍物检测。其内部包含一对红外发射管和接收管: - **发射管**:发射特定频率的红外线(如38kHz),穿透环境光线干扰[^2]。 - **接收管**:当检测方向存在障碍物时,红外线被反射至接收管,转化为电信号。 - **信号处理**:接收信号通过**比较器电路**处理,若强度超过阈值,输出低电平信号(0V),同时绿色指示灯亮起。 - **距离调节**:通过电位器旋钮可调节检测灵敏度,有效范围为$2 \sim 30\ \text{cm}$。 $$原理公式:\text{输出信号} = \begin{cases} 低电平 & \text{检测到障碍物} \\ 高电平 & \text{无障碍物} \end{cases}$$ #### 2. 典型应用场景 1. **机器人避障**:实时检测路径障碍物,触发转向或停止[^2]。 2. **智能小车**:用于自动避障小车的前端探测模块。 3. **工业计数**:流水线通过遮挡检测实现物料计数。 4. **循迹系统**:与黑白线反射率差异配合,实现轨道跟踪。 #### 3. 电路图说明(文字描述) 根据引用[2]的电原理图,模块主要包含以下部分: ``` ┌───────────────────────┐ │ 红外发射管 → 发射电路 │ │ 红外接收管 → 信号放大电路 │ │ 比较器 → 阈值判断 │ │ 电位器 → 调节灵敏度 │ │ 数字输出接口(GPIO) │ └───────────────────────┘ ``` - **比较器**:将接收管的模拟信号转为数字信号 - **电位器**:调整比较器阈值以改变探测距离 - **输出接口**:直接连接树莓派GPIO,通过高低电平判断状态[^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

产品人卫朋

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

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

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

打赏作者

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

抵扣说明:

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

余额充值