⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 智能小车c程序.txt

📁 mage16 brainpower vehile
💻 TXT
字号:

#include <intrins.h>						 
#include <AT89X52.h>
/********************************************************************************\
**                         			宏定义区									**
\********************************************************************************/

/*-------------------------------  LCD模块 ------------------------------------*/
#define LCD_RW  			P2_6 				//读写控制端
#define LCD_RS  			P2_7					//数据命令选择端
#define LCD_E   			P2_5					//执行使能端
#define LCD_Data			P1  					//P1口
#define Write				0x00					//低电平写入
#define Read				0x01					//高电平读出
#define Data				0x01					//高电平选择数据
#define Cmd				0x00					//低电平选择命令

#define Enable			0x00					//跃变到低电平时执行命令
#define Disable			0x01    
#define True				0x01
#define False				0x00
#define LCD_Init			0x38					//初始化模式							
#define LCD_DispCtr    		0x0C					//开显示及光标设置
#define LCD_CloseCtr		0x08					//关显示
#define LCD_CLS        		0x01					//清屏幕
#define LCD_EnterSet   		0x06					//显示光标 
#define Busy				P1_7					//忙信号

/*--------------------------  测速/测距/测时模块 -------------------------------*/
#define CircleLength		0.132				//小车转一轮的长度为.132m

/*--------------------------------  控速模块 -----------------------------------*/
#define P03				P0_3	   				//后电机
#define P04				P0_4	  				//后电机
#define P01  				P0_1	   				//前电机
#define P02				P0_2	   				//前电机
#define P31				P0_5       			//控制液晶背光
#define P33				P3_3

/*------------------------------  菜单选择模块	---------------------------------*/
#define Line				0x00					//0代表直线模式
#define Curve				0x01					//1代表S型模式
#define Normal			0x00					//0 代表正常速度
#define Low				0x01					//1 代表低速
#define High				0x02					//2 代表高速

/*********************************************************************************\
**							  全局函数声明区      						  **
\*********************************************************************************/

/*-------------------------------  LCD模块 -------------------------------------*/
void LCDInit(void);								//LCD初始化
void SetWriteCmd(void);								//设置写命令模式
void SetReadCmd(void);								//设置读命令模式
void SetWriteData(void);							//设置写数据模式
void WriteCmd(char cmd);							//写命令
void WriteData(char ddata);							//写数据
void ExecuteCmd(void);								//执行命令
void SetXY(char x,char y);							//定位显示地址
void DisplaySingleChar(char x,char y,char cchar);		//显示单个字符
void DisplayString(char x,char y,char *str); 			//显示一段字符串
void Delay(unsigned int time);						//延时主程序
void DelayUs(unsigned int time);						//延时子程序
bit  IsBusy(void);									//判断忙标志函数
void DisplayTime(void);								//显示时间
void DisplayAVGSpeed(void);							//显示平均速度
void DisplayDistance(void);							//显示路程

/*--------------------------  测速/测距/测时模块 -------------------------------*/					 	
void INTInit(void);				          		//所有中断初始化
void SpeedINT(void);					   			//测速中断
void ComputeTime(void);
void ComputeSpeedANDDistance(void);					//计算速度和距离

/*--------------------------------  控速模块 -----------------------------------*/
void CtrSpeedINT(void);            		 			//控速中断
void Time0INT(void);	  
void Time1INT(void);				       			//控速单位时间中断
void Clock0_Init(void);								//时钟中断初始化
void Clock1_Init(void);             	   				//时钟中断初始化
void CtrSpeed(void);

/********************************************************************************\
**                  			   全局变量区									**
\********************************************************************************/

float  SpeedCount = 0;			      				//测速计数脉冲
float  Speed = 0.0;							
float  Distance = 0.0;                 			
char   Time1INTCount=0;								//T1中断时间计时
float  PassTime=0.00;								//小车行走的时间
short  IsT0INT=1;									
bit	   IsT1INT;									//判断T1是否已经响应中断
short  IsT0INT2=1;

char   Thx[5]={0xf4,0xf4,0xc5,0xf4,0xff};		    		//3ms,3ms,15ms,3ms
char   Tlx[5]={0x48,0x48,0x68,0x48,0xff};			
char   Thx0=0xd8;
char   Tlx0=0xf0;
char   Thx1=0xb1;					 				//20ms
char   Tlx1=0xe0;


short  Round=0;
short  Back=0;
short  Back0=0;
bit    Backid;
bit    Stop=0;

char   Area0=0;
char   Area1=0;									//区域变量

char   LowSpeedArea1StartTime;
char   LowSpeedArea1EndTime;
char   HighSpeedAreaEndTime;
char   LowSpeedArea2EndTime;
char   LowSpeedArea1PassTime=0; 						//第一个低速区通过时间
char   HighSpeedAreaPassTime=0;						//高速区通过时间
char   LowSpeedArea2PassTime=0;						//第二个低速区通过时间
char   ReadyToGo=4;								//倒计时

char   flag;
bit    Roundid=0;
char   Nocurve=0; 
char   ChangeFlag;
char   Mode; 

