使用微 Controller 时,通常您必须对寄存器进行写入和读取,为了使代码更具可读性,您需要定义寄存器地址及其位。这有点好,但是当您的寄存器名称彼此非常相似时,它很快就会变得困惑,例如此处所示
#define SYSAHBCLKCTRL (*(unsigned int*) 0x40048080)
#define TMR16B0TCR (*(unsigned int*) 0x4000C004)
#define TMR16B0TC (*(unsigned int*) 0x4000C008)
#define TMR16B0PR (*(unsigned int*) 0x4000C00C)
#define TMR16B0MR0 (*(unsigned int*) 0x4000C018) // Match register
#define ISER1 (*(unsigned int*) 0xE000E104) // Enable IRQ
#define TMR16B0MCR (*(unsigned int*) 0x4000C014) // Match Control
#define TMR16B0IR (*(unsigned int*) 0x4000C000) // Interrupt Flag Register
在这个级别上,它仍然在某种程度上是可以管理的,但是当您开始定义每个寄存器的关联标志(例如这个寄存器)时,情况会变得更糟
#define I2C1CONSET (* (unsigned int *) 0x4005C000)
#define I2C1CONSET_EN 0x40
// bit 5, start condition
#define I2C1CONSET_STA 0x20
// bit 4, stop condition
#define I2C1CONSET_STO 0x10
// bit 2, acknowledge signal
#define I2C1CONSET_ACK 0x04
此时,我更愿意使用 namespace 之类的东西,所以我可以做这样的事情:
I2C1CONSET |= _I2C1CONSET.EN | _I2C1CONSET.STA; // set EN and STA bits on I2C1CONSET register
对于我现在的工作方式,有什么干净的替代方案吗?
最佳答案
您可以使用位字段,例如
struct i2c1conset_flags
{
unsigned : 2;
unsigned ack : 1;
unsigned : 1;
unsigned sto : 1;
unsigned sta : 1;
unsigned en : 1;
};
static volatile union {
unsigned value;
struct i2c1conset_flags flags;
} *const I2C1CONSET = (void *)0x4005C000;
这允许你写
I2C1CONSET->value = 0;
I2C1CONSET->flags.sto = 1;
并假设 C99
#define I2C1CONSET_FLAGS(...) ((struct i2c1conset_flags){ __VA_ARGS__ })
I2C1CONSET->flags = I2C1CONSET_FLAGS(.ack = 1, .en = 1);
但这真的有助于提高可读性吗?您必须自己决定。
<小时/>现在我已经尝试了更多,我认为这种方法实际上可以提高可读性。以下是我能想到的最好的,我相信它看起来确实不错:
#define I2C1CONSET (*(volatile unsigned *)0x4005C000)
struct I2C1CONSET_flags
{
unsigned : 2;
unsigned ack : 1;
unsigned : 1;
unsigned sto : 1;
unsigned sta : 1;
unsigned en : 1;
unsigned : 25;
};
#define flags(REG) \
(*(volatile struct REG ## _flags *)®)
#define mask(REG, ...) \
(((union { unsigned value; struct REG ## _flags flags; }){ \
.flags = { __VA_ARGS__ } \
}).value)
flags(I2C1CONSET).sto = 1;
I2C1CONSET |= mask(I2C1CONSET, .ack = 1, .en = 1);
关于微 Controller 寄存器的更干净的命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26192618/