原创 C语言宏里面的陷阱

2011-1-13 16:04 2622 6 6 分类: 软件与OS

在8位的MCU使用下面的宏可能会产生不同的结果:

//宏可以用的参数列表

//串口数据格式配置宏定义参数
//for UiMR
#define UART_PARITY_NONE    0x00   /*无校验*/
#define UART_PARITY_ODD     0x40   /*奇校验*/
#define UART_PARITY_EVEN    0x60   /*偶校验*/

#define UART_NINTHBIT       0x06    /*传输第九位*/
#define UART_EIGHTBIT  0x05  /*传输8位*/
#define UART_SEVENBIT  0x04 /*传输7位 */

#define UART_STOP_BIT_ONE 0x00 /*1个停止位*/
#define UART_STOP_BIT_TWO 0x10 /*1个停止位*/
//for UiC0
#define UART_MSB_LAST       0x00   /*低位在先*/
#define UART_MSB_FIRST      0x80   /*高位在先*/

//宏1,有问题

#define UART_DATA_FORMAT_CFG(uart,cfg) \
do \
{ \
uform_u##uart##c0 = 0;  \
if ( (cfg & UART_MSB_FIRST) ) \
{ \
uform_u##uart##c0 = 1; \
asm("NOP"); \
} \
u##uart##mr &= ~0xf7; \
u##uart##mr |= (cfg & 0x7f); \
}while(0)

//宏2

#define UART_DATA_FORMAT_CFG(uart,cfg)  \
 do          \
 {          \
  uform_u##uart##c0 = 0;     \
  if ( ((UINT8)(cfg) & UART_MSB_FIRST) )  \
  {         \
   uform_u##uart##c0 = 1;   \
  }         \
  u##uart##mr &= ~0xf7;    \
  u##uart##mr |= (cfg & 0x7f);  \
 }while(0)

 

调用宏如下:

UART_DATA_FORMAT_CFG(0, UART_MSB_LAST|UART_PARITY_NONE|UART_EIGHTBIT|UART_STOP_BIT_ONE );

结果是宏1无法将寄存器uic0的D7位置0,宏2可以做到将uic0的D7位清零,目前我只能想到一个解释:就是常量在编译的时候先计算结果,但在却不是以unsigned char型存放的。所以导致上面的问题。

如果先定义

UINT8 cfg;
cfg = UART_MSB_LAST|UART_PARITY_NONE|UART_EIGHTBIT|UART_STOP_BIT_ONE ;
再调用
UART_DATA_FORMAT_CFG(0, cfg);
则宏1,宏2都能得到期望的结果。

文章评论0条评论)

登录后参与讨论
我要评论
0
6
关闭 站长推荐上一条 /2 下一条