📄 main.c
字号:
/***********************************************************************/
/* 文件名 :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 + -