搜索
bottom↓
回复: 21

CAN总线,汽车厂的协议ByteOrder是Motorola Forward lsb为何要这么做

[复制链接]

出0入0汤圆

发表于 2017-7-7 17:51:02 | 显示全部楼层 |阅读模式
CAN总线,汽车厂的协议ByteOrder是Motorola Forward lsb为何要这么做,好处是什么?


KEIL C51中,变量都是大端模式的,KEIL MDK中,变量是小端模式的。
其实这是与MCU类型相关的,51是8位机,但所有的编译器都是大端的,为了兼容原有的环境,就只能一直大下去。而ARM是32位的CPU,其内核先天就是小端的,那编译器也不会特立独行地搞个大端出来。



在STM32里面,字节序是Intel(即小端),位序为Standard。CAN总线8字节数据 分布情况如图:





但是汽车厂给的CAN通信协议中,字节序为Motorola,位序是Forward lsb。CAN总线8字节数据 分布情况如图:





在下不知道,字节序定义为Motorola forward lsb的好处是什么?
如果stm32收到的数据需要串口打印出来,那势必需要进行格式转换,这种转换怎么做?

小弟迷惑










本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

 楼主| 发表于 2017-7-7 17:54:57 | 显示全部楼层
本帖最后由 WM_CH 于 2017-7-7 17:59 编辑

好像都是从右往左,只不过Intel是从上往下,Motorola是从下往上



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入24汤圆

发表于 2017-7-7 18:07:57 | 显示全部楼层
8位机没有大小端,编译器自己决定,Keil C51是大端,IAR 8051是小端
ARM的处理器大小端ARM公司没有指定,由厂家自己定。MCU通常是只支持小端,有些处理器同时支持大小端,用户自己配置,例如S3C2400,寄存器地址有两套,大小端的各一套
STM32上面可以使用RBIT指令,按位反转

出0入0汤圆

发表于 2017-7-7 18:23:27 来自手机 | 显示全部楼层
国内用的大多Motorola,国外大多Intel,只要不跨字节没啥区别

出0入0汤圆

发表于 2017-7-7 18:56:13 来自手机 | 显示全部楼层
很明显,你说呢

出0入0汤圆

发表于 2017-7-7 19:19:02 | 显示全部楼层
本帖最后由 RAMILE 于 2017-7-7 19:22 编辑

一种推理:

现在很多汽车芯片 像发动机 车身什么的,用的都是 FSL的PPC或者MSX12XXX

FSL就是Motorola的半导体部门,除了日本车,其他的几乎都用Motorola的方案

所以,当初博世提出CAN方案,很大可能就是在Motorola的MCU上实现的,所以6800就是要和8080Intel不一样

当年Motorola的CPU也是很牛的

出0入0汤圆

 楼主| 发表于 2017-7-7 19:53:21 | 显示全部楼层
RAMILE 发表于 2017-7-7 19:19
一种推理:

现在很多汽车芯片 像发动机 车身什么的,用的都是 FSL的PPC或者MSX12XXX

原来不是有什么好处,只是历史遗留的习惯,谢谢

出0入0汤圆

 楼主| 发表于 2017-7-7 19:53:48 | 显示全部楼层
20061002838 发表于 2017-7-7 18:07
8位机没有大小端,编译器自己决定,Keil C51是大端,IAR 8051是小端
ARM的处理器大小端ARM公司没有指定,由 ...

多谢这么专业的指导

出0入0汤圆

 楼主| 发表于 2017-7-7 20:05:40 | 显示全部楼层
本帖最后由 WM_CH 于 2017-7-7 20:18 编辑
q457344370 发表于 2017-7-7 18:23
国内用的大多Motorola,国外大多Intel,只要不跨字节没啥区别


兄台一语点破,原来我在纠结跨字节的问题。刚刚核对了一下协议,还是有跨字节的数据的。

这里再追问一下,要是跨字节访问怎么做呢,兄台这块还请指导一下,我脑子彻底懵了



夸两个字节的话,低字节的高几位比如(Byte0的bit7 , bit6),通过位移,和高字节的低几位拼起来(比如Byte1的bit1 , bit0),
最后的结果就是B1b1, B1b0, B0b7, B0b6,这样的一个数据,对吗?





