【IoT】红外循迹避障小车

news2024/10/10 4:25:50

说明

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

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

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

本设计通过小车这个载体再结合由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);
		}

		
		}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/190806.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Unity开发入门吐血反思

年前Team Leader开会时曾说道&#xff0c;以后我们可能都要去参与Unity开发&#xff0c;当时我还兴致勃勃一连提了好几个问题&#xff0c;有没有领路人&#xff0c;文档是否充分等等&#xff0c;毕竟做Android之余多掌握门技术也不错&#xff0c;学到的就是赚到的&#xff0c;技…

倚天剑第一式——爬虫基础

博主简介&#xff1a;博主是一个大二学生&#xff0c;主攻人工智能领域研究。感谢缘分让我们在CSDN相遇&#xff0c;博主致力于在这里分享关于人工智能&#xff0c;C&#xff0c;python&#xff0c;爬虫等方面的知识分享。如果有需要的小伙伴&#xff0c;可以关注博主&#xff…

Docker部署ThingsBoard-Gateway ODBC数据上传(五)

目录 1、linux系统安装Docker 1.docker安装Python 2.安装ODBC包 2、docker安装运行tb-gateway 3、修改config配置文件 4、 安装ODBC驱动程序 5、重启docker 因为需要数据库ODBC数据上传&#xff0c;所以我选择单独部署在远程服务器的docker容器中。其原理大致是这样的&…

在中国市场,OATLY燕麦奶依靠什么成为“标杆品牌”?

在中国新茶饮赛道异常拥挤、新品类层出不穷的局面下&#xff0c;OATLY作为一个来自瑞典的品牌&#xff0c;仅用3年时间&#xff0c;不仅顺利通过国外食品饮料品牌进军中国市场九死一生的惨烈考验&#xff0c;而且凭借其主打产品燕麦奶&#xff0c;成功在中国市场缔造了一个全新…

CameraX + MLKit 打造超简单 OCR 方案

前言 疫情期间隔三差五就要做核酸&#xff0c;随时都要准备身份证给大白扫描识别。写一篇文章聊聊其中用到的技术吧&#xff0c;顺道缅怀这段难忘的经历&#xff0c;希望大家的生活彻底告别的疫情影响&#xff0c;早日回归正常&#xff01; 身份证扫描主要用到是文字识别技术&…

Java程序设计实验3 | 面向对象(上)

*本文是博主对Java各种实验的再整理与详解&#xff0c;除了代码部分和解析部分&#xff0c;一些题目还增加了拓展部分&#xff08;⭐&#xff09;。拓展部分不是实验报告中原有的内容&#xff0c;而是博主本人自己的补充&#xff0c;以方便大家额外学习、参考。 目录 一、实验…

2023软考软件设计师易混淆知识点~(5)

将2023上半年软考《软件设计师》易混淆知识点&#xff0c;分享给大家&#xff0c;快来跟着一起打卡学习吧&#xff01;易混淆点4:软件维护类型1、更正性维护:针对真实存在并已经发生的错误进行的维护行为。2、预防性维护:针对真实存在但还未发生的错误进行的维护。3、适应性维护…

物联网毕业设计项目选题:harmonyos鸿蒙系统开发智能小车案例-hi3861v100开发板-留言领源码

华清远见FS-Hi3861开发套件&#xff0c;支持HarmonyOS 3.0系统。开发板主控Hi3861芯片内置WiFi功能&#xff0c;开发板板载资源丰富&#xff0c;包括传感器、执行器、NFC、显示屏等&#xff0c;同时还配套丰富的拓展模块。开发板配套丰富的学习资料&#xff0c;包括全套开发教程…

洛谷 P2983 [USACO10FEB]Chocolate Buying S

这题其实不难&#xff0c;但时间复杂度是大难点 题目描述 Bessie and the herd love chocolate so Farmer John is buying them some. The Bovine Chocolate Store features N (1 < N < 100,000) kinds of chocolate in essentially unlimited quantities. Each type i o…

网络电缆有哪些类型,网络工程师必知!

在 21 世纪&#xff0c;理想的目标是完全消除网络电缆的使用&#xff0c;并生活在一个一切都以无线方式管理的世界中。没有电缆的困扰&#xff0c;管理服务器会容易得多&#xff0c;我们也不必浪费时间标记和跟踪数百条电缆。 在那个时候到来之前&#xff0c;我们一直坚持使用…

