单片机嵌入式字符流数据解析库

kw_charProtocol库说明

本库针对字符数据流类型设备,接收发送特定协议帧制作的微库。可以裸机运行,也可以配合实时操作系统运行。

本库开源连接地址:gitee连接

实现思路

本库采用C语言进行编程,方便移植,用户通过调用库接口函数即可使用。

以[YY6500传感器]为例,对应,该传感器采用串口作为通信接口。

主要接口函数如下:

项目 函数 功能 备注
1 kw_CPInitPara 初始化注册协议变量对象,包括:
1. 异步队列数组
2. 接收数组
3. 发送数组
2 kw_CPSetHead 注册协议包头
3 kw_CPRegisterTailCB 注册协议包尾
4 kw_CPRegisterCheckCB 注册校验和回调
5 kw_CPRegisterFrameCB 注册解完整数据包回调
6 kw_CPDecode 周期解码
7 kw_CPReceiveByte 接收字符流数据

主要变量如下

项目 变量 类型 说明
1 _g_cpYY6500 kw_charProtocol_s 协议对象
2 _g_YY6500Queue 接收队列数组 unsigned char[]
3 _g_YY6500RBuf 接收数组缓存 unsigned char[]
4 _g_Head 包头 unsigned char[]

需要实现的协议接口如下:

项目 接口 说明
1 _IsTail 包尾判断
2 _IsCheckOK 校验和判断
3 _frame 完整数据包回调

测试代码

协议代码

#include "CP_YY6500.h"

#ifdef CONFIG_KW_CP

kw_charProtocol_s _g_cpYY6500;
unsigned char _g_YY6500Queue[128];
unsigned char _g_YY6500RBuf[128];
unsigned char _g_Head[1] = {0x16};
unsigned char _YY6500_Tmp[4] = {0};
cp_YY6500_e _g_YY6500_Flag = CP_YY6500_NONE;

cp_YY6500_s _g_YY6500;

static bool _IsTail(kw_frame_s *p, unsigned char in);
static bool _IsCheckOK(kw_frame_s *p);
static void _frame(kw_frame_s *p);

void CP_YY6500Init()
{
    kw_CPInitPara(&_g_cpYY6500,
                  _g_YY6500Queue, sizeof(_g_YY6500Queue),
                  _g_YY6500RBuf, sizeof(_g_YY6500RBuf),
                  0, 0);
    kw_CPSetHead(&_g_cpYY6500, _g_Head, sizeof(_g_Head));
    kw_CPRegisterTailCB(&_g_cpYY6500, _IsTail);
    kw_CPRegisterCheckCB(&_g_cpYY6500, _IsCheckOK);
    kw_CPRegisterFrameCB(&_g_cpYY6500, _frame);
}

void CP_YY6500Decode()
{
    kw_CPDecode(&_g_cpYY6500);
}

void CP_YY6500SendResult(cp_YY6500_e type, int (*send)(unsigned char *datas, unsigned int len))
{
    if (send != 0 && type < CP_YY6500_MAX && type > CP_YY6500_NONE)
    {
        _YY6500_Tmp[0] = 0x11;
        _YY6500_Tmp[1] = 0x01;
        if(type == CP_YY6500_RESULT)
        {
            _YY6500_Tmp[2] = 0x01;
            _YY6500_Tmp[3] = 0xED;
        }
        else if(type == CP_YY6500_VERSION)
        {
            _YY6500_Tmp[2] = 0x1E;
            _YY6500_Tmp[3] = 0xD0;
        }
        else if(type == CP_YY6500_NO)
        {
            _YY6500_Tmp[2] = 0x1F;
            _YY6500_Tmp[3] = 0xCF;
        }
        send(_YY6500_Tmp, 4);
        _g_YY6500_Flag = type;
    }
}

void CP_YY6500Receive(unsigned char in)
{
    kw_CPReceiveByte(&_g_cpYY6500, in);
}

static bool _IsTail(kw_frame_s *p, unsigned char in)
{
    return p->wIdx > 4 && p->wIdx == p->buf.buffer[1] + 2;
}

static bool _IsCheckOK(kw_frame_s *p)
{
    unsigned char sum = 0;
    for (unsigned char i = 0; i < p->wIdx - 1; i++)
    {
        sum += p->buf.buffer[i];
    }

    return (p->buf.buffer[p->wIdx - 1] + (sum)) & (0xFF) == 0xFF;
}

static void _frame(kw_frame_s *p)
{
    if (_g_YY6500_Flag == CP_YY6500_RESULT)
    {
        _g_YY6500.nongdu = (p->buf.buffer[3] << 8) + p->buf.buffer[4];
        _g_YY6500.liuliang = (p->buf.buffer[5] << 8) + p->buf.buffer[6];
        _g_YY6500.wendu = ((p->buf.buffer[7] << 8) + p->buf.buffer[8] - 500);
        _g_YY6500.res = (p->buf.buffer[9] << 8) + p->buf.buffer[10];
        _g_YY6500_Flag = CP_YY6500_NONE;
    }
    else if(_g_YY6500_Flag == CP_YY6500_VERSION)
    {
        for (unsigned char i = 0; i < 8; i++)
        {
            _g_YY6500.version[i] = p->buf.buffer[i + 3];
        }
        _g_YY6500_Flag = CP_YY6500_NONE;
    }
    else if(_g_YY6500_Flag == CP_YY6500_NO)
    {
        for (unsigned char i = 0; i < 10; i++)
        {
            _g_YY6500.NO[i] = p->buf.buffer[i + 3];
        }
        _g_YY6500_Flag = CP_YY6500_NONE;
    }
}

#endif

#ifndef _CP_YY6500_H
#define _CP_YY6500_H

#ifdef __cplusplus
extern "C"
{
#endif
#include "kw_baseDrvCFG.h"
#ifdef CONFIG_KW_CP

    typedef enum _cp_YY6500_e
    {
        CP_YY6500_NONE,
        CP_YY6500_RESULT,
        CP_YY6500_VERSION,
        CP_YY6500_NO,
        CP_YY6500_MAX,
    } cp_YY6500_e;

    typedef struct _cp_YY6500_s
    {
        unsigned short nongdu;
        unsigned short liuliang;
        short wendu;
        unsigned short res;
        unsigned char version[8];
        unsigned char NO[10];
    } cp_YY6500_s;

    void CP_YY6500Init();
    void CP_YY6500SendResult(cp_YY6500_e type, int (*send)(unsigned char *datas, unsigned int len));
    void CP_YY6500Decode();
    void CP_YY6500Receive(unsigned char in);

#endif

#ifdef __cplusplus
}
#endif

#endif

主函数调用


#include "CP_YY6500.h"

static void _hal_uartRecv(unsigned char data)
{
    CP_YY6500Receive(data);
}

void main()
{
    HAL_UARTInit();
    CP_YY6500Init();
    while (1)
    {
        CP_YY6500Decode();
    }
}

你可能感兴趣的:(单片机嵌入式微库,单片机,嵌入式硬件,嵌入式微库)