出0入0汤圆

 楼主| 发表于 2017-7-7 20:18:58 | 显示全部楼层

测漏兄帮下忙呗

出0入0汤圆

发表于 2017-7-7 20:26:55 来自手机 | 显示全部楼层
WM_CH 发表于 2017-7-7 20:05
兄台一语点破,原来我在纠结跨字节的问题。刚刚核对了一下协议,还是有跨字节的数据的。

这里再追问一下 ...

应该有转字节序的函数的什么ntohl ntohs的

出0入0汤圆

发表于 2017-7-7 20:52:36 来自手机 | 显示全部楼层
WM_CH 发表于 2017-7-7 20:05
兄台一语点破,原来我在纠结跨字节的问题。刚刚核对了一下协议,还是有跨字节的数据的。

这里再追问一下 ...

看MCU和你需要用的是不是一致的,一致直接用共用体+位域就可以做了,如果想要兼容性直接写个函数实现吧,根据起始位和长度读写bool u8 u16 u32共6个函数,如果不考虑效率,里边直接用for就可以搞定

出0入0汤圆

发表于 2017-7-7 20:58:21 | 显示全部楼层
WM_CH 发表于 2017-7-7 20:05
兄台一语点破,原来我在纠结跨字节的问题。刚刚核对了一下协议,还是有跨字节的数据的。

这里再追问一下 ...

给你几个用for循环实现的,效率差点,还是能用的,需要效率的话你自己写吧
  1. /// <summary>
  2.         /// Intel
  3.         /// </summary>
  4.         /// <param name="bytes"></param>
  5.         /// <param name="start"></param>
  6.         /// <param name="length"></param>
  7.         /// <param name="value"></param>
  8.         /// <returns></returns>
  9.         public static byte[] SetBitIntel(this byte[] bytes, int start, int length, uint value)
  10.         {
  11.             for (int i = 0; i < length; i++)
  12.             {
  13.                 int posByte = (i+ start) / 8;
  14.                 int posBit = (i + start) % 8;
  15.                 byte bitValue = (byte)((value >> i) & 0x01);

  16.                 bytes[posByte] &= (byte)(~(1 << posBit));
  17.                 bytes[posByte] |= (byte)(bitValue<< posBit);
  18.             }
  19.             return bytes;
  20.         }

  21.         /// <summary>
  22.         /// Intel
  23.         /// </summary>
  24.         /// <param name="bytes"></param>
  25.         /// <param name="start"></param>
  26.         /// <param name="length"></param>
  27.         /// <returns></returns>
  28.         public static uint GetBitIntel(this byte[] bytes, int start, int length)
  29.         {
  30.             uint value = 0;
  31.             for (int i = 0; i < length; i++)
  32.             {
  33.                 int posByte = (i + start) / 8;
  34.                 int posBit = (i + start) % 8;
  35.                 value |= (((uint)bytes[posByte] >> posBit) & 0x01) << i;
  36.             }
  37.             return value;
  38.         }

  39.         /// <summary>
  40.         /// Motorola
  41.         /// </summary>
  42.         /// <param name="bytes"></param>
  43.         /// <param name="start"></param>
  44.         /// <param name="length"></param>
  45.         /// <param name="value"></param>
  46.         /// <returns></returns>
  47.         public static byte[] SetBitMotorola(this byte[] bytes, int start, int length, uint value)
  48.         {
  49.             int posByte = start / 8;
  50.             int posBit = start % 8;

  51.             for (int i = 0; i < length; i++)
  52.             {
  53.                 byte bitValue = (byte)((value >> i) & 0x01);

  54.                 bytes[posByte] &= (byte)(~(1 << posBit));
  55.                 bytes[posByte] |= (byte)(bitValue << posBit);
  56.                 if(i >= length)
  57.                 {
  58.                     break;
  59.                 }
  60.                 if(++posBit >= 8)
  61.                 {
  62.                     posBit = 0;
  63.                     posByte--;
  64.                 }
  65.             }
  66.             return bytes;
  67.         }

  68.         /// <summary>
  69.         /// Motorola
  70.         /// </summary>
  71.         /// <param name="bytes"></param>
  72.         /// <param name="start"></param>
  73.         /// <param name="length"></param>
  74.         /// <returns></returns>
  75.         public static uint GetBitMotorola(this byte[] bytes, int start, int length)
  76.         {
  77.             uint value = 0;
  78.             int posByte = start / 8;
  79.             int posBit = start % 8;

  80.             for (int i = 0; i < length; i++)
  81.             {
  82.                 value |= (((uint)bytes[posByte] >> posBit) & 0x01) << i;

  83.                 if (i >= length)
  84.                 {
  85.                     break;
  86.                 }
  87.                 if (++posBit >= 8)
  88.                 {
  89.                     posBit = 0;
  90.                     posByte--;
  91.                 }
  92.             }
  93.             return value;
  94.         }
