📄 serial.c
字号:
/*********************************************************************************************************
**--------------文件信息--------------------------------------------------------------------------------
**文 件 名: serial.c
**创 建 人: 刘宝贵
**最后修改日期: 2004年4月20日
**描 述: 串行口驱动
**
**--------------历史版本信息----------------------------------------------------------------------------
** 创建人: 刘宝贵
** 版 本: V1.00
** 日 期: 2004年4月20日
** 描 述: 原始版本
**
**------------------------------------------------------------------------------------------------------
** 修改人:
** 版 本:
** 日 期:
** 描 述:
**
**------------------------------------------------------------------------------------------------------
**--------------当前版本修订------------------------------------------------------------------------------
** 修改人: 刘宝贵
** 日 期: 2004年4月20日
** 描 述:
**
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#include "config.h"
uint8 OS_Q_MEM_SEL NotUse _at_ 0x0000; //指针的NULL为0,这个变量占用0地质避免出现有效的NULL指针
uint8 OS_Q_MEM_SEL SerialInData[100]; //给读串口消息队列分配的队列空间
uint8 OS_Q_MEM_SEL SerialOutData[200]; //给写串口消息队列分配的队列空间
void PutChar(uint8 Data); //发送一个字节
void Send(uint8 Data); //发送一个数据包
uint8 GetCharWithCheck(void); //从读串口消息队列取一字节,并且对该字节校验
bit SerialCanSend = 1;
bit CommSending = 0;
//uint8 data test;
uint8 data inchk; //校验和
uint8 data outchk; //校验和
uint8 data cid; //命令码
uint8 data rtn; //返回码 RTN值 表示意义
uint8 xdata buf[100]; // 缓冲串口数据
#define RIGHT 1 // 01H 正常
#define CHKSUM_ERROR 2 // 02H CHKSUM 错
#define LENGTH_ERROR 3 // 03H LENGTH 错
#define CID_ERROR 4 // 04H CID 无效
#define TYPE_ERROR 5 // 05H 命令格式错
#define DATA_ERROR 6 // 06H 无效数据
#define LOGIC_ERROR 7 // 07H 逻辑错
#define OTHER_ERROR 0XE0 // E0H~EFH 其他错误
/*********************************************************************************************************
** 函数名称: PutChar
** 功能描述: 发送一个字节
** 输 入: Data:发送的数据
** 输 出: 无
** 全局变量: 无
** 调用模块: 无
**
** 作 者: 陈明计
** 日 期: 2002年12月4日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void PutChar(uint8 Data)
{
OS_ENTER_CRITICAL();
if (SerialCanSend == 1)
{
SerialCanSend = 0;
SBUF0 = Data;
}
else
{
OSQIntPost(SerialOutData,Data);
}
OS_EXIT_CRITICAL();
}
/*********************************************************************************************************
** 函数名称: PutCharWithcheck
** 功能描述: 发送一个字节同时校验
** 输 入: Data:发送的数据
** 输 出: 无
** 全局变量: chk
** 调用模块: PutChar
**
** 作 者: 刘宝贵
** 日 期: 2004年4月21日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void PutCharWithCheck(uint8 Data)
{
outchk ^= Data ;
PutChar (Data);
}
/*********************************************************************************************************
** 函数名称: CommSendInfo
** 功能描述: 发送一个报文
** 输 入: 无
** 输 出: 无
** 全局变量: address cid rtn chk
** 调用模块: OSQCreate PutCharWithCheck PutChar
**
** 作 者: 刘宝贵
** 日 期: 2004年4月25日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void CommSendInfo(void)
{
OSQCreate(SerialOutData,200);
outchk = 0;
PutCharWithCheck(0xeb);
PutCharWithCheck(0x90);
PutCharWithCheck(0xeb);
PutCharWithCheck(0x90);
PutCharWithCheck(Address);
PutCharWithCheck(cid);
PutCharWithCheck(1);
PutCharWithCheck(rtn);
PutChar(outchk);
PutChar(0x0d);
}
/*********************************************************************************************************
** 函数名称: GetCharWithCheck
** 功能描述: 从读串口消息队列取一字节,并且对该字节校验
** 输 入: 无
** 输 出: temp:从串口消息队列取的字节
** 全局变量: inchk:校验和
** 调用模块: OSQPend
**
** 作 者: 刘宝贵
** 日 期: 2004年4月21日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
uint8 GetCharWithCheck(void)
{
uint8 data temp;
OSQPend(&temp,SerialInData,0); /* 接收一个字节 */
inchk^=temp;
return(temp);
}
/*********************************************************************************************************
** 函数名称: GetCharWithoutCheck
** 功能描述: 从读串口消息队列取一字节
** 输 入: 无
** 输 出: temp:从串口消息队列取的字节
** 全局变量: 无
** 调用模块: OSQPend
**
** 作 者: 刘宝贵
** 日 期: 2004年4月21日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
uint8 GetCharWithoutCheck(void)
{
uint8 data temp;
OSQPend(&temp,SerialInData,0); /* 接收一个字节 */
return(temp);
}
/*********************************************************************************************************
** 函数名称: TaskReceive
** 功能描述: 串口接收处理任务
** 输 入: 无
** 输 出: 无
** 全局变量: 无
** 调用模块: 无
**
** 作 者: 刘宝贵
** 日 期: 2004年4月20日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void TaskReceive(void)
{
uint8 code head[4] = {0xEB,0x90,0xEB,0x90};
OSQCreate(SerialInData,100); /* 建立所需要的消息队列 */
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;
}//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 + -