|
楼主 |
发表于 2023-12-2 15:54:15
|
显示全部楼层
/*******************************************************SERIAL_FrameBuffer.c**********************************************************/
/*
*******************************************************************************
* 包含头文件
*******************************************************************************
*/
#include "includes.h"
#include "SERIAL_FrameBuffer.h"
#include "SERIAL_Protocol1.h"
#include "SERIAL_Protocol3.h"
/*
********************************************************************************
* 宏定义
********************************************************************************
*/
#define DEF_SERIAL_FRAME_BUFFER_COUNT 5
/*
********************************************************************************
* 结构定义
********************************************************************************
*/
/* 帧协议操作数据结构 */
typedef struct
{
INT16U (*Encode)(INT8U *ptsmt_buf, INT8U cmd, INT8U type, INT8U *param,INT8U *pdata_buf, INT16U len);
void (*Decode)(SERIAL_FRAME_BUFFER *frame_buffer, INT8U data, void (*receive) (INT8U, INT8U, INT16U, INT8U *, INT8U *));
void (*Clear)(SERIAL_FRAME_BUFFER *frame_buffer);
}SERIAL_PROTOCOL_OPERATION;
/*
********************************************************************************
* 内部变量
********************************************************************************
*/
static SERIAL_PROTOCOL_OPERATION m_SerPrtcOpt[DEF_SERIAL_FRAME_BUFFER_COUNT]=
{
{0, 0, 0},
{SERIAL_Protocol1Encode, SERIAL_Protocol1Decode, SERIAL_Protocol1Clear},
{0, 0, 0},
{SERIAL_Protocol3Encode, SERIAL_Protocol3Decode, SERIAL_Protocol3Clear},
{0, 0, 0},
};
static SERIAL_FRAME_BUFFER m_SerFmBuf[DEF_SERIAL_FRAME_BUFFER_COUNT];
static INT8U m_SerFmBufCt;
/*
********************************************************************************
* 内部函数
********************************************************************************
*/
/*
********************************************************************************
********************************************************************************
* 接口函数
********************************************************************************
********************************************************************************
*/
/*
******************************************************************************
函数名称: SERIAL_FmBufCreate
函数功能: 创建数据帧
输入参数: protocol_type:协议类型
pbuf:用户数据缓冲区
len:用户数据缓长度
输出参数: none
返 回 值: 数据帧句柄
注 意:
*******************************************************************************
*/
SerFmBufHd SERIAL_FmBufCreate(INT8U protocol_type,INT8U *pbuf, INT16U len)
{
if (m_SerFmBufCt > DEF_SERIAL_FRAME_BUFFER_COUNT-1)
{
return DEF_SERIAL_FRAME_BUFFER_CREATE_ERROR;
}
m_SerFmBuf[m_SerFmBufCt].ProtocolType = protocol_type;
m_SerFmBuf[m_SerFmBufCt].FmPkge.Buffer = pbuf;
m_SerFmBuf[m_SerFmBufCt].FmPkge.BufLen = len;
m_SerPrtcOpt[protocol_type].Clear(&m_SerFmBuf[m_SerFmBufCt]);
m_SerFmBufCt++;
return (m_SerFmBufCt-1);
}
/*
******************************************************************************
函数名称: SERIAL_FrameDecode
函数功能: 数据帧解包
输入参数: hfm_buf:数据帧句柄
data:数据
receive:数据接收服务函数
输出参数: none
返 回 值: none
注 意:
*******************************************************************************
*/
void SERIAL_FmBufDecode(SerFmBufHd hfm_buf, INT8U data, void (*receive) (INT8U, INT8U, INT16U, INT8U *, INT8U *))
{
SERIAL_FRAME_BUFFER *frame_buffer;
frame_buffer = &m_SerFmBuf[hfm_buf];
m_SerPrtcOpt[frame_buffer->ProtocolType].Decode(frame_buffer, data ,receive);
}
/*
******************************************************************************
函数名称: SERIAL_FrameEncode
函数功能: 数据帧打包
输入参数: prtc_type:协议类型
ptsmt_buf:发送的数据缓冲区
cmd:控制命令
type:数据类型
pbuf:缓冲区
len:长度
输出参数: none
返 回 值: none
注 意:
*******************************************************************************
*/
INT16U SERIAL_FmBufEncode(INT8U prtc_type, INT8U *ptsmt_buf, INT8U cmd, INT8U type, INT8U *param, INT8U *pdata_buf, INT16U len)
{
return m_SerPrtcOpt[prtc_type].Encode(ptsmt_buf, cmd, type, param, pdata_buf, len);
}
/**********************************************************SERIAL_FrameBuffer.h*********************************************************/
#ifndef SERIAL_FRAME_BUFFER_H
#define SERIAL_FRAME_BUFFER_H
#include "includes.h"
/*
*******************************************************************************
* 包含头文件
*******************************************************************************
*/
/*
********************************************************************************
* 宏定义
********************************************************************************
*/
#define DEF_SERIAL_FRAME_BUFFER_CREATE_ERROR -1
//#define DEF_SERIAL_FRAME_BUFFER_DATA_SIZE (4096)
#define DEF_SERIAL_FRAME_BUFFER_PARAM_SIZE (12)
enum
{
PROTOCOL_0,
PROTOCOL_1,
PROTOCOL_2,
PROTOCOL_3,
PROTOCOL_4,
};
/*
********************************************************************************
* 结构定义
********************************************************************************
*/
/*
数据包结构体
*/
typedef struct
{
/* 数据帧长度 */
INT16U Length;
/* 命令 */
INT8U Command;
/* 数据类型 */
INT8U DataType;
/* 参数 */
INT8U Param[DEF_SERIAL_FRAME_BUFFER_PARAM_SIZE];
/* 数据帧效验和 */
INT16U CheckSum;
/* 数据缓冲区指针 */
INT8U *Buffer;//[DEF_SERIAL_FRAME_BUFFER_DATA_SIZE];
/* 数据缓冲区长度 */
INT16U BufLen;
}SERIAL_FRAME_PACKAGE;
/*
数据帧控制块结构体
*/
typedef struct
{
/* 状态 */
INT8U Status;
/* 长度*/
INT16U Count;
/* 辅助变量 */
INT8U temp[2];
}SERIAL_FRAME_CONTROL_BLOCK;
/*
数据帧缓冲结构体
*/
typedef struct
{
/* 协议类型 */
INT8U ProtocolType;
SERIAL_FRAME_PACKAGE FmPkge;
SERIAL_FRAME_CONTROL_BLOCK FmCtrBlk;
}SERIAL_FRAME_BUFFER;
typedef INT8S SerFmBufHd;
/*
********************************************************************************
* 接口函数
********************************************************************************
*/
extern void SERIAL_FmBufDecode(SerFmBufHd hfm_buf, INT8U data, void (*receive) (INT8U, INT8U, INT16U, INT8U *, INT8U *));
extern INT16U SERIAL_FmBufEncode(INT8U prtc_type, INT8U *ptsmt_buf, INT8U cmd, INT8U type, INT8U *param,INT8U *pdata_buf, INT16U len);
extern SerFmBufHd SERIAL_FmBufCreate(INT8U protocol_type, INT8U *pbuf, INT16U len);
#endif
/*******************************************SERIAL_Protocol.c********************************************************/
/*
*******************************************************************************
* 包含头文件
*******************************************************************************
*/
#include "includes.h"
#include "SERIAL_Protocol1.h"
/*
********************************************************************************
* 宏定义
********************************************************************************
*/
enum
{
DEF_SERIAL_PROTOCOL1_RECEIVE_SRATUS_HEAD,
DEF_SERIAL_PROTOCOL1_RECEIVE_SRATUS_LEN,
DEF_SERIAL_PROTOCOL1_RECEIVE_SRATUS_CMD,
DEF_SERIAL_PROTOCOL1_RECEIVE_SRATUS_TYPE,
DEF_SERIAL_PROTOCOL1_RECEIVE_SRATUS_DATA,
DEF_SERIAL_PROTOCOL1_RECEIVE_SRATUS_CHECKSUM,
DEF_SERIAL_PROTOCOL1_RECEIVE_SRATUS_TAILD
};
/*
********************************************************************************
* 结构定义
********************************************************************************
*/
/*
********************************************************************************
* 内部变量
********************************************************************************
*/
static const char m_CharToASCII[103] =
{
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
/* modified by hxd on 2015.11.04 增加'A' - 'F' -> 10 - 15 */
#if 0
2,3,4,5,6,7,8,9,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,
#else
2,3,4,5,6,7,8,9,0,0,0,0,0,0,0,10,11,12,13,14,15,0,0,0,0,
#endif
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,11,12,13,
14,15
};
static const char m_ASCIIToChar[16] = "0123456789abcdef";
/*
********************************************************************************
* 内部函数
********************************************************************************
*/
/*
******************************************************************************
函数名称: Char_To_Hex
函数功能: 字符转ASCII
输入参数: c:字符
输出参数: none
返 回 值: ASCII
注 意:
*******************************************************************************
*/
static INT8U Char_To_Hex(char c)
{
INT8U dataResult;
/* modified by hxd on 2015.11.04 增加'A' - 'F' */
//if ( (c<48) || ((c > 57)&&(c < 97)) || (c > 102) ){
if ( (c<48) || ((c > 57)&&(c < 65)) ||(c > 70 && c < 97) || (c > 102) ){
return -1;
}
dataResult = m_CharToASCII[c];
return dataResult;
}
/*
******************************************************************************
函数名称: Hex_To_Char
函数功能: ASCII转字符
输入参数: h:ASCII
输出参数: none
返 回 值: 字符
注 意:
*******************************************************************************
*/
static char Hex_To_Char(INT8U h)
{
if(h> 15)
{
return 0;
}
return m_ASCIIToChar[h];
}
/*
******************************************************************************
函数名称: SERIAL_Protocol1GetHex
函数功能: 获取接收数据
输入参数: pdata:数据缓冲
pbuf:数据指针
size:长度
输出参数: none
返 回 值: none
注 意:
*******************************************************************************
*/
void SERIAL_Protocol1GetHex(INT8U *pdst, INT8U *psrc, INT8U size)
{
while (size)
{
*pdst = (Char_To_Hex(*psrc++) << 4);
*pdst += Char_To_Hex(*psrc++);
/* modified by hxd on 2015.11.18 这里只是将pdst 指针加1, 没有必要进行访存操作*/
#if 0
*pdst++;
#else
pdst++;
#endif
size -= 2;
}
}
/*
******************************************************************************
函数名称: SERIAL_Protocol1SetChar
函数功能: 设置发送数据
输入参数: size:4bit个数
pbuf:数据指针
输出参数: none
返 回 值: none
注 意:
*******************************************************************************
*/
void SERIAL_Protocol1SetChar(INT8U *pdst, INT8U *psrc, INT8U size)
{
while (size)
{
*pdst++ = Hex_To_Char((*psrc & 0xf0) >> 4);
*pdst++ = Hex_To_Char(*psrc & 0x0f);
psrc++;
size--;
}
}
/*
********************************************************************************
********************************************************************************
* 接口函数
********************************************************************************
********************************************************************************
*/
/*
******************************************************************************
函数名称: SERIAL_Protocol1Clear
函数功能: 数据帧解包
输入参数: pframe_buffer:数据帧缓冲指针
输出参数: none
返 回 值: none
注 意:
*******************************************************************************
*/
void SERIAL_Protocol1Clear(SERIAL_FRAME_BUFFER *pframe_buffer)
{
SERIAL_FRAME_PACKAGE *pfm_pkge;
SERIAL_FRAME_CONTROL_BLOCK *pfm_ctr_blk;
if (pframe_buffer == (void *)0)
{
return;
}
pfm_pkge = &pframe_buffer->FmPkge;
pfm_ctr_blk = &pframe_buffer->FmCtrBlk;
pfm_ctr_blk->Status = DEF_SERIAL_PROTOCOL1_RECEIVE_SRATUS_HEAD;
pfm_ctr_blk->Count = 0;
pfm_pkge->Length = 0;
memset(pfm_pkge->Buffer, 0, pfm_pkge->BufLen);
}
/*
******************************************************************************
函数名称: SERIAL_Protocol1Decode
函数功能: 数据帧解包
输入参数: pframe_buffer:数据帧缓冲指针
data:数据
receive:接收服务函数
输出参数: none
返 回 值: none
注 意:
*******************************************************************************
*/
void SERIAL_Protocol1Decode(SERIAL_FRAME_BUFFER *pframe_buffer, INT8U data, void (*receive) (INT8U, INT8U, INT16U, INT8U *, INT8U *))
{
SERIAL_FRAME_PACKAGE *pfm_pkge;
SERIAL_FRAME_CONTROL_BLOCK *pfm_ctr_blk;
INT8U pbuf[256];
if (pframe_buffer == (void *)0)
{
return;
}
pfm_pkge = &pframe_buffer->FmPkge;
pfm_ctr_blk = &pframe_buffer->FmCtrBlk;
switch (pfm_ctr_blk->Status)
{
/* 解析头部 */
case DEF_SERIAL_PROTOCOL1_RECEIVE_SRATUS_HEAD:
if (data == DEF_SERIAL_PROTOCOL1_HEAD)
{
pfm_ctr_blk->Status = DEF_SERIAL_PROTOCOL1_RECEIVE_SRATUS_LEN;
}
break;
/* 解析长度 */
case DEF_SERIAL_PROTOCOL1_RECEIVE_SRATUS_LEN:
pfm_ctr_blk->temp[pfm_ctr_blk->Count++] = Char_To_Hex(data);
/* 长度由两个数据分别表示:低4位和高4位 */
if (pfm_ctr_blk->Count > 1)
{
pfm_pkge->Length = pfm_ctr_blk->temp[0]<<4 | pfm_ctr_blk->temp[1];
/* 长度效验 */
if (pfm_pkge->Length > pfm_pkge->BufLen-1)
{
SERIAL_Protocol1Clear(pframe_buffer);
}
else
{
pfm_ctr_blk->Count = 0;
pfm_ctr_blk->Status = DEF_SERIAL_PROTOCOL1_RECEIVE_SRATUS_CMD;
}
}
break;
/* 解析命令 */
case DEF_SERIAL_PROTOCOL1_RECEIVE_SRATUS_CMD:
pfm_pkge->Command = data;
pfm_ctr_blk->Status = DEF_SERIAL_PROTOCOL1_RECEIVE_SRATUS_TYPE;
break;
/* 解析类型 */
case DEF_SERIAL_PROTOCOL1_RECEIVE_SRATUS_TYPE:
pfm_pkge->DataType = data;
pfm_ctr_blk->Status = DEF_SERIAL_PROTOCOL1_RECEIVE_SRATUS_DATA;
break;
/* 解析数据 */
case DEF_SERIAL_PROTOCOL1_RECEIVE_SRATUS_DATA:
pfm_pkge->Buffer[pfm_ctr_blk->Count++] = data;
/* 接收帧长度如果等于数据长度,则表示数据已满接收 */
if (pfm_ctr_blk->Count > pfm_pkge->Length-1)
{
pfm_ctr_blk->Status = DEF_SERIAL_PROTOCOL1_RECEIVE_SRATUS_CHECKSUM;
pfm_ctr_blk->Count = 0;
pfm_pkge->CheckSum = 0;
/* 加入数据 */
for (pfm_ctr_blk->temp[0] = 0; pfm_ctr_blk->temp[0] < pfm_pkge->Length; pfm_ctr_blk->temp[0]++)
{
pfm_pkge->CheckSum += pfm_pkge->Buffer[pfm_ctr_blk->temp[0]];
}
/* 加入命令和数据类型 */
pfm_pkge->CheckSum += (pfm_pkge->Command + pfm_pkge->DataType);
pfm_pkge->CheckSum = (~pfm_pkge->CheckSum) & 0x7f;
}
break;
/* 数据和校验 */
case DEF_SERIAL_PROTOCOL1_RECEIVE_SRATUS_CHECKSUM:
pfm_ctr_blk->temp[pfm_ctr_blk->Count++] = Char_To_Hex(data);
if (pfm_ctr_blk->Count > 1)
{
/* 校验和判断 */
if (pfm_pkge->CheckSum != ((pfm_ctr_blk->temp[0]<<4) | (pfm_ctr_blk->temp[1])))
{
/* 校验和错误,则丢弃数据 */
//Debug("【App】Protocol1 与控制板的通讯,校验和错误... \r\n");
SERIAL_Protocol1Clear(pframe_buffer);
}
else
{
/* 通知应用层,数据包解析完毕 */
SERIAL_Protocol1GetHex(pbuf, pfm_pkge->Buffer, pfm_pkge->Length);
receive(pfm_pkge->Command, pfm_pkge->DataType, pfm_pkge->Length/2, pfm_pkge->Param, pbuf);
SERIAL_Protocol1Clear(pframe_buffer);
}
}
break;
default :
SERIAL_Protocol1Clear(pframe_buffer);
break;
}
}
/*
******************************************************************************
函数名称: SERIAL_Protocol1Encode
函数功能: 数据帧打包
输入参数: ptsmt_buf:发送缓冲区
cmd:控制命令
type:数据类型
pbuf:协议帧源数据缓冲区
len:长度
输出参数: none
返 回 值: 发送长度
注 意:
*******************************************************************************
*/
INT16U check_sum_temp = 0;
INT16U SERIAL_Protocol1Encode(INT8U *ptsmt_buf, INT8U cmd, INT8U type, INT8U *param,INT8U *pdata_buf, INT16U len)
{
INT8U i;
INT16U check_sum;
INT8U *pf;
INT8U pbuf[256];
/* 输入效验 */
if (pdata_buf == NULL || ptsmt_buf == NULL || len == 0)
{
return 0;
}
memset(pbuf, 0, 256);
pf = ptsmt_buf;
check_sum = 0;
/* 数据转char,长度扩大一倍 */
SERIAL_Protocol1SetChar(&pbuf[0], pdata_buf, len);
len *= 2;
/* 添加数据帧头 */
*pf++ = DEF_SERIAL_PROTOCOL1_HEAD;
/* 添加长度 */
*pf++ = Hex_To_Char((len) >> 4);
*pf++ = Hex_To_Char((len) & 0x0f);
/* 添加cmd */
*pf++ = cmd;
/* 添加type */
*pf++ = type;
/* 添加数据 */
for (i = 0; i < len; i++,pf++)
{
*pf = pbuf;
check_sum += pbuf;
}
check_sum += cmd; //M -> 0x4D
check_sum += type; //n -> 0x6E
check_sum = (~check_sum) & 0x7f; //1583
check_sum_temp = check_sum; //80
/* 添加效验和 */ //转化为16进制数据
*pf++ = Hex_To_Char(check_sum >> 4);
*pf++ = Hex_To_Char(check_sum & 0x0f);
/* 添加数据帧尾 */
*pf++ = DEF_SERIAL_PROTOCOL1_TAIL;
len += DEF_SERIAL_PROTOCOL1_PACK_SIZE;
return len;
}
/****************************************************SERIAL_Protocol.h*******************************************************/
#ifndef SERIAL_PROTOCPL1_H
#define SERIAL_PROTOCPL1_H
#include "includes.h"
#include "SERIAL_FrameBuffer.h"
/*
*******************************************************************************
* 包含头文件
*******************************************************************************
*/
/*
********************************************************************************
* 宏定义
********************************************************************************
*/
/* 头+尾+效验和+长度 */
#define DEF_SERIAL_PROTOCOL1_PACK_SIZE 8
/* 定义头 */
#define DEF_SERIAL_PROTOCOL1_HEAD ('<')
#define DEF_SERIAL_PROTOCOL1_TAIL ('>')
/*
********************************************************************************
* 接口函数
********************************************************************************
*/
extern void SERIAL_Protocol1Decode(SERIAL_FRAME_BUFFER *pframe_buffer, INT8U data, void (*receive) (INT8U, INT8U, INT16U, INT8U *, INT8U *));
extern INT16U SERIAL_Protocol1Encode(INT8U *ptsmt_buf, INT8U cmd, INT8U type, INT8U *param,INT8U *pbuf, INT16U len);
extern void SERIAL_Protocol1Clear(SERIAL_FRAME_BUFFER *pframe_buffer);
extern void SERIAL_Protocol1SetChar(INT8U *pdst, INT8U *psrc, INT8U size);
extern void SERIAL_Protocol1GetHex(INT8U *pdst, INT8U *psrc, INT8U size);
#endif
就是类似这种 我只需要修改协议的实现protocol1里面的内容,而不需要修改其他 |
|