1.作用
- 防止编译器优化对该变量的访问过程,确保每次访问都能得到最新的值。
- 编译器通常会对代码进行优化,例如将变量的值存储在寄存器中,以减少对内存的访问
2.应用
场景:1.硬件寄存器 2.中断服务程序中的变量 3.多线程程序中的共享变量
//stm32f407xx.h
typedef struct
{
__IO uint32_t LISR; /*!< DMA low interrupt status register, Address offset: 0x00 */
__IO uint32_t HISR; /*!< DMA high interrupt status register, Address offset: 0x04 */
__IO uint32_t LIFCR; /*!< DMA low interrupt flag clear register, Address offset: 0x08 */
__IO uint32_t HIFCR; /*!< DMA high interrupt flag clear register, Address offset: 0x0C */
} DMA_TypeDef;
//core_cm4.h
#ifdef __cplusplus // C和C++编译器区分一下 _I 的宏定义
#define __I volatile /*!< Defines 'read only' permissions */
#else
#define __I volatile const /*!< Defines 'read only' permissions */
#endif
#define __O volatile /*!< Defines 'write only' permissions */
#define __IO volatile /*!< Defines 'read / write' permissions */
/* 强调用于结构体成员M = member */
#define __IM volatile const /*! Defines 'read only' structure member permissions */
#define __OM volatile /*! Defines 'write only' structure member permissions */
#define __IOM volatile /*! Defines 'read / write' structure member permissions */
3. 解释说明
- __I、__O、_IO 都表示 volatile,变量访问不可被优化,只是用不同标识符来区别访问权限
- __I表示输入寄存器,一般只读,__O表示输出寄存器,一般只写,__IO表示可读写寄存器
- __I:volatile const __O:volatile __IO:volatile
- 输入寄存器:例如一个温度传感器连接到MCU,传感器的输出连接到一个输入寄存器,可以读取该输入寄存器的值获得温度值,当然还有状态信息或其他外部输入信号的应用场景
- 输出寄存器:用于向外部硬件发送数据,典型的输出寄存器用于控制外设、发送数据或触发特定的硬件操作
- 输入输出寄存器:用于需要双向数据传输的外设,例如GPIO、U(S)ART、I2C和SPI接口等
- 根据作用分类可分为:状态寄存器、控制寄存器、数据寄存器,跟MCU总线类似(地址总线、控制总线、数据总线)