我的目标是实现写入标准CAN帧信号的功能。标准CAN帧包含以下信号:
这是我对CAN框架的表示
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;
Write函数如下:
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
....
您认为有什么问题,您有什么想法解决这个问题吗?
答案 0 :(得分:0)
您的解决方案无法移植。
您无法可靠地使用位域:内存中字段的实际布局是实现定义的,通常取决于目标架构字节顺序。
如果您的编译器/架构组合的布局恰好正确,您确定实际位布局吗?您在.footer {
position: absolute;
margin-bottom: 0px;
background: rgba(0, 0, 0, 0.6);
color: #FFF;
width: 100%;
height: auto;
}
数组之前定义18
位:将插入至少6个填充位,以便在字节边界上对齐tabData
,产生一个11字节结构,您似乎认为它是只有10个字节长。
答案 1 :(得分:0)
您的位字段数据的总大小为18位,因此使用&#39; int&#39;或者&#39; unsigned int&#39;将正常工作以表示您的标题数据。
typedef union
{
unsigned char tab[10];
struct
{
int id_8_10:3; //ID: bit 8==>10
int id_4_7:4; //ID: bit 4==>7
int id_0_3:4; //ID: bit 0==>3
int rtr:1;
int reserved0:1;
int reserved1:1;
int char dlc:4;
unsigned char tabData[8];
}bBit;
}tCanFrame;
如果是位字段,
struct
{
data_type [member_name] : width;
};
&#39; data_type&#39;的大小使用位字段数据成员指定的边界考虑因素。
在你的情况下, id_8_10(3比特),id_4_7(4比特)和id_0_3(4比特)加起来超过8比特的11比特。因此,id_0_3(4比特)被分配在第二字节中。第一个字节仅包含id_8_10(3位)和id_4_7(4位)= 7位+ 1位未使用。
使用&#39; int&#39;或者&#39; unsigned int&#39;会有所帮助。
注意::基于你的main(),字节1预计为1110.0111,而不是
字节1:..... //结果应为Byte 1:0010.0111&lt; - 如您所示。
答案 2 :(得分:0)
我选择实现自己的功能:
/*function: copy_bits
description: copy nbBitsToCopy bits from srcAdress to destAdress starting from a specific bit start_bit
destAdress: destination address
start_bit:the bit in the destination where to paste data
srcAdress:source address
nbBitsToCopy: Number of bit to copy from source
*/
void copy_bits(unsigned char* destAdress , unsigned char start_bit, unsigned char *srcAdress, unsigned char nbBitsToCopy)
{
unsigned int dest_Cursor_Byte;
unsigned int dest_Cursor_Bit;
unsigned int src_Cursor_Byte;
unsigned int src_Cursor_Bit;
unsigned int nbCopiedBits=0;
//Initialisation of cursors
dest_Cursor_Byte=start_bit/8;
dest_Cursor_Bit =start_bit%8;
src_Cursor_Byte=0;
src_Cursor_Bit=0;
while (nbCopiedBits<nbBitsToCopy)
{
if (CHECK_BIT(srcAdress[src_Cursor_Byte],src_Cursor_Bit,1))
{
SET_BIT_VALUE(destAdress[dest_Cursor_Byte],dest_Cursor_Bit,1);
}
else
{
SET_BIT_VALUE(destAdress[dest_Cursor_Byte],dest_Cursor_Bit,0);
}
nbCopiedBits++;
start_bit++;
//Update cursors
dest_Cursor_Byte=start_bit/8;
dest_Cursor_Bit =start_bit%8;
src_Cursor_Bit=nbCopiedBits%8;
src_Cursor_Byte=nbCopiedBits/8;
}
}
欢迎你发表评论