一种CAN通讯矩阵填包算法

一种CAN通讯矩阵填包算法

使用说明(重要)

CAN通讯矩阵填包的实现,入参需要填入起始地址、占用的长度、需要填入的值、偏移(若无则填0)、倍率(无则填1)、需要填入的矩阵地址,该接口实现最通用的接口算法,无任何行数和应用场景的限制。
如果需要依据具体的协议封装出更上层的接口,可在此通用接口上直接封装,需要代写请私信联系。

算法实现代码


```c
#include <stdio.h>
#include <stdlib.h>

typedef unsigned int uint32;
typedef unsigned short ushort;
typedef unsigned char uchar;
typedef int int32;

//跨行时算法
void calculate_endindex_allline(uchar st, uchar len, uchar *arr)
{
    uchar all_line = 0;      //除去结束line和开始line,单独占用的帧数量
    uchar st_index = st % 8; //起始索引
    uchar end_index = 0;     //结束索引
    uchar temp = (len + st_index - 9);
    if (temp < 8)
    {
        end_index = temp;
    }
    else
    {
        end_index = temp % 8;
        all_line = temp / 8;
    }
    arr[0] = end_index;
    arr[1] = all_line;
    return;
}
uchar Insert_message(char st, char len, int32 value, int32 offset, float factor, uchar *buff)
{
    uchar end;                                   //结束地址
    uchar line = st / 8;                         //起始地址行号
    uchar st_index = st % 8;                     //起始索引
    uchar end_index;                             //结束索引
    value = (uint32)((value - offset) / factor); //转换值
    uchar fill = 0;                              //转换后的填充值
    uchar all_line = 0;
    uchar arr[2] = {0, 0};
    int i = 0;
    int j = 0;
    if (len > (8 - st_index)) //需要跨行
    {
        calculate_endindex_allline(st, len, arr);
        end_index = arr[0];
        all_line = arr[1];
        if (all_line == 0) //等于两行
        {
            for (i = st_index; i <= 7; i++) //清空bit位
            {
                buff[line] &= (~((uchar)1 << i));
            }
            for (i = st_index; i <= 7; i++) //计算需要填充的值
            {
                fill |= (uchar)((value << st_index) & ((uchar)1 << i));
            }
            buff[line] |= fill;
            for (i = 0; i <= end_index; i++)
            {
                buff[line - 1] &= (~((uchar)1 << i));
            }
            fill = 0;
            for (i = 0; i <= end_index; i++) //计算需要填充的值
            {
                fill |= (uchar)((value >> (8 - st_index)) & ((uchar)1 << i));
            }
            buff[line - 1] |= fill;
        }
        else //大于两行
        {
            for (i = st_index; i <= 7; i++) //清空bit位
            {
                buff[line] &= (~((uchar)1 << i));
            }
            fill = 0;
            for (i = st_index; i <= 7; i++) //计算需要填充的值
            {
                fill |= (uchar)(value & ((uchar)1 << i));
            }
            buff[line] |= fill;
            for (i = 0; i <= end_index; i++)
            {
                buff[end_index / 8] &= (~((uchar)1 << i));
            }
            fill = 0;
            for (i = 0; i <= end_index; i++) //计算需要填充的值
            {
                fill |= (uchar)((value >> ((8 - st_index) + 8 * all_line)) & ((uchar)1 << i));
            }
            buff[end_index / 8] |= fill;
            fill = 0;
            for (i = 1; i <= all_line; i++)
            {
                buff[st_index / 8 - i] = 0;
                for (int j = 0; j < 8; j++)
                {
                    fill |= ((value >> ((8 - st_index) + (i - 1) * 8 + j)) & ((uchar)1 << j));
                }
                buff[st_index / 8 - i] |= fill;
            }
        }
    }
    else //不需要跨行
    {
        end = st + len - 1;                     //计算结束地址
        end_index = st_index + len - 1;         //计算结束索引
        for (i = st_index; i <= end_index; i++) //清空需要填充的bit位
        {
            buff[line] &= (~((uchar)1 << i));
        }
        for (i = st_index; i <= end_index; i++) //计算需要填充的值
        {
            fill |= (uchar)((value << st_index) & ((uchar)1 << i));
        }
        buff[line] |= fill; //填入数据
    }
    return 0;
}


## 验证代码示例

```c
int main()
{
    uchar packet[8] = {
        0,
    };
    Insert_message(42, 14, 50, -500, 0.1, packet);
    Insert_message(24, 16, 30, -20000, 1, packet);
    Insert_message(12, 1, 1, 0, 1, packet);
    Insert_message(13, 1, 0, 0, 1, packet);
    Insert_message(14, 2, 3, 0, 1, packet);

    for (int i = 0; i < 8; i++)
    {
        printf("message %d:0x%x\r\n", i, packet[i]);
    }
    system("pause");
    return 0;
}

验证结果

输出结果。当前环境为window,linux上无差异

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值