Chinaunix首页 | 论坛 | 博客
  • 博客访问: 356479
  • 博文数量: 197
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 303
  • 用 户 组: 普通用户
  • 注册时间: 2013-09-02 14:21
文章分类

全部博文(197)

文章存档

2014年(89)

2013年(108)

我的朋友

分类: C/C++

2013-10-31 14:45:21

相关概念:

大端模式:数据的低位保存在内存的高地址中,而数据的高位保存在内存的低地址中,这种存储模式就类似把数据当做字符串顺序处理,例如:数据中两个字节按顺序为:FE 10 ,它表示的一个数就是0xFE10。
换句话说:内存的低地址存放着数据高位;

小端模式:数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中,这种存储方式就是将地址的高低和数据的位结合起来,前面的例子按照小端模式表示,应该为:0x10FE。
换句话说:内存的低地址存放着数据低位。 

使用背景:

        通信中数据是以字节形式传递的,而单片机中的数据种类有很多,char、int、long、数组、结构体,这些数据都需要转换为字节形式,按照通信协议的要求(高字节在前或低字节在前)进行发送。最基本的做法是使用未处理把每个字节分离,但这不是最好的办法,也不是常用的办法。常用的方法是使用指针。

使用实例:

        从我的程序中举两个例子,之所以举这两个例子,是因为,在第二次使用时,我发现指针我还是没搞透,不过幸亏我了解自己,所以特意留意了这个问题,呵呵,不至于让他成为一个Bug。
例1.对传感器输出数据的调整 
        由于传感器输出的数据是MSB在前,LSB在后;而MSP430的内存为 ”小端模式“,所以需要进行内存调整。搞明白了这个还需要搞明白怎样使用指针来进行内存交换。
这里 int  XYZ_RoughVal [3] = {0};  //是一块连续的内存。
 那么表达式 (u8)*((u8*)XYZ_RoughVal+j) 就可以取到这块内存中第j个字节的值,分析:
XYZ_RoughVal :数组地址,一个指针,类型为 int*,指向int数据
 (u8*)XYZ_RoughVal  :把地址指针转换为 u8* 类型,使得指针指向字节
 (u8*)XYZ_RoughVal+j :第j个元素的地址
*((u8*)XYZ_RoughVal+j)  :第j个元素的值
 (u8)*((u8*)XYZ_RoughVal+j) :强制转换为 u8

例2.把一个int型数据写入发送缓冲
int CarInfo = 0;
        同样,协议要求MSB在前,但是MSP430为小端对齐,所以需要取得int数据中每个字节的值。而与数组不同的是,如果使用 *((u8*)CarInfo+1) 表达式,结果是错误的。为什么?
    来分析下,CarInfo 是一个int数据, 那么 (u8*)CarInfo 是一个u8* 类型指针,但他指向的地址是 CarInfo 的值所表示的地址,譬如CarInfo内存地址为0×248,值为0×101,那么 (u8*)CarInfo指向的地址是 地址0×101,而地址0×101中存放的数据是0x0B。这就错了。
正确的表达式应该是  *((u8*)&CarInfo+1)  ,分析: &CarInfo:CarInfo的地址;  (u8*)&CarInfo:把这个地址转换为 u8* 类型。

小结:

指针是非常高效的,内存对齐是值得注意的。

阅读(459) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~