每节课都是一个项目 手把手用STM32打造联网气象站-2-从点灯到volatile

1. 抛出问题

在学习C语言,或者面试C语言的时候,常常会遇到这样一个问题:

请解释一下volatile关键词的含义,以及它起到什么作用?

百度出来的答案往往是这样的

但是这个答案究竟在代码中起到什么作用?有什么意义?

2. 背景介绍

我们知道单片机代码中,一般有两种方式:带系统的和不带系统的。在稍微简单一些的项目,或者对时序要求很高的项目中,多采用不带系统的方式开发。在带有4G NBIOT 这些通信应用的项目中,由于往往会用到多个线程进行同步,采用带系统的居多。

不带系统的代码包含初始化部分和大循环部分。

在这个简单点灯代码中,初始化部分,完成了LED的初始化。大循环部分,不断调用LED(ON)和LED(OFF),中间加上SOFT_DELAY的延时,实现LED点亮和熄灭的效果。

SOFT_DELAY是通过Delay函数来定义的。

而Delay函数中,用到了__IO, 也就是volatile关键词修饰的变量。

下面问题来了:如果去掉这个volatile关键词修饰,LED闪烁频率会如何?

动画1:LED快速闪烁的效果

 

动画2:LED闪烁速度明显变慢

下面,具体的问题来了:

动画1和动画2中的代码,唯一的改变就是:其中一个注释掉了__IO,请问具体是哪一个注释掉了IO?快的那个,还是慢的那个?

3. 分析与解答

要回答这个问题,显然不能靠猜测。我们需要深入理解volatile关键词究竟起到什么作用才行。

当C编译器看到volatile关键词修饰的变量时,它就会知道,这个变量的值是常常会发生变化的(volatile英文含义为易变的)。因此,它就会试图从内存中,去操作和读取这个变量。而当这个词没有被修饰时,它会从寄存器中,直接操作这个变量。

由于寄存器的操作读取速度是大于内存操作读取速度的,因此当去掉关键词volatile之后,就会提高灯闪烁频率。

因此,闪灯慢的是volatile, 闪灯快的不带volatile。

4. 进一步探讨:编译优化

当我们在编译时,选择不同的优化选线,可能会导致LED闪烁频率变化。但是在实际测试中,肉眼并未发现具体的变化,估计可能需要用示波器才能够看出波形的变化。在这里就不展开了。可以从下面的链接进一步查看。

keil优化等级影响STM32 GPIO速度变化 - 知乎 (zhihu.com)

 5. 题外话-学习嵌入式的正确姿势

很多人觉得,多敲代码就可以提高学习嵌入式的效率。如果多敲代码能够改善学习效率的话,那最好的程序员应该是打字员。

学习嵌入式或者其他编程技术的最佳方式是:

1. 多做实验,将不同的代码功能实际运行一下,看看效果;

2. 多做代码整理:实验好的结果,一定要有条不紊的整理好,特别是代码模块的接口尽量单独列出来;

3. 多做代码复用:好的工程师是敲代码快么?不是的。好的工程师是在大脑里,还有电脑里,建议了很多功能模块,遇到问题后,可以非常方便的拿出模块,解决问题。学习编程的路径,不仅仅是学习语言,或者学习驱动,而是不断积累功能模块,并把功能模块反复复用,解决问题。

关注我,手把手带你完成智能气象站的设计。

  现在就动手,把对应工程编译下载试试看吧。

(24条消息) led点灯代码。代码简单,主要用来验证开发环境。开发环境采用vscode+keil,详见博文-嵌入式文档类资源-CSDN文库

纸上得来终觉浅,绝知此事要躬行!

接下来会一步一步带你完成家庭气象站的开发工作,敬请收藏关注,以免下次找不到了。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值