volatile的用法

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. 解释说明

  • __O、_IO 都表示 volatile,变量访问不可被优化,只是用不同标识符来区别访问权限
  • __I表示输入寄存器(只读),不可被软件修改,但可被硬件更新,__O表示输出寄存器(只写),__IO表示可读写寄存器
  • __I:volatile const     __O:volatile    __IO:volatile
  • 输入寄存器(REG):例如一个温度传感器连接到MCU,传感器的输出连接到一个输入寄存器,可以读取该输入寄存器的值获得温度值,当然还有状态信息或其他外部输入信号的应用场景
  • 输出寄存器:用于向外部硬件发送数据,典型的输出寄存器用于控制外设、发送数据或触发特定的硬件操作
  • 输入输出寄存器:用于需要双向数据传输的外设,例如GPIO、U(S)ART、I2C和SPI接口等
  • 根据作用分类可分为:状态寄存器、控制寄存器、数据寄存器,跟MCU总线类似(地址总线、控制总线、数据总线)
posted @ 2024-06-09 15:54  变秃了也就变强了  阅读(7)  评论(0编辑  收藏  举报