使用说明(重要)
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;
}