gpt4 book ai didi

微 Controller 寄存器的更干净的命名空间

转载 作者:行者123 更新时间:2023-11-30 15:29:34 26 4
gpt4 key购买 nike

使用微 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 *)&REG)

#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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com