我需要写三个不同的CAN消息到CAN总线。第一条消息由8个8位的值组成,所以没有问题,但第二条和第三条消息更不规则在第三条消息中,我有三个值,大小都是16位,第三条消息有一些小于8位的值。如何使用大于或小于8位的值为can帧正确创建数据?
这是我的代码
int main(int argc, char **argv)
{
int s;
struct sockaddr_can addr;
struct ifreq ifr;
struct can_frame frame;
struct can_frame frame2;
if ((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
perror("Socket");
return 1;
}
strcpy(ifr.ifr_name, "vcan0" );
ioctl(s, SIOCGIFINDEX, &ifr);
memset(&addr, 0, sizeof(addr));
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("Bind");
return 1;
}
frame.can_id = 0x500;
frame.can_dlc = 8;
frame.data[0] = 122;
frame.data[1] = 150;
frame.data[2] = -27;
frame.data[3] = -22;
frame.data[4] = 160;
frame.data[5] = 160;
frame.data[6] = -60;
frame.data[7] = 90;
frame2.can_id = 0x501;
frame.can_dlc = 6;
frame.data[0] = 32766;
frame.data[2] = -32765;
frame.data[4] = 20542;
if (write(s, &frame, sizeof(struct can_frame)) != sizeof(struct can_frame)) {
perror("Write");
return 1;
}
if (close(s) < 0) {
perror("Close");
return 1;
}
return 0;
}
'索引0显然对应于数据帧的前8位但我真的不知道有什么其他方法可以做到这一点因为我对C
的经验很少我希望能够使这些CAN帧与两个索引上的数据正确,但不知道如何做到这一点。以及一种使用单个比特而不是使用帧索引的8比特的方法。数据对象,因为我需要制作CAN消息,其中多个值存在于CAN消息的单个8位数据帧中。如果有意义
首先,您不能这样做,除非您知道特定CAN总线的网络端序。大端序是最常见的,但一些CAN应用层,如CANopen使用小端序作为有效载荷。
假设network =大端序,假设32766
,-32765
和20542
是你的16位数字,那么:
const int16_t data16[3] = { 32766, -32765, 20542 };
...
frame.data[0] = ((uint16_t)data16[0] >> 8) & 0xFFu;
frame.data[1] = ((uint16_t)data16[0] >> 0) & 0xFFu;
frame.data[2] = ((uint16_t)data16[1] >> 8) & 0xFFu;
frame.data[3] = ((uint16_t)data16[1] >> 0) & 0xFFu;
frame.data[4] = ((uint16_t)data16[2] >> 8) & 0xFFu;
frame.data[5] = ((uint16_t)data16[2] >> 0) & 0xFFu;
或者:
for(size_t i=0; i<3; i++)
{
frame.data[i*2] = ((uint16_t)data16[i] >> 8) & 0xFFu;
frame.data[i*2+1] = ((uint16_t)data16[i] >> 0) & 0xFFu;
}
这里的位移是相同的,无论CPU是大/小端序,但你必须交换MS和LS字节,以防网络使用小端序。