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

📄 main.c

📁 AT89C51 I2C接口通信程序例程.rar
💻 C
📖 第 1 页 / 共 2 页
字号:
void System_SendCommand(uint comid)
{
	uchar check = 0,index;
	
	TrxBUF[0] = UART_MESGFLAG;				//起始字节
	
	TrxBUF[2] = (uchar)(comid&0xFF);		//指令码2
    
	TrxBUF[1] = (uchar)((comid>>8)&0xFF);	//指令码1
	
	TrxBUF[3] = 0x00;						//数据码1
	
	switch(comid)
	{
		case MOTO_CFGRFB : 	//如果是电机配置信息读取数据
			
			TrxBUF[4] = CurConfig.MotoRunCycle;
			
			break;

		case IRLED_CFGRFB : //如果是红外灯配置信息读取数据
			
			TrxBUF[4] = CurConfig.IRLEDLight;
			
			break;

		case MOTO_STATERFB ://如果是电机状态信息读取数据
			
			TrxBUF[4] = CurConfig.MotoState;

			break;
			
		default :			//其他为0x00 
			
			TrxBUF[4] = 0x00;

			break;
	}
	
	for(index = 0;index<BUFFER_LENGTH-1;index++)
		
		check += TrxBUF[index];
	
	TrxBUF[BUFFER_LENGTH-1] = check;
	
	UART_SendStr(TrxBUF,BUFFER_LENGTH);
}

//***********************************************************************
//系统解析当前信息函数
void System_ParseCommand(void)
{
	uint comid;
	uchar temp;
	
	comid = (uint)RcvBUF[2];
	comid += (((uint)RcvBUF[1])<<8);
	
	switch(comid)
	{
		case MOTO_RUN :			//如果是电机运行
			
			System_MotoRun((uint)CurConfig.MotoRunCycle);
			
			System_SendCommand(MOTO_STOP);			
			
			break;

		case MOTO_STATER :		//如果是读取电机当前状态
			
			System_SendCommand(MOTO_STATERFB);
			
			break;
		
		case MOTO_CFGR :		//读取电机单步运行时间
			
			System_SendCommand(MOTO_CFGRFB);
			
			break;
		
		case IRLED_CFGR :		//如果是读取红外灯亮度
			
			System_SendCommand(IRLED_CFGRFB);
			
			break;

		case IRLED_ON :			//如果是红外灯打开控制码
			
			LEDCTL1 = 0;
			
			break;
		
		case IRLED_OFF :		//如果是红外灯关闭控制码
			
			LEDCTL1 = 1;
			
			break;
		
		case NVM_RESET :		//如果是EEPROM复位控制码
			
		 	CurConfig.MotoState = DEFAULT_MOTOSTATE;	//初始化电机状态
			
			CurConfig.MotoRunCycle = DEFAULT_MOTOCYCLE;	//电机缺省单步运行时间100ms
			
			CurConfig.IRLEDLight = DEFAULT_IRLEDLIGHT;	//红外灯缺省亮度		
			
			NVM_WriteStr(NVM_CONTROL,NVM_MOTOSTATE_ADDR,(uchar *)(&CurConfig),3);

			System_SetMoto();
			
			break;
		
		case MOTO_CFGM :		//如果是修改电机单步执行时间
			
			temp = RcvBUF[4];

			CurConfig.MotoRunCycle = temp;
			
			NVM_WriteB(NVM_CONTROL,NVM_MOTOCYCLE_ADDR,temp);
			
			break;

		case IRLED_CFGM :		//如果是修改红外灯亮度
			
			temp = RcvBUF[4];
			
			CurConfig.IRLEDLight = temp;

			NVM_WriteB(NVM_CONTROL,NVM_IRLEDLIGHT_ADDR,temp);
			
			break;
		case MOTO_RUNALLTIME :	//如果是电机一直运行指令
			
			System_MotoRun(0);
			
			break;
		
		case MOTO_STOPALLTIME :	//如果是电机强制停止指令
			
			System_MotoStop();

			break;

		case MOTO_ALTERSTATE :	//如果是电机状态指令
			
			POSFlag = 1;
			
			break;

		default :  
			
			break; 
	}
}

