标签存档: 数据类型

来看看这几个宏SetBit、GetBit、ClearBit

#define GetBit(dat,i) ((dat&(0x0001<<i))?1:0)
#define SetBit(dat,i) ((dat)|=(0x0001<<(i)))
#define ClearBit(dat,i) ((dat)&=(~(0x0001<<(i))))

1.首先在STM32上常数默认是int型的。使用EWARM开发环境。
2.因为常数是int型,所以是4字节(STM32是32位系统,int型数据和long型数据都是32bit),故这里i的范围是0~31。如果i超过31(大于等于32),则会出现如下报错:
Warning[Pe063]: shift count is too large
3.当i=31时会出现如下报错:
Warning[Pe068]: integer conversion resulted in a change of sign (整型转换导致符号改变)
原因:
当1<<30,结果是0x40000000,即1073741824,结果是正数。
当1<<31,结果是0x80000000,即-2147483648,结果是负数。

对于上面的宏,比较好的写法是:
#define GetBit(dat,i) ((dat&((u32)1<<i))?1:0)
#define SetBit(dat,i) ((dat)|=((u32)1<<(i)))
#define ClearBit(dat,i) ((dat)&=(~((u32)0x01<<(i))))

Cortex M3 的数据类型

用惯了16位的MSP430,在STM32上忘了他是32位的,还以为他的int是2字节,原来int与long是一样的4字节。

所以int型数据发范围是 -2147483648 到 +2147483647。而long型与int型是同样宽度的,所以,long型的数据范围同样是-2147483648 到 +2147483647。

数据类型导致计算溢出的问题

问题:数据类型使用不当和表达式使用不当是的计算溢出,导致数据错误。
看如下表达式:

int  XYZ_BaseVal[3], XYZ_SmoothVal[i];
XYZ_BaseVal[i] =  XYZ_BaseVal[i] * 95 +   XYZ_SmoothVal[i] * 5;
XYZ_BaseVal[i] =   XYZ_BaseVal[i] / 100;
数组元素的取值范围是-2408到2047.

所以, 当 XYZ_BaseVal[i] 的值比较大时,XYZ_BaseVal[i] * 95 表达式得到的是一个负数 ,导致计算结果错误。 继续阅读 »