F623光猫超级管理员密码获取

中兴F623光猫超级管理员密码获取 ⚠️事前说明 如果你不熟悉光猫的操作&#xff0c;请勿修改或拆解任何与光猫有关的命令、零件、网线等。操作有风险&#xff0c;运行需谨慎。 光猫型号&#xff1a;ZXHN F623 所属运营商&#xff1a;中国移动 硬件版本号&#xff1a;V6.0 …

算法刷题打卡第77天:解密消息

解密消息 难度&#xff1a;简单 给你字符串 key 和 message &#xff0c;分别表示一个加密密钥和一段加密消息。解密 message 的步骤如下&#xff1a; 使用 key 中 26 个英文小写字母第一次出现的顺序作为替换表中的字母 顺序 。 将替换表与普通英文字母表对齐&#xff0c;…

模型量化I—基础概念

最近接了个模型量化的任务&#xff0c;读了几篇比较新的论文&#xff0c;并跑通了几个模型。因为第一次接触这个领域&#xff0c;没有理论基础打底&#xff0c;直接读“大成”性的论文&#xff0c;常常有种云山雾罩的感觉&#xff0c;如空中楼阁&#xff0c;不知道每个结论的来…

java常用类: String,StringBuffer和StringBuilder

java常用类型: Ineteger等包装类 String类&#xff0c;StringBuffer类和StringBuilder类 Math类及常用方法 System类及常用方法 Arrays类及常用方法 BigInteger类和BigDecimal类及常用方法 日期类Date类,Calender类和LocalDateTime类 文章目录String介绍String创建细节String s…

转投高通平台,大众展露主导自动驾驶的野心

/ 导读 /2022年&#xff0c;英特尔几乎以亏本的价格推动Mobileye上市&#xff0c;成为市场上的一大看点。出现这种情况的原因&#xff0c;除了整个美国自动驾驶大环境不好&#xff0c;和Mobileye接连失去几个大客户不无关系。其中尤以大众这样体量的客户对于Mobileye的影响最为…

Ubuntu 系统如何以 root 用户SSH登录实例

文章目录前言总结前言 出了点小插曲&#xff0c;心情烦躁&#xff0c;搞得Ubuntu都连不上了&#xff0c;心态炸裂。 不过后面冷静下来以后还是找到了解决办法&#xff0c;可以用ssh成功连上root权限的Ubuntu。 因为很少接触Ubuntu&#xff0c;所以不知道即使root的密码正确…

09技术太卷我学APEX-定制页面及导航菜单权限

09技术太卷我学APEX-定制页面及导航菜单权限 0 始终没搞明白APEX的角色如果分配页面的权限&#xff0c;只能自己定制一个 APEX现学现卖开发了个《5217仓库管理》&#xff0c;功能在春节前就搞定了&#xff0c;卡在对页面的权限控制&#xff0c;经过翻阅牛人的博客&#xff0c…

使用vue3,vite,less从零开始学习硅谷外卖.docx

严正声明&#xff01; 重要的事情说三遍&#xff0c;本文章仅供分享&#xff0c;文章和代码都是开源的&#xff0c;严禁以此牟利&#xff0c;严禁侵犯尚硅谷原作视频的任何权益&#xff0c;我知道学习编程的人各种各样的心思都有&#xff0c;但这不是你对开源社区侵权的理由&am…

读书:《高效的秘密》

#《高效的秘密》的作者是《纽约时报》商业调查记者查尔斯都希格&#xff0c;他的另一本畅销书是《习惯的力量》。 高效不是超额工作、拼命工作&#xff0c;甚至牺牲自己的个人生活。高效的秘密取决于你做选择的方式。 一、激发动力&#xff0c;重新审视效率产生的源头 掌控力…

1.7 Cubemx STM32F429_RTX FATFS 库函数讲解(三)

文章目录1、打开文件夹2、读取文件夹3、打开\新建一个文件5、读取文件1、打开文件夹 FRESULT f_opendir ( DIR* DirObject, /* Pointer to the blank directory object structure */ const TCHAR* DirName /* Pointer to the directory name */ ) 函数说明: 此函数可以打开…