1 //寄存器的值常常是芯片外设自动更改的,即使 CPU 没有执行程序,也有可能发生变化
2 //编译器有可能会对没有执行程序的变量进行优化
3
4 //volatile 表示易变的变量,防止编译器优化,
5 #define __IO volatile
6 typedef unsigned int uint32_t;
7 typedef unsigned short uint16_t;
8
9 // GPIO 寄存器结构体定义
10 typedef struct
11 {
12 __IO uint32_t CRL; // 端口配置低寄存器, 地址偏移 0X00
13 __IO uint32_t CRH; // 端口配置高寄存器, 地址偏移 0X04
14 __IO uint32_t IDR; // 端口数据输入寄存器, 地址偏移 0X08
15 __IO uint32_t ODR; // 端口数据输出寄存器, 地址偏移 0X0C
16 __IO uint32_t BSRR; // 端口位设置/清除寄存器,地址偏移 0X10
17 __IO uint32_t BRR; // 端口位清除寄存器, 地址偏移 0X14
18 __IO uint32_t LCKR; // 端口配置锁定寄存器, 地址偏移 0X18
19 } GPIO_TypeDef;
这段代码在每个结构体成员前增加了一个“__IO”前缀,它的原型在这段代码的第一
行,代表了 C 语言中的关键字“volatile”,在 C 语言中该关键字用于表示变量是易变的,
要求编译器不要优化。这些结构体内的成员,都代表着寄存器,而寄存器很多时候是由外
设或 STM32 芯片状态修改的,也就是说即使 CPU 不执行代码修改这些变量,变量的值也
有可能被外设修改、更新,所以每次使用这些变量的时候,我们都要求 CPU 去该变量的地
址重新访问。若没有这个关键字修饰,在某些情况下,编译器认为没有代码修改该变量,
就直接从 CPU 的某个缓存获取该变量值,这时可以加快执行速度,但该缓存中的是陈旧数
据,与我们要求的寄存器最新状态可能会有出入。
详细解决方案
volatile 在STC32中的含义解释,应用
热度:97 发布时间:2023-12-17 22:22:33.0
相关解决方案
- 常见异常 不能打开注册表关键字 'Temporary (volatile) Jet DSN for process 0xbec Thread 0xd34 DBC 0x3510024 Jet'
- #define rINTPND (*(volatile unsigned *)0x4a000010) 编译器是如何知道往这个地址里面写值的
- *((volatile unsigned *)i)=0xEA000000+0x1FFE;该如何解决
- *(volatile unsigned short *)0x20000000背后的意义是啥?该如何处理
- 多线程中的锁系统(2)-volatile、Interlocked、ReaderWriterLockSlim
- volatile 变量没有给出预期的输出
- Java Concurrent--内存可见性(volatile)
- 线程六:volatile
- synchronized、volatile、CAS 比较
- volatile 限定修饰符
- __IO uint32_t 中的__IO (volatile)
- C语言中auto register static const volatile
- volatile 在STC32中的含义解释,应用
- volatile 与诡异事件
- volatile, 用更低的代价替代同步
- java 高性能并发一之 volatile
- Java 的 volatile 关键字学习
- Volatile 在程序设计中的作用
- (*(volatile unsigned int *))详解
- C语言中auto,register,static,const,volatile,extern的区别
- C# volatile 理解
- strictfp, volatile, transient关键词
- 并发专题(三)Volatile
- JAVA(17)-设计模式-多线程-单例-synchronized-volatile
- Synchronized ,Volatile,Lock 三者不可告人的秘密
- C++程序员应了解的那些事(55)静态成员函数没有this指针,不与类的实例(对象)“挂钩”【即不能声明为const、volatile、virtual】