bit    Running;
bit    SelectedAll;								//模式和速度是否选择完毕标志
bit	  IsSelectingMode;								//模式选择标志
bit	  IsSelectingSpeed;							//速度选择标志
bit    ModeSelected;								//已经被选择的模式标志
char   SelectedMode=10;								//模式选择是否完毕标志
bit    Next;										//Next键标志
bit    SpeedSelected;								//已经被选中的速度方案标志
char   SelectedSpeed;								//速度选择是否完毕标志

bit    ChoosingDisplay;								//人工选择菜单开始标志
bit    SelectedShow;								//显示选择标志
bit	  SelectedReturn;								//返回选择标志
bit    Selected;									//确定/返回键选择标志
bit    ReturnSelection;								//返回键启用标志
bit    AVGSpeedShow;								//平均速度显示标志
bit    TotalDistanceShow;							//总路程显示标志
bit    ReturnMain;									//返回主菜单标志

bit    AutoDisplay;								//自动显示标志
bit    GoToChoosingDisplay;							//人工选择标志

bit    AutoMode=0;
char   PassLineID=0;
char   PassLine=0;
float  PrepareDistance;
float  FirstDistance;
float  SecondDistance;
float  ThirdDistance;
int    FirstHigh;
int    SecondHigh;
int    ThirdHigh;
float  Rate=1.25;   								//5ms时的速度
float  Count=4;									//时间的倍数


/*-------------------------------------    延时函数  -------------------------------------*/
void Delay(unsigned int time)
{
    unsigned int timeCounter = 0;
	for (timeCounter = time;timeCounter > 0 ;timeCounter --)
		DelayUs(255);
}

void DelayUs(unsigned int time)
{
	unsigned int timeCounter = 0;
	for (timeCounter = 0;timeCounter < time;timeCounter ++)
		_nop_();
}






/*-------------------------------------  中断初始化  -------------------------------------*/

void INTInit(void)
{						
	EA=1;									  //开总中断
	IT0=1;									  //INTO边沿触发
	PX0=1;          							  //INTO优先级为高级
	EX1=1;									  //开INT1中断
	IT1=1;									  //INT1边沿触发
	PX1=1;          							  //INT1优先级为高级
	Clock0_Init();                 				  //初始化时钟中断
	TMOD=0x11;								  //T0/T1定时方式1
	ET0=0x01;      							  //开T0中断
	ET1=0x01;     							  //开T1中断
}

void Clock0_Init(void)
{
	TR0=0x01;       							  //启动T0
	TH0=Thx0;								       //定时初值
	TL0=Tlx0;

}
void Clock1_Init(void) 
{
	TR1=0x01;      							  //启动T1
	TH1=0x3C;									  //定时初值-50ms中断一次
	TL1=0x0B0;
}

/*******************************************************************************************\
**									   中断处理程序                                  **
\*******************************************************************************************/

/*-----------------------------------   外部中断0 ----------------------------------------*\

	外部中断0有两个功能
	(1)作为菜单选择的Next键
	(2)作为测速的计数器

\*-----------------------------------------------------------------------------------------*/
void SpeedINT(void) interrupt 0 			 //中断INT0
{
	if (SelectedAll==False)				//如果模式和速度还没有选择完毕,则此中断作为Next键
		Next=True;									
	if (Running==True)					 //如果模式和速度已经选择完毕,则此中断作为测速中断
		SpeedCount++;
	if (ChoosingDisplay==True)			//如果是在选择要显示的内容
		Next=True;	 	 	
}




