我的目标是实现写标准CAN帧信号的函数标准CAN帧包含以下信号:
ID:11位
rtr:1比特
预留位:1位
预留1:1位
数据链路控制:4位
数据:8字节
这是我对罐头框架的描述

typedef union
{
unsigned char tab[10];
struct
{
    unsigned char id_8_10:3; //ID: bit 8==>10
    unsigned char id_4_7:4; //ID: bit 4==>7
    unsigned char id_0_3:4; //ID: bit 0==>3
    unsigned char rtr:1;
    unsigned char reserved0:1;
    unsigned char reserved1:1;
    unsigned char dlc:4;
    unsigned char tabData[8];
 }bBit;
}tCanFrame;

写函数如下:
void IL_Wr_id_8_10(unsigned char ubVal)
{
 ((tCanFrame*)(&tabFrame))->bBit.id_8_10 = (unsigned int)(ubVal);
}

void IL_Wr_id_4_7(unsigned char ubVal)
{
 ((tCanFrame*)(&tabFrame))->bBit.id_4_7 = (unsigned int)(ubVal);
}

void IL_Wr_id_0_3(unsigned char ubVal)
{
((tCanFrame*)(&tabFrame))->bBit.id_0_3 = (unsigned int)(ubVal);
}

void IL_Wr_rtr(unsigned char ubVal)
{
 ((tCanFrame*)(&tabFrame))->bBit.rtr =(ubVal);
}

void IL_Wr_reserved1(unsigned char ubVal)
{

 ((tCanFrame*)(&tabFrame))->bBit.reserved1 =(ubVal);

}

void IL_Wr_dlc(unsigned char ubVal)
{

 ((tCanFrame*)(&tabFrame))->bBit.dlc =(ubVal);

}

void IL_Wr_data(unsigned char* ubVal)
{

 memcpy(((tCanFrame*)(&tabFrame))->bBit.tabData,ubVal,8);

}

总的来说,我试图给信号赋值并打印它们,但不幸的是,似乎插入了一些数据位。
这是主要的:
int main()
{
 int i;
 IL_Wr_id_8_10(0x7);
 IL_Wr_id_4_7(0x00);
 IL_Wr_id_0_3(0x0F);
 IL_Wr_rtr(0x00);
 IL_Wr_reserved0(0x0);
 IL_Wr_reserved1(0xFF);
 IL_Wr_dlc(0x0F);
 IL_Wr_data(tableauDonnee);

 for (i=0;i<18;i++)
 {
    printf("Byte %i : %s \n",i,byte_to_binary(tabFrame[i]));
 }
 return 0;
}

结果如下:
Byte 0 : 0000.0111 // the result should be Byte 0 : 1000.0111
Byte 1 : 0100.1111 // the result should be Byte 1 : 1110.0111
....

你认为这个问题是什么?你有什么办法解决这个问题吗?

最佳答案

你的解决方案不可移植。
不能可靠地使用位字段:内存中字段的实际布局是由实现定义的,通常取决于目标体系结构字节顺序。
如果您的编译器/体系结构组合的布局恰好正确,那么您确定actuel位布局吗在18数组之前定义tabData位:将插入至少6个填充位,以便在字节边界上对齐tabData,从而生成一个11字节的结构,您似乎认为它只有10字节长。

10-08 20:03