在 C 中重新排列复合初始值设定项的宏

Macro to rearrange compound initializer in C

简介

我相信按照制造商数据表中描述的相同顺序分配微控制器的寄存器值可以避免错误。我提出了以下解决方案:

struct myBits
{
   uint32_t b00 : 1;
   uint32_t b01 : 1;
   uint32_t b02 : 1;
    ...
   uint32_t b30 : 1;
   uint32_t b31 : 1;
};


// PIOB->        offset: PIO_CODR
// 0x400E1000U           0x00000034U
(*(volatile uint32_t*)0x400E1034U) = *(uint32_t*)&(struct myBits) {
// --------------------------------------------------------------------------------------------------
/*|    B31    |    B30    |    B29    |    B28    |    B27    |    B26    |    B25    |    B24    |*/
.b31=   0   ,.b30=  0   ,.b29=  0   ,.b28=  0   ,.b27=  0   ,.b26=  0   ,.b25=  0   ,.b24=  0     ,
// --------------------------------------------------------------------------------------------------
/*|    B23    |    B22    |    B21    |    B20    |    B19    |    B18    |    B17    |    B16    |*/
.b23=   0   ,.b22=  0   ,.b21=  0   ,.b20=  0   ,.b19=  0   ,.b18=  0   ,.b17=  0   ,.b16=  0     ,
// --------------------------------------------------------------------------------------------------
/*|    B15    |    B14    |    B13    |    B12    |    B11    |    B10    |    B09    |    B08    |*/
.b15=   0   ,.b14=  0   ,.b13=  0   ,.b12=  0   ,.b11=  0   ,.b10=  0   ,.b09=  0   ,.b08=  0     ,
// --------------------------------------------------------------------------------------------------
/*|    B07    |    B06    |    B05    |    B04    |    B03    |    B02    |    B01    |    P00    |*/
.b07=   0   ,.b06=  0   ,.b05=  0   ,.b04=  0   ,.b03=  0   ,.b02=  0   ,.b01=  0   ,.b00=  0      };

问题

我希望有一个宏来翻转复合赋值中的结构值以消除指定的需要:

// PIOB->        offset: PIO_CODR
// 0x400E1000U           0x00000034U
(*(volatile uint32_t*)0x400E1034U) = *(uint32_t*)&(struct myBits) desiredMacro ({
// --------------------------------------------------------------------------------------------------
/*|    B31    |    B30    |    B29    |    B28    |    B27    |    B26    |    B25    |    B24    |*/
        0     ,     0     ,     0     ,     0     ,     1     ,     0     ,     0     ,     0    ,
// --------------------------------------------------------------------------------------------------
/*|    B23    |    B22    |    B21    |    B20    |    B19    |    B18    |    B17    |    B16    |*/
        0     ,     0     ,     0     ,     0     ,     0     ,     0     ,     0     ,     0     ,
// --------------------------------------------------------------------------------------------------
/*|    B15    |    B14    |    B13    |    B12    |    B11    |    B10    |    B09    |    B08    |*/
        0     ,     0     ,     0     ,     0     ,     0     ,     0     ,     0     ,     0     ,
// --------------------------------------------------------------------------------------------------
/*|    B07    |    B06    |    B05    |    B04    |    B03    |    B02    |    B01    |    P00    |*/
        0     ,     0     ,     0     ,     0     ,     0     ,     0     ,     0     ,     0      });

这可能吗?

提前致谢。希望我的 ASCII 艺术能激发社区的灵感。

解决方案

由于 Nate Eldredge 提出的解决方案,我重新审视了我之前的一次宏尝试。这次我把宏写对了,成功了。

#define invertMacro(b31,b30,b29,b28,b27,b26,b25,b24,b23,b22,b21,b20,b19,b18,b17,b16,b15,b14,b13,b12,b11,b10,b09,b08,b07,b06,b05,b04,b03,b02,b01,b00) b00,b01,b02,b03,b04,b05,b06,b07,b08,b09,b10,b11,b12,b13,b14,b15,b16,b17,b18,b19,b20,b21,b22,b23,b24,b25,b26,b27,b28,b29,b30,b31

// PIOB->        offset: PIO_CODR
// 0x400E1000U           0x00000034U
(*(volatile uint32_t*)0x400E1034U) = *(uint32_t*)&(struct myBits) { invertMacro (
// --------------------------------------------------------------------------------------------------
/*|    B31    |    B30    |    B29    |    B28    |    B27    |    B26    |    B25    |    B24    |*/
        0     ,     0     ,     0     ,     0     ,     0     ,     0     ,     0     ,     0    ,
// --------------------------------------------------------------------------------------------------
/*|    B23    |    B22    |    B21    |    B20    |    B19    |    B18    |    B17    |    B16    |*/
        0     ,     0     ,     0     ,     0     ,     0     ,     0     ,     0     ,     0     ,
// --------------------------------------------------------------------------------------------------
/*|    B15    |    B14    |    B13    |    B12    |    B11    |    B10    |    B09    |    B08    |*/
        0     ,     0     ,     0     ,     0     ,     0     ,     0     ,     0     ,     0     ,
// --------------------------------------------------------------------------------------------------
/*|    B07    |    B06    |    B05    |    B04    |    B03    |    B02    |    B01    |    P00    |*/
        0     ,     0     ,     0     ,     0     ,     0     ,     0     ,     0     ,     0      )};

复制此代码时,请注意他的建议,以避免在双关时违反严格的别名。