📄 serial.c
字号:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void TaskReceive(void)
{
uint8 code head[4] = {0xEB,0x90,0xEB,0x90};
OSQCreate(SerialInData,130); /* 建立所需要的消息队列 */
OSQCreate(SerialOutData,200);
while (1)
{
uint8 xdata state=0;
while (1)//识别报文头
{
if(head[state] == GetCharWithoutCheck())
state++;
else
state=0;
if(state==4)
break;
}//while (1)//识别报文头
rtn=RIGHT; /* 返回码置初值 */
inchk = 0xeb^0x90^0xeb^0x90; /* 初始化校验和 */
if(Address == GetCharWithCheck()) /* 如果地址正确则继续 */
{
uint8 data i;
uint8 xdata length;
cid = GetCharWithCheck();
length = GetCharWithCheck();
if (length>100)
{
length=100;
}
for (i=0;i<length;i++) // 接收数据区数据
{
buf[i]=GetCharWithCheck();
}
i = GetCharWithoutCheck();
if (inchk != i && i!=0x55) // 判断校验和 0x55 为不校验
{
rtn = CHKSUM_ERROR;
}
if (0x0d != GetCharWithoutCheck()) // 判断报文尾
{
rtn = TYPE_ERROR;
}
EN_485 = 0;
OSWait(K_TMO,(5*OS_TICKS_PER_SEC)/1000); //delay15ms
if(rtn==1)//如果报文的校验和,类型正确
{
CommCounter = 0;
switch (cid)
{
case 0: // 握手命令
{
CommSendInfo();
}break;
case 1: // 取电池数据信息
{
CommSendCellDataInfo();
}break;
case 2: // 工步设置
{
if(CurrentWorkStep ==0)//如果当前为停止状态则可以修改工步
{
SumWorkStep = buf[0];
if(SumWorkStep>12)
SumWorkStep=12;
for(i=1;i<=SumWorkStep;i++)
{
WorkStep[i].type = buf[(i-1)*9+2];
WorkStep[i].i = buf[(i-1)*9+3];
WorkStep[i].i = WorkStep[i].i <<8 ;
WorkStep[i].i = WorkStep[i].i | buf[(i-1)*9+4];
WorkStep[i].i *=10;
WorkStep[i].limit = buf[(i-1)*9+5];
WorkStep[i].limit = WorkStep[i].limit <<8 ;
WorkStep[i].limit = WorkStep[i].limit | buf[(i-1)*9+6];
WorkStep[i].limit *=10;
WorkStep[i].t = buf[(i-1)*9+7];
WorkStep[i].t = WorkStep[i].t <<8 ;
WorkStep[i].t = WorkStep[i].t | buf[(i-1)*9+8];
WorkStep[i].t *= 60;//换算成秒
WorkStep[i].u = buf[(i-1)*9+9];
WorkStep[i].u = WorkStep[i].u <<8 ;
WorkStep[i].u = WorkStep[i].u | buf[(i-1)*9+10];
WorkStep[i].u *= 10;
}
if( WorkStepCheck()==0 )//如果工步无效
{
rtn = DATA_ERROR;
}
CommSendInfo();
OSSemPend(IICSem,0);
EepromWriteByte(SumWorkStepIICBase,SumWorkStep);
for(i=1;i<=SumWorkStep;i++)
{
EepromWriteByte(WorkStepIICBase + i*9 + 0,WorkStep[i].type );
EepromWriteWord(WorkStepIICBase + i*9 + 1,WorkStep[i].i );
EepromWriteWord(WorkStepIICBase + i*9 + 3,WorkStep[i].limit);
EepromWriteWord(WorkStepIICBase + i*9 + 5,WorkStep[i].t );
EepromWriteWord(WorkStepIICBase + i*9 + 7,WorkStep[i].u );
}
OSSemPost(IICSem);
}
else//if(CurrentWorkStep ==0)//如果当前为停止状态则可以修改工步
{
rtn = LOGIC_ERROR;
CommSendInfo();
}
}break;
case 3:// 模块停止
{
CellCheckFlag = 0;
if(CurrentWorkStep>0)//CurrentWorkStep==0则系统众目停止
{
OSSemPost(StopWorkStepSem);
}
else
{
rtn = LOGIC_ERROR;
}
CommSendInfo();
}break;
case 4:// 分容
{
if(length==3)
{
if(CurrentWorkStep == 0)
{
i=buf[0];
if((bit)(i&1)) P4|=0x01; else P4&=0xFE; i=i>>1;
if((bit)(i&1)) P4|=0x02; else P4&=0xFD; i=i>>1;
if((bit)(i&1)) P4|=0x04; else P4&=0xFB; i=i>>1;
if((bit)(i&1)) P4|=0x08; else P4&=0xF7; i=i>>1;
if((bit)(i&1)) P4|=0x10; else P4&=0xEF; i=i>>1;
if((bit)(i&1)) P4|=0x20; else P4&=0xDF; i=i>>1;
if((bit)(i&1)) P4|=0x40; else P4&=0xBF; i=i>>1;
if((bit)(i&1)) P4|=0x80; else P4&=0x7F; i=i>>1;
i=buf[1];
if((bit)(i&1)) P5|=0x01; else P5&=0xFE; i=i>>1;
if((bit)(i&1)) P5|=0x02; else P5&=0xFD; i=i>>1;
if((bit)(i&1)) P5|=0x04; else P5&=0xFB; i=i>>1;
if((bit)(i&1)) P5|=0x08; else P5&=0xF7; i=i>>1;
if((bit)(i&1)) P2|=0x10; else P2&=0xEF; i=i>>1;
if((bit)(i&1)) P2|=0x20; else P2&=0xDF; i=i>>1;
if((bit)(i&1)) P2|=0x40; else P2&=0xBF; i=i>>1;
if((bit)(i&1)) P2|=0x80; else P2&=0x7F; i=i>>1;
i=buf[2];
if((bit)(i&1)) P1|=0x01; else P1&=0xFE; i=i>>1;
if((bit)(i&1)) P1|=0x02; else P1&=0xFD; i=i>>1;
if((bit)(i&1)) P1|=0x04; else P1&=0xFB; i=i>>1;
if((bit)(i&1)) P1|=0x08; else P1&=0xF7; i=i>>1;
if((bit)(i&1)) P1|=0x10; else P1&=0xEF; i=i>>1;
if((bit)(i&1)) P1|=0x20; else P1&=0xDF; i=i>>1;
if((bit)(i&1)) P1|=0x40; else P1&=0xBF; i=i>>1;
if((bit)(i&1)) P1|=0x80; else P1&=0x7F; i=i>>1;
}//if(CurrentWorkStep == 0)
else
{
rtn = LOGIC_ERROR;
}
}//if(length==3)
else
{
rtn = LENGTH_ERROR;
}
CommSendInfo();
}break;//case 4:// 分容
case 5:// 取分容信息命令
{
uint16 data temp;
temp = buf[0];
temp = temp<<8;
temp = temp | buf[1];
if(temp%100 == 0 && temp<=3800 && temp>=2600)
{
if(CurrentWorkStep == 0)//如果当前为停止
{
CommSendFenRongInfo(temp);
}
else
{
rtn = LOGIC_ERROR;
CommSendInfo();
}
}//if(temp%100 == 0)
else
{
rtn = DATA_ERROR;
CommSendInfo();
}//if(temp%100 == 0)
}break;
case 6:// 模块启动
{
if(CurrentWorkStep==0)
{
CurrentWorkStep = 1;
CurrentWorkStepMax = 1;
Reset = 0;
CellCheckFlag = 0;
OSSemPost(StartWorkStepSem);//发送同步工步执行信号量
}
else
{
rtn = LOGIC_ERROR;
}
CommSendInfo();
}break;
case 7:// 工步续接
{
CommSendInfo();
}break;
case 8:// 电池对点
{
if(CurrentWorkStep==0)
{
CellCheckUHigh = buf[0];
CellCheckUHigh = CellCheckUHigh<<8;
CellCheckUHigh|= buf[1];
CellCheckULow = buf[2];
CellCheckULow = CellCheckULow<<8;
CellCheckULow |= buf[3];
if((CellCheckUHigh < 5000) && (CellCheckUHigh > 500) &&
(CellCheckULow < 5000) && (CellCheckULow > 500) &&
(CellCheckUHigh > CellCheckULow))
{
CellCheckULow *= 10;
CellCheckUHigh*= 10; //为了能和单片机内电池数据比较
CellCheckFlag = 1;
}
else
{
CellCheckULow = 0;
CellCheckUHigh = 0;
CellCheckFlag = 0;
rtn = DATA_ERROR;
}
}
else
{
rtn = LOGIC_ERROR;
}
CommSendInfo();
}break;
case 0xC0:// 设模块参数
{
if(length == 3)
{
uint16 data temp;
temp = buf[1];
temp = temp<<8;
temp = temp | buf[2];
if(temp < PARAMETER_MAX && temp >PARAMETER_MIN)//保证所写参数在一定数值范围内
{
if(OSSemPend(IICSem,10)==OS_SEM_OK)
{
EepromWriteByteA(CellParaIICBase+buf[0]*2,buf[1]);
EepromWriteByteA(CellParaIICBase+buf[0]*2+1,buf[2]);
OSSemPost(IICSem);
}
if(buf[0]%8 == 0 || buf[0]%8 == 2 )
AdParaChanged = 1;
if(buf[0]%8 == 4 || buf[0]%8 == 6 )
DaParaChanged = 1;
}
else
{
rtn = DATA_ERROR;
}
}
else
{
rtn = LENGTH_ERROR;
}
CommSendInfo();
}break;
case 0xC1:// 取模块参数
{
CommSendParaInfo();
}break;
default:
{
rtn = CID_ERROR;
CommSendInfo();
}
}//switch (cid)
}//if(rtn==1)//如果报文的校验和,类型正确]
else//如果校验和或类型不正确
{
CommSendInfo();
}
}//if (Address == GetCharWithCheck())
}//while (1)
}//void TaskReceive(void)
/*********************************************************************************************************
** 函数名称: comm
** 功能描述: 串口中断处理程序
** 输 入: 无
** 输 出: 无
** 全局变量: 无
** 调用模块: 无
**
** 作 者: 刘宝贵
** 日 期: 2004年4月20日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#if EN_OS_INT_ENTER >0
#pragma disable /* 除非最高优先级中断,否则,必须加上这一句 */
#endif
void comm(void) interrupt 4
{
uint8 data temp;
if(EN_485 == 1)//EN_485==1:通信处于接收状态
{
if (RI0 == 1)
{
#if EN_OS_INT_ENTER >0
OS_INT_ENTER();
#endif
RI0 = 0;
OSQIntPost(SerialInData,SBUF0);
OSIntExit();
return;
}
}
else
{
RI0 = 0;
}
if (TI0 == 1)
{
TI0 = 0;
if (OSQAccept(&temp,SerialOutData) == OS_Q_OK)
{
SBUF0 = temp;
}
else
{
SerialCanSend = 1;
EN_485 = 1;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -