1
完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
在有些程序中,经常会看到这样的变量定义,前面有加__IO,想问一下,这样定义的目的是什么?跟前面不加__IO有什么区别?
__IO uint16_t TxCnt,RxCnt; __IO FlagStatus SendFlag,ReceiveFlag; |
|
相关推荐
22个回答
|
|
内存就是你MCU中的RAM
MCU操作寄存器的速度比操作内存的速度快,所以编译器优化的时候,会把局部变量的值在使用时放到寄存器中(比如R1),后续需要操作这个临时变量时,就会直接找操作这个R1。但这样做有个问题,就是如果这时这个局部变量的在RAM中的值变了,就是说RAM上的值和寄存器R1的值不一致,这样MCU还操作R1上的值就会出现错误,为了避免这样的情况,这种值容易发生变话的变量就会用volatile(易变的)来修饰,这样的话,编译器就不会“自作聪明”吧值放到寄存器R1里操作,每次都会访问内存取最新的值进行操作,这样就不会出上述错误。你可以做个小实验,观察汇编语句就知道差别了 像R1这样的寄存器就十几个,只有在需要使用的时候才会被赋值。 如果你的程序需要避免上述情况,那就加volatile,确保操作正确 如果你的程序不会出现上述情况,那就不加volatile,这样编译器会优化变量操作,提供速度,一般情况下都不用volatile 关于volatile的使用可以百度一下,讲的比我详细 |
|
|
|
表示volatile修饰符,在STM库里__IO宏定义volatile
|
|
|
|
没搞明白,为什么有些要加volatile修饰符,有写不用?
|
|
|
|
加volatile修饰符的基本作用就是不会被编译器优化,确保变量申请在内存中,每次访问该值的时候都是去内存中访问,而不是去寄存器中(编译器为了优化,会把变量值放到寄存器中并直接访问)
|
|
|
|
好像还是没有特别明白,申请变量在内存中?你说的内存是哪个内存?是闪存还是SRAM啊?你说会把变量值放到寄存器中,还可以这样的吗?STM32有多少空间寄存器可以用来存放变量啊?
另外,一般什么情况下要加__IO?什么情况下可以不加啊? |
|
|
|
ianhom高手啊,看了之后明白很多了。。。
|
|
|
|
厉害!
|
|
|
|
茅塞顿开啊
|
|
|
|
|
|
|
|
是的啊,另外我看库函数里面的寄存器变量的定义,也都加了volatile。
|
|
|
|
那还请问
#define __O volatile /*!< defines 'write only' permissions */ #define __IO volatile /*!< defines 'read / write' permissions */ 这两个有什么区别?定义的不是同一个类型吗 |
|
|
|
那还请问
#define __O volatile /*!< defines 'write only' permissions */ #define __IO volatile /*!< defines 'read / write' permissions */ 这两个有什么区别?定义的不是同一个类型吗 |
|
|
|
两个宏定义在代码预处理完成之后是一样的,都只是用了volatile来修饰。
这里用两个不同的宏名定义同一个volatile,是为了从代码阅读的角度做区别,帮助理解意图,__O表明'write only'权限,__IO表明'read / write'权限 |
|
|
|
|
|
|
|
虽然现在还是不怎么明白 我先留着这个问题 谢谢啦
|
|
|
|
之前不是有一篇譬喻的很好,好像也在這個論壇
類似是說 一個作業員每隔10分鐘要去查表作一次記錄 忽然主管詢問他"現在"表的值是多少 如果有volatile =>作業員一定要再去查表後才能回報主管 (速度慢) 沒有volatile =>作業員根據上一次的記錄回報主管 (速度快,但數值可能已經不一樣了) 如果某的位址裡面存放的數據是會被硬體改變的(狀態寄存器之類的...) 那就必須加上volatile修飾的...不然讀取該位址時有可能會拿通用寄存器裡的數值.. |
|
|
|
学习了.
|
|
|
|
一般中断里用到的变量,中断函数中调用其他函数用到的变量,要用volatile,否则会有意想不到的问题。
|
|
|
|
volatile关键字:说明变量在程序执行中可被隐含地改变。
/*STM32F10x 固件库旧的变量类型 (为了传统目的而维护) / typedef int32_t s32; typedef int16_t s16; typedef int8_t s8; typedef const int32_t sc32; /*!< Read Only */ typedef const int16_t sc16; /*!< Read Only */ typedef const int8_t sc8; /*!< Read Only */ typedef __IO int32_t vs32; typedef __IO int16_t vs16; typedef __IO int8_t vs8; typedef __I int32_t vsc32; /*!< Read Only */ typedef __I int16_t vsc16; /*!< Read Only */ typedef __I int8_t vsc8; /*!< Read Only */ typedef uint32_t u32; typedef uint16_t u16; typedef uint8_t u8; typedef const uint32_t uc32; /*!< Read Only */ typedef const uint16_t uc16; /*!< Read Only */ typedef const uint8_t uc8; /*!< Read Only */ typedef __IO uint32_t vu32; typedef __IO uint16_t vu16; typedef __IO uint8_t vu8; typedef __I uint32_t vuc32; /*!< Read Only */ typedef __I uint16_t vuc16; /*!< Read Only */ typedef __I uint8_t vuc8; /*!< Read Only */ //#ifndef __cplusplus typedef enum {FALSE = 0, TRUE = !FALSE} bool; //#endif //typedef enum {FALSE = 0, TRUE = !FALSE} BOOL; typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus; typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; #define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE)) typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus; /*STM32F10x 固件库旧的宏定义 (为了传统目的而维护) / #define HSEStartUp_TimeOut HSE_STARTUP_TIMEOUT #define HSE_Value HSE_VALUE #define HSI_Value HSI_VALUE |
|
|
|
只有小组成员才能发言,加入小组>>
请问下图大疆lightbridge2遥控器主板电源芯片型号是什么?
4466 浏览 1 评论
使用常见的二极管、三极管和mos做MCU和模组的电平转换电路,但是模组和MCU无法正常通信,为什么?
342浏览 2评论
为了提高USIM卡电路的可靠性和稳定性,在电路设计中须注意的点有哪些?
344浏览 2评论
368浏览 2评论
362浏览 2评论
407浏览 2评论
小黑屋| 手机版| Archiver| 德赢Vwin官网 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-21 19:48 , Processed in 1.434185 second(s), Total 113, Slave 96 queries .
Powered by 德赢Vwin官网 网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
德赢Vwin官网 观察
版权所有 © 湖南华秋数字科技有限公司
德赢Vwin官网 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号