- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我必须在基于 ARM9 的微 Controller 中对外围寄存器进行编程。
例如,对于 USART,我将相关内存地址存储在 enum
中:
enum USART
{
US_BASE = (int) 0xFFFC4000,
US_BRGR = US_BASE + 0x16,
//...
};
然后,我在函数中使用指针来初始化寄存器:
void init_usart (void)
{
vuint* pBRGR = (vuint*) US_BRGR;
*pBRGR = 0x030C;
//...
}
但是我的老师说我最好使用#define
,例如:
#define US_BASE (0xFFFC4000)
#define US_BRGR (US_BASE + 0x16)
#define pBRGR ((vuint*) US_BRGR)
void init_usart (void)
{
*pBRGR = 0x030C;
}
他说,就像这样,您没有在堆栈中分配指针的开销。
就个人而言,我不太喜欢#define
,也不喜欢其他预处理器指令。所以问题是,在这种特殊情况下,#define
真的值得使用而不是 enum
和堆栈分配的指针吗?
相关问题:Want to configure a particular peripheral register in ARM9 based chip
最佳答案
我一直喜欢的方法是首先定义一个反射(reflect)外设寄存器布局的结构
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;
然后在代码中我可以使用
p_usart0->brgr = 0x030C;
当您有多个相同类型的外围设备实例时,这种方法会更简洁:
USART *p_usart1 = (USART * const) 0xFFFC5000;
USART *p_usart2 = (USART * const) 0xFFFC6000;
用户 sbass 提供了指向 an excellent column 的链接由 Dan Saks 撰写,提供了有关此技术的更多详细信息,并指出了它相对于其他方法的优势。
如果您有幸使用 C++,那么您可以为外围设备上的所有常见操作添加方法,并很好地封装设备特性。
关于c - #define 与用于寻址外围设备的枚举,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3970876/
我有一个基于 Java 的应用程序 (Android),我希望能够在后台执行可能长时间的操作。 AsyncTask 上的 Android 文档建议不要将它们用于可能运行时间超过几秒的任务(这是为什么?
所以我有外围 BLE 设备,我需要一些标识符以便稍后与另一部 iPhone 共享。示例我将 iPhone 'A' 连接到外围设备。 iPhone 'A' 将外围设备的标识符保存到数据库中,稍后我可以轻
当我指定这样的服务时: centralManager.scanForPeripherals(withServices:[BEAN_SERVICE_UUID],选项:[CBCentralManagerS
我是一名优秀的程序员,十分优秀!