//***********************************************************************
//串行口发送一个字符串函数
//参数说明:str -- 待发送的字符串首地址
//			len	-- 待发送的字符串长度,最大为250
bit UART_SendStr(uchar *str,uchar len)
{
	uchar index;
	if( len>BUFFER_LENGTH )   return(0);	//如果数据长度大于缓冲区长度
	UARTCTRL = 1;							//SN75176处于发送状态
	Delay_nms(1);							//延时,提高可靠性
	ES = 0;									//关闭串口中断
	for(index = 0;index<len;index++)
	{
		SBUF = *(str+index);
		while(TI == 0);
		TI = 0;
	}
	ES = 1;									//打开串口中断
	Delay_nms(1);							//延时,提高可靠性
	UARTCTRL = 0;							//重置75176于接收状态
}

//***********************************************************************
//nms定时子程序
void Delay_nms(uint n)
{
	uchar i;
	while(n--)
	{
	   for(i=0;i<99;i++)  {;}
	}
}

/*******************************中断服务程序****************************/

//***********************************************************************
//外部中断0服务子程序  
void XINT0(void) interrupt 0 using 2
{
	POS_TimeOut = 1;					//标识位置抗干扰侦测
	TH0	= 0x00;							//定时中断
	T1Counter = 0;						
	EX0 = 0;
	TR1 = 1;	
}

//***********************************************************************
//定时器0中断服务子程序,触发时间为278微秒
void Timer0(void) interrupt 1 using 1
{		
	bit Sample;	
	
	TL0 = 0x00;
	T0Counter++;
	if(T0Counter == 4)				//每1.1ms
	{
		if(T0Flag1 == 0)
		{
			Sample = MANUALR;
			if(Sample == 0)
			{
				T0Counter1++;
				if(T0Counter1>27)
				{
					T0Flag1 = 1;
					T0Counter1 = 0;
				}
			}
			else	T0Counter1 = 0;
		}
		
		if(T0Flag1 == 2)
		{
			Sample = MANUALR;
			if(Sample == 1)
			{
				T0Counter1++;
				if(T0Counter1>27)
				{
					T0Flag1 = 3;
					T0Counter1 = 0;
				}
			}
			else    T0Counter1 = 0;
		}
		
		if(T0Flag2 == 0)
		{
			Sample = MANUALL;
			if(Sample == 0)
			{
				T0Counter2++;
				if(T0Counter2>27)
				{
					T0Flag2 = 1;
					T0Counter2 = 0;
				}
			}
			else	T0Counter2 = 0;
		}
		
		if(T0Flag2 == 2)
		{
			Sample = MANUALL;
			if(Sample == 1)
			{
				T0Counter2++;
				if(T0Counter2>27)
				{
					T0Flag2 = 3;
					T0Counter2 = 0;
				}
			}
			else    T0Counter2 = 0;
		}

		T0Counter = 0;
	}
}

//***********************************************************************
//外部中断1服务子程序  
void XINT1(void) interrupt 2 using 2
{
	SIG_TimeOut = 1;					//标识位置抗干扰侦测
	TH0	= 0x00;							//定时中断
	T1Counter = 0;
	EX1 = 0;
	TR1 = 1;	
}

//***********************************************************************
//定时器1中断服务子程序,触发时间为278微秒
void Timer1(void) interrupt 3 using 1
{
	TH0 = 0x00;
	T1Counter++;
	if(T1Counter == 36)
	{
		T1Counter = 0;
		TR1 = 0;
		if(POS_TimeOut == 1)			//如果是到位检测延时触发
		{
			if(PINT0 == 0)	POSFlag = 1;
			POS_TimeOut = 0;
			EX0 = 1;
		}
		if(SIG_TimeOut == 1)			//如果是到位检测延时触发
		{
			if(PINT1 == 0)	SIGFlag = 1;
			SIG_TimeOut = 0;
			EX1 = 1;
		}	
	}
}

//***********************************************************************
//串行口接收函数,采用中断实现
void UART(void) interrupt 4 using 2
{
	uchar temp;
	if(RI&(!UARTFlag))
	{
		temp = SBUF;
		RI = 0;
		if(rlength == 0)
		{
			if(temp == UART_MESGFLAG)
			{
				RcvBUF[rlength] = temp;
				rlength ++;
				checksum = temp;
			}
			else
			{
				rlength = 0;
			}
		}
		else if(rlength == 5)
		{
			RcvBUF[rlength] = temp;
			if(((checksum^temp)==0))
				UARTFlag = 1;
			rlength = 0;
			checksum = 0;
		}
		else
		{
			RcvBUF[rlength] = temp;
			checksum += temp;
			rlength ++;
		}
	}
	if(TI)
	{
		TI = 0;
	}
}

//结束

⌨️ 快捷键说明

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