问题描述
我必须在基于 ARM9 的微控制器中对外围寄存器进行编程.
I have to program peripheral registers in an ARM9-based microcontroller.
例如,对于 USART,我将相关内存地址存储在 enum
中:
For instance, for the USART, I store the relevant memory addresses in an enum
:
enum USART
{
US_BASE = (int) 0xFFFC4000,
US_BRGR = US_BASE + 0x16,
//...
};
然后,我在函数中使用指针来初始化寄存器:
Then, I use pointers in a function to initialize the registers:
void init_usart (void)
{
vuint* pBRGR = (vuint*) US_BRGR;
*pBRGR = 0x030C;
//...
}
但是我老师说我最好用#define
s,比如:
But my teacher says I'd better use #define
s, such as:
#define US_BASE (0xFFFC4000)
#define US_BRGR (US_BASE + 0x16)
#define pBRGR ((vuint*) US_BRGR)
void init_usart (void)
{
*pBRGR = 0x030C;
}
就像这样,他说,你没有在堆栈中分配指针的开销.
Like so, he says, you don't have the overhead of allocating pointers in the stack.
就我个人而言,我不太喜欢 #define
,也不喜欢其他预处理器指令.所以问题是,在这种特殊情况下,#define
是否真的值得使用而不是 enum
和堆栈分配的指针?
Personally, I don't like #define
s much, nor other preprocessor directives.So the question is, in this particular case, are #define
s really worth using instead of enum
s and stack-allocated pointers?
推荐答案
我一直喜欢的方法是首先定义一个结构来反映外设寄存器布局
The approach I've always preferred is to first define a struct reflecting the peripherals register layout
typedef volatile unsigned int reg32; // or other appropriate 32-bit integer type
typedef struct USART
{
reg32 pad1;
reg32 pad2;
reg32 pad3;
reg32 pad4;
reg32 brgr;
// any other registers
} USART;
USART *p_usart0 = (USART * const) 0xFFFC4000;
然后在代码中我可以使用
Then in code I can just use
p_usart0->brgr = 0x030C;
当您有多个相同类型的外围设备实例时,这种方法会更简洁:
This approach is much cleaner when you have multiple instances of the same sort of peripheral:
USART *p_usart1 = (USART * const) 0xFFFC5000;
USART *p_usart2 = (USART * const) 0xFFFC6000;
用户 sbass 提供了一个链接到 一个很棒的专栏,作者是 Dan Saks,其中提供了有关此技术的更多详细信息,并指出了它相对于其他方法的优势.
User sbass provided a link to an excellent column by Dan Saks that gives much more detail on this technique, and points out its advantages over other approaches.
如果您有幸使用 C++,那么您可以为外围设备上的所有常见操作添加方法,并很好地封装设备特性.
If you're lucky enough to be using C++, then you can add methods for all the common operations on the peripheral and nicely encapsulate the devices peculiarities.
这篇关于#define 与用于寻址外围设备的枚举的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!