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

📄 main.c

📁 AT89C51 I2C接口通信程序例程.rar
💻 C
📖 第 1 页 / 共 2 页
字号:
/***********************************************************************/
/* 文件名  :main.c
/* 芯片    :Atmel AT89C51
/* 作者	   :Ericson
/* 日期	   :2007.11.15
/* 功能描述:走纸影像靶集中控制系统主程序。

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

//***********************************************************************
//包含头文件
#include "I2C.h"

//***********************************************************************
//宏定义
#define BUFFER_LENGTH		6			//串行命令帧长度
#define	UART_MESGFLAG		0xA1		//接收消息开始字节

//串行口指令码定义
//控制码由主机发至控制箱,标识码由控制箱发至主机,数据码用于携带数据信息
#define MOTO_RUN			0x0001		//电机运行控制码
#define MOTO_STATER			0x0002		//读取当前电机运行状态
#define MOTO_CFGR			0x0003		//读取电机单步运行时间
#define IRLED_CFGR			0x0004		//读取红外灯亮度
#define IRLED_ON			0x0005		//红外灯打开
#define IRLED_OFF			0x0006		//红外灯关闭
#define NVM_RESET			0x0007		//复位E2PROM
#define MOTO_CFGM			0x0008		//修改电机单步运行时间
#define IRLED_CFGM			0x0009		//修改红外灯亮度

//辅助命令
#define MOTO_RUNALLTIME		0x000A		//使电机一直走
#define MOTO_STOPALLTIME	0x000B		//强制电机停止
#define MOTO_ALTERSTATE		0x000C		//强制改变状态

//反馈命令
#define MOTO_STOP			0x8001		//电机停止
#define MOTO_STATERFB		0x8002		//电机当前运行状态
#define	MOTO_CFGRFB			0x8003		//电机配置信息读取
#define IRLED_CFGRFB		0x8004		//红外灯亮度数据
#define POS_INDICATOR		0x8005		//到位信息有效
#define SIG_INDICATOR		0x8006		//射击信息有效
#define INIT_SUCCESS		0x8007		//系统初始化成功

//电机状态定义
//状态字节定义:FR ** ** ** ** ** MR ML
#define MOTO_FIRSTRUN		0x80
#define MOTO_MOVL			0x01		
#define MOTO_MOVR			0x02

#define MOTO_PRERUN_TIME	1000					//电机预走纸时间
#define DEFAULT_MOTOSTATE	0x02					//电机缺省向右转动
#define DEFAULT_MOTOCYCLE	100						//电机缺省按单步运行100ms
#define DEFAULT_IRLEDLIGHT  128						//红外发光管缺省亮128

#define	NVM_CONTROL			0xA0					//AT24C32控制字节为1010 0000
#define NVM_MOTOSTATE_ADDR	0x0000					//电机当前状态地址
#define NVM_MOTOCYCLE_ADDR	NVM_MOTOSTATE_ADDR+1	//电机单步运行时间地址
#define NVM_IRLEDLIGHT_ADDR NVM_MOTOSTATE_ADDR+2	//红外发光管亮度

//***********************************************************************
//端口定义
sbit	MANUALR = P1^2;         //纸带右移手动操作输入端口
sbit  	MANUALL = P1^3;			//纸带左移手动操作输入端口
sbit	LEDR    = P1^4;			//纸带右移LED显示
sbit	LEDL	= P1^5;			//纸带左移LED显示
sbit	UARTCTRL= P1^7;			//RS485收/发控制端口
sbit	MOTO	= P2^0;			//电机互锁控制:0--左电机,1--右电机
sbit	MOTOCTL	= P2^1;			//电机信号输出控制:0--信号有效,1--信号无效
sbit	CLUTHCTL= P2^2;			//离合器信号输出控制:0--信号有效,1--信号无效
sbit	CLUTH	= P2^3;			//离合器互锁控制:0--左离合器,1--右离合器
sbit	LEDCTL1	= P2^4;			//红外照明灯控制:0--打开红外照明设备
								//				  1--关闭红外照明设备
//sbit	LEDCTL2 = P2^5;         //红外照明灯控制:0--打开红外照明设备
								//				  1--关闭红外照明设备(备用)
//sbit	TEST1 	= P2^6;			//测试端口(备用)
//sbit	TEST2	= P2^7;			//测试端口(备用)
sbit	PINT0	= P3^2;			//外部中断0端口
sbit	PINT1	= P3^3;			//外部中断1端口
sbit	MODESIG	= P2^6;			//用于模式信号输出,方便操作
sbit	MODECTL = P2^7;         //模式控制端口,用于屏蔽手动工作,0--手动,1--自动

//***********************************************************************
//全局变量定义
uchar	T0Counter = 0,T0Counter1 = 0,T0Counter2 = 0,T1Counter = 0;
uchar	T0Flag1 = 0,T0Flag2 = 0;
bit		POS_TimeOut = 0,SIG_TimeOut = 0;
bit		POSFlag = 0,SIGFlag = 0,MODEFLAG = 0;

bit UARTFlag = 0;
uchar rlength = 0;
uchar checksum = 0;
uchar RcvBUF[BUFFER_LENGTH];
uchar TrxBUF[BUFFER_LENGTH];

struct NVMConfig
{
	uchar MotoState;					//状态字节定义:FR ** ** ** ** ** MR ML
	uchar MotoRunCycle;					//电机当前单步运行时间
	uchar IRLEDLight;					//红外灯当前亮度
} CurConfig;

//***********************************************************************
//局部函数声明
void Delay_nms(uint n);					//nms定时子程序
bit  UART_SendStr(uchar *str,uchar len);//串行口发送一个字符串函数

void System_Init(void);					//系统初始化程序
void System_SetMoto(void);				//电机、离合器状态初始化函数
void System_ExchangeMoto(void);			//电机、离合器状态切换函数
void System_MotoRun(uint time);			//系统电机运行函数
void System_SendCommand(uint comid);	//系统反馈当前信息函数
void System_ParseCommand(void);			//系统解析当前信息函数

//***********************************************************************
//主函数
void main(void)
{ 	 
	uchar Temp;
	System_Init();				//系统初始化
	EA = 0;						//关闭中断
	if( NVM_ReadB(NVM_CONTROL,NVM_MOTOSTATE_ADDR,&Temp) )
	{	//读取当前电机状态
		if(Temp&MOTO_FIRSTRUN)	//如果设备第一次运行
		{							
			CurConfig.MotoState = DEFAULT_MOTOSTATE;	//初始化电机状态
			CurConfig.MotoRunCycle = DEFAULT_MOTOCYCLE;	//电机缺省单步运行时间100ms
			CurConfig.IRLEDLight = DEFAULT_IRLEDLIGHT;	//红外灯缺省亮度		
			NVM_WriteStr(NVM_CONTROL,NVM_MOTOSTATE_ADDR,(uchar *)(&CurConfig),3);
		}
		else					//如果不是第一次运行
		{	//读取EEPROM内各配置信息
			NVM_ReadStr(NVM_CONTROL,NVM_MOTOSTATE_ADDR,(uchar *)(&CurConfig),3);
		}
	}
	else
	{
		Temp = 0x00;
		//EEPROM读数错误处理代码
	}
	EA = 1;
	System_SetMoto();					//根据读取的状态内容设定电机和离合器工作方式
	System_MotoRun(MOTO_PRERUN_TIME);	//系统启动后根据状态值预运行
	System_SendCommand(INIT_SUCCESS);	//向主机反馈系统初始化成功

	//系统进入等待状态
	while(1)
	{
		TR0 = MODECTL;			//MODECTL = 1,手动有效;否则无效
		if(T0Flag1 == 1)		//电机手动右转有效
		{
			EA = 0;
			CLUTH = 1;			//离合器2吸合
			CLUTHCTL = 0;		//打开离合器屏蔽端口
			Delay_nms(10);		//定义在I2C.h,等待离合器吸合
			MOTO = 1;			//电机2吸合
			MOTOCTL = 0;		//打开电机屏蔽端口
			LEDR = 0;
			EA = 1;
			T0Flag1 = 2;
		}
		if(T0Flag1 == 3)		//电机手动右转结束
		{
			EA = 0;					
			MOTOCTL = 1;		//关闭电机屏蔽端口
			LEDR = 1;
			EA = 1;
			T0Flag1 = 0;
			System_SetMoto();	//恢复到自动运行状态
		}
		if(T0Flag2 == 1)		//电机手动左转有效
		{
			EA = 0;
			CLUTH = 0;			//离合器1吸合
			CLUTHCTL = 0;		//打开离合器屏蔽端口
			Delay_nms(10);		//定义在I2C.h,等待离合器吸合
			MOTO = 0;			//电机1吸合
			MOTOCTL = 0;		//打开电机屏蔽端口
			LEDL = 0;
			EA = 1;
			T0Flag2 = 2;
		}
		if(T0Flag2 == 3)		//电机手动左转结束
		{
			EA = 0;					
			MOTOCTL = 1;		//关闭电机屏蔽端口
			LEDL = 1;
			EA = 1;
			T0Flag2 = 0;
			System_SetMoto();	//恢复到自动运行状态
		}
		if(POSFlag == 1)	    //如果到位信息有效
		{				
			System_ExchangeMoto();	//电机改变运行状态
			EA = 0;
			NVM_WriteB(NVM_CONTROL,NVM_MOTOSTATE_ADDR,CurConfig.MotoState);	//更新EEPROM
			EA = 1;
			System_SendCommand(POS_INDICATOR);		//反馈电机到位信息
			POSFlag = 0;
		}										
		if(SIGFlag == 1)		//如果射击信息有效				
		{ 
			//添加射击传感器接收信号代码
			System_SendCommand(SIG_INDICATOR);		//反馈电机到位信息
			SIGFlag = 0;
		}
		if(UARTFlag == 1)		//收到串口指令有效
		{
			System_ParseCommand();					//处理串口指令
			UARTFlag = 0;
		}
	}
}

//***********************************************************************
//系统初始化程序
void System_Init(void)
{
	uchar index;
	
	TMOD = 0x23;	//定时器0工作在模式3定时方式,受TR0,TR1控制,定时器1用于串行口波特率发生器
	TCON = 0x05;	//外部中断INT0、INT1工作在脉冲触发方式
	TH1	= 0xFD;		//串行口波特率为9600bps
	TL1	= 0xFD;
	SCON = 0x50;	//串行口工作在方式1,允许接收
	PCON = 0x00;	//SMOD = 0;
	TH0	= 0x00;
	TL0	= 0x00;
	IE = 0x9F;		//开启所有中断
	IP = 0x15;		//INT0、INT1、UART优先级为1,定时器0、1为0	
	UARTCTRL = 0;	//RS485接口处在接收状态
	MOTOCTL = 1;
	CLUTHCTL = 1;
	MODESIG = 0;	//用于模式控制的信号输入
	for(index = 0;index<BUFFER_LENGTH;index++)
	{				//初始化串行口缓冲区
		RcvBUF[index] = 0;
		TrxBUF[index] = 0;
	}
}

//***********************************************************************
//电机、离合器状态初始化函数
//State : FR ** ** ** ** ** MR ML
void System_SetMoto(void)
{
	uchar Temp = CurConfig.MotoState;
	if(Temp&MOTO_MOVL)		//如果ML=1,离合器1吸合
	{
		EA = 0;
		CLUTH = 0;			//离合器1吸合
		CLUTHCTL = 0;		//打开离合器屏蔽端口
 	    EA = 1;
	}
	else if(Temp&MOTO_MOVR)	//如果MR=1,离合器2吸合
	{
		EA = 0;
		CLUTH = 1;			//离合器2吸合
		CLUTHCTL = 0;		//打开离合器屏蔽端口
		EA = 1;
	}
	else
	{
		////添加系统出错代码
	}
}


//***********************************************************************
//系统电机运行函数
void System_MotoRun(uint time)
{
	uchar Temp = CurConfig.MotoState;
	if(Temp&MOTO_MOVL)		//如果ML=1,电机1吸合
	{
		EA = 0;
		MOTO = 0;			//电机1吸合			
		MOTOCTL = 0;		//打开电机屏蔽端口
		LEDL = 0;
		EA = 1;
		if(time == 0)		
			return ;		//时间为零则一直走纸
		else
			Delay_nms(time);//延时100ms
		EA = 0;
		MOTOCTL = 1;		//关闭电机屏蔽端口
		LEDL = 1;
		EA = 1;
	}
	else if(Temp&MOTO_MOVR)	//如果MR=1,电机2吸合
	{
		EA = 0;
		MOTO = 1;			//电机2吸合			
		MOTOCTL = 0;		//打开电机屏蔽端口
		LEDR = 0;
		EA = 1;
		if(time == 0)
			return ;		//时间为零则一直走纸
		else
			Delay_nms(time);//延时100ms
		EA = 0;
		MOTOCTL = 1;		//关闭电机屏蔽端口
		LEDR = 1;
		EA = 1;
	}
	else
	{
		//添加系统出错代码
	}
}

//***********************************************************************
//系统电机停止函数
void System_MotoStop(void)
{	
	EA = 0;
	MOTOCTL = 1;		//关闭电机屏蔽端口
	LEDL = 1;
	LEDR = 1;
	EA = 1;
}

//***********************************************************************
//电机、离合器状态切换函数
//State : FR ** ** ** ** ** MR ML
void System_ExchangeMoto(void)
{
	uchar Temp = CurConfig.MotoState;	
	if(Temp&MOTO_MOVL)		//如果ML=1,电机2吸合
	{
		EA = 0;
		CLUTH = 1;			//离合器2吸合
		CLUTHCTL = 0;		//打开离合器屏蔽端口
		EA = 1;
	
		Temp = MOTO_MOVR;	//更新电机状态
	}
	else if(Temp&MOTO_MOVR)	//如果MR=1,电机1吸合
	{
		EA = 0;
		CLUTH = 0;			//离合器1吸合
		CLUTHCTL = 0;		//打开离合器屏蔽端口
		EA = 1;
	
		Temp = MOTO_MOVL;	//更新电机状态
	}
	else
	{
		//添加系统出错代码
	}
	
	CurConfig.MotoState = Temp;
}

//***********************************************************************
//系统反馈当前信息函数,包括:走纸到位信息,射击有效信息,系统初始化成功信息。
//							  

⌨️ 快捷键说明

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