复制代码

出0入0汤圆

发表于 2017-7-8 13:25:29 | 显示全部楼层
先学习,谢谢!!!

出0入0汤圆

发表于 2017-7-8 15:57:05 | 显示全部楼层
CAN属于通信协议, 林林总总的通信协议多了去。不管哪种,最后总要归个大小端的类。 比如底层是串口UART,上面可以是各种协议,这些协议有些就是大端,有些就是小端。比如MODBUS是大端,而别的有些也是基于UART的却是小端。       TCP,USB神马的自己去看吧。
8位的大小端是编译器决定的,高于8位的CPU除非内核限制死了大小端,不然编译器也可以决定大小端的。  不管哪种情况,林林总总的CPU用起来也是最终要归个大小端的类。
问题来了,N个通信协议在N个CPU间传输,AaBb组合问题,难免有人要不顺,为什么有人顺有人不顺?没有对错,只有组合和运气。        神马,你说你用的CPU可以人为指定大小端?不怕跟别人通信纠结?  那让你同时两个协议通信,一个通信协议大端一个通信协议小端看你怎么办。所以还是看运气啊。。。如果这两个协议大小端一样就顺了,不然你就去SWAP倒字序吧。

出0入0汤圆

发表于 2017-7-8 16:04:31 | 显示全部楼层
总之,所有规则都是人为定的,人为折腾出来的。谁拳头大,谁先出声,就随谁的喜好定了。
然后有些地方喜欢大端的人拳头大,有些地方喜欢小端的人先出声。最后,当两个地方碰在一起,就出现了大小端不和谐的情况。

出0入0汤圆

发表于 2017-7-8 16:08:32 | 显示全部楼层
日期写法都有人要争个Y/M/D  M/D/Y   D/M/Y神马的        度量衡更加没有统一要换算,英制公制。

出0入0汤圆

 楼主| 发表于 2017-7-10 15:45:48 | 显示全部楼层
q457344370 发表于 2017-7-7 20:58
给你几个用for循环实现的,效率差点,还是能用的,需要效率的话你自己写吧
...

多谢兄台指导         

出0入0汤圆

 楼主| 发表于 2017-7-10 17:51:25 | 显示全部楼层
huangqi412 发表于 2017-7-8 15:57
CAN属于通信协议, 林林总总的通信协议多了去。不管哪种,最后总要归个大小端的类。 比如底层是串口UART,上 ...

不好意思,兄台见笑了。我还以为是这样做比较方便,原来只是历史问题。

出0入0汤圆

发表于 2017-7-11 20:07:37 | 显示全部楼层
WM_CH 发表于 2017-7-10 17:51
不好意思,兄台见笑了。我还以为是这样做比较方便,原来只是历史问题。 ...

不止字节有区别  你看看单片机spi配置寄存器  位也有区别  都是spi接口 有些芯片是msb  有些却是lsb

出0入0汤圆

 楼主| 发表于 2017-7-11 20:09:03 | 显示全部楼层
huangqi412 发表于 2017-7-11 20:07
不止字节有区别  你看看单片机spi配置寄存器  位也有区别  都是spi接口 有些芯片是msb  有些却是lsb ...

感谢兄台指点

都没注意过。。


出0入0汤圆

 楼主| 发表于 2017-9-12 09:46:12 | 显示全部楼层
楼主位的两种方式,不就是简单的字节序不同的区别嘛。。。。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-26 02:54

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表