/*-----------------------------------   外部中断1 ----------------------------------------*\

	外部中断1有两个功能
	(1)作为菜单选择的确定键/返回键
	(2)控速

\*-----------------------------------------------------------------------------------------*/
void CtrSpeedINT(void) interrupt 2     		      //中断INT1
{			      
	
	if (SelectedAll==False)					//如果模式和速度还没有选择完毕,则此中断作为确定键
	{
		if (IsSelectingMode==True)				  //模式选择标志
				ModeSelected=True;
		if (IsSelectingSpeed==True)				  //速度选择标志
				SpeedSelected=True;
	}

	if (Running==True)					 //如果模式和速度选择已经完毕,则此中断作为控速中断
	{
		if (Area0==0)					//经过第一条铁线(即起跑线),开始计时,开始测速
		{
			EX0=1;
			Clock1_Init();
	 		P31=0;								  //过起跑线,背光灭
		}
		if (Area0==1)
			LowSpeedArea1StartTime=PassTime;    //读取进入第一个低速区的时刻
		if (Area0==2)
			LowSpeedArea1EndTime=PassTime;//读取离开第一个低速区的时刻,也就是进入高速区的时刻
		if (Area0==3)
			HighSpeedAreaEndTime=PassTime;//读取离开高速区的时刻,也就是进入第二个低速区的时刻
		if (Area0==4)
			LowSpeedArea2EndTime=PassTime;       //读取离开第二个低速去的时刻
		
		if(AutoMode==1)			  				  //自动模式
		{  
		   	PassLine++;
		   	switch(PassLine)
		   	{
				case 5  :PassLineID=1;break;
		    	case 10 :PassLineID=2;break;
				default :PassLineID=PassLineID;break;
	  		}
		} 	 
		else										  
		{
			if (SelectedMode==Line)		      	  //直线模式
			{
				Thx0=Thx[Area0++];
				Tlx0=Tlx[Area1++];
				if (Area0==5)
					EX1=0;
			}
			else							 	  //S型模式
			{
				Nocurve++;
			    Round++;
			    if(Roundid==1&&Round==2)
			   		{Round++;Roundid=0;}
				Back=0;
				Back0=0;
				EX1=0;
			}
		}
		IE1=0;
	}
	if (AutoDisplay==True)
	{
		GoToChoosingDisplay=True;
	}
	if (ChoosingDisplay==True)
	{
		SelectedShow=True;
		SelectedReturn=True;
		Selected=True;
	}
}
/*--------------------------------------   T0中断 ----------------------------------------*\

	T0中断用来输出方波以控制速度

\*-----------------------------------------------------------------------------------------*/
 void Time0INT(void) interrupt 1 		         //T0中断
{  
	if(AutoMode==1)
    {
		IsT0INT*=-1;
	   	switch(PassLine)
	   	{   case 2  :PrepareDistance=Distance;break;
	    	case 3  :FirstDistance=Distance-PrepareDistance;break;
		    case	4  :SecondDistance=Distance-PrepareDistance-FirstDistance;break;
		    case 5  :ThirdDistance=Distance-PrepareDistance-FirstDistance-SecondDistance;break;
		    default :break;
	    } 
	    switch(PassLineID)
	    {  
			 case 0  :{
			 			 if(IsT0INT==1)
				    		 {TR0=0x01;TH0=0xec;TL0=0x78;}	       //5ms
			       	     else
				  	      	 {TR0=0x01;TH0=0xb1;TL0=0xe0;}	  //20ms
				      }break;
		     case 1  :{ 
		   				 if(PassLine==5)
		              	 {	
							 FirstHigh=(int)(65536-20*FirstDistance/(15*Count*Rate-FirstDistance)*1000);
							 SecondHigh=(int)(65536-20*SecondDistance/(15*Rate-SecondDistance)*1000);
							 ThirdHigh=(int)(65536-20*FirstDistance/(15*Count*Rate-FirstDistance)*1000);
							 TR0=0x01;TH0=0xf4;TL0=0x48;
					     }                    
		              }break;
		     case 2  :{
			 			  AutoMode=0;SelectedMode=Line;Area0=Area1=0;PassTime=0;Distance=0;
		             	  TR0=0x01;TH0=0xf4;TL0=0x48;
		                  Thx[0]=Thx[1]=((FirstHigh & 0xf0)>>8);Tlx[0]=Tlx[1]=(FirstHigh & 0x0f);
					      Thx[2]=Thx[2]=((SecondHigh & 0xf0)>>8);Tlx[2]=Tlx[2]=(SecondHigh & 0x0f);
					      Thx[3]=Thx[3]=((ThirdHigh & 0xf0)>>8);Tlx[3]=Tlx[3]=(ThirdHigh & 0x0f);
					      Thx[4]=Thx[4]=0xff;Tlx[4]=Tlx[4]=0xff; 
		              }break;
		     default :break;
	    }
    }
	else
	{
			if (SelectedMode==Line)
			{
				IsT0INT*=-1;
			    if (Area0<5)	
				{
					if(IsT0INT==1)
				   		Clock0_Init();
				 	else
				    {
				   		TR0=0x01;       			  //启动T0
				    	TH0=Thx1;						  //定时初值
				    	TL0=Tlx1;						    
				    } 
				}
				else 
					IsT0INT=-1;
			}
			else
			{ 	
				IsT0INT2*=-1;
			    if(IsT0INT2==1)
				  	{TR0=0x01;TH0=0xd8;TL0=0xf0;}	       //10ms
				else
				  	{TR0=0x01;TH0=0xb1;TL0=0xe0;}	       //20ms
				Back++;
				if(Back>=90)
				    Back0=70;
				
				if((Nocurve<2)&&(Back0>0)&&Back!=0)
				    {  
						if(Back0<=65)
					    Roundid=1;
					  	Back0--;
					}
				if((Nocurve>2)&&Back>=450)
					{Stop=1;IsT0INT2=-1;}
				if(Stop==1)
				    flag=6;
				  	  		  
			}
	}	
	TF0=0;	
}												 
/*-----------------------------------     T1中断  ----------------------------------------*\
	T1中断用来定时
\*-----------------------------------------------------------------------------------------*/

void Time1INT(void) interrupt 3 				          //T1中断
{
	Clock1_Init();
	Time1INTCount++;							 
	if (Time1INTCount == 10)						 //500ms扫描一次
	{
		IsT1INT=1;
		if (Area0>5)
			P03=0;
		Time1INTCount=0;	
	}
	TF1=0;	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -