单片机变量不被初始化的实现方法

2023-05-16

关注+星标公众,不错过精彩内容

8c559681f2caa46c2b6e16c7c185a2ab.jpeg

作者 | strongerHuang

微信公众号 | strongerHuang

最近有读者问了一个这样的问题:看门狗复位之后,能不能保持复位之前的状态?

这种问题,或者类似的问题,相信很多小伙伴都经历过,特别是有多年单片机开发经验的小伙伴,而且现实中的很多项目确实有这样的需求。

实现的方法有很多种,这里给大家讲讲在Keil、 IAR编译环境下,单片机变量不被初始化的实现方法。

处理器复位

处理器复位的方式有很多种,这里结合STM来讲述MCU复位的来源:

STM32的复位为三类:系统复位、电源复位和后备域复位

系统复位:

1. NRST引脚上的低电平(外部复位)

2. 窗口看门狗计数终止(WWDG复位)

3. 独立看门狗计数终止(IWDG复位)

4. 软件复位(SW复位)

5. 低功耗管理复位

电源复位:

1. 上电/掉电复位(POR/PDR复位)

2. 从待机模式中返回

备份区域复位:

1. 软件复位,备份区域复位可由设置备份域控制寄存器(RCC_BDCR)中的BDRST位产生。

2. 在VDD和VBAT两者掉电的前提下, VDD或VBAT上电将引发备份区域复位。

请参考《STM32复位来源,Cotrex-M系统与内核复位区别》。

修饰符

实现处理器复位而变量不被初始化方法之前,让我们先了解一下修饰符的知识。

修饰符是用于限定类型以及类型成员申明的一种符号。如C语言中常见的修饰符:

1.static静态修饰符:修饰变量,函数。作用域:变量仅仅在本文件可见,函数在本文件可以被调用;

2.extern声明修饰符:修饰变量,函数。修饰变量时候,变量的声明在外面;

3.const常量修饰符:修饰变量,函数。修饰变量时候,不能被重复赋值,只能放在只读段中;

4.volatile不稳定变量修饰符:这个变量不好翻译,在c中的作用大概有两点意思:A.表示变量是易失的,易变的; B.强制访存操作,防止编译器去优化,告诉编译器每次必须去内存中取值,而不是从寄存器或者缓存。

其实,在C++  JAVA中还有更多:

public公共访问修饰符、private私有访问修饰符、protected保护访问修饰符、friendly、abstract等。

而本文会使用到一个修饰符:

__no_init

虽然这个修饰符不是C语言标准的修饰符,但在Keil、IAR这种集成开发环境中,他们支持这种修饰符。

而本文说的修饰符,修饰的变量位于RAM中:

在默认情况下,编译器会将其变量存放在主RAM中,并在启动时对其进行初始化。而__no_init类型修饰符使编译器把变量放在非易失RAM区中,在启动时也不对它们进行初始化,也就是说__no_init在系统启动时不初始化变量。

Keil中__no_init的配置和使用

在Keil中,__no_init不是标准的修饰符,需要进行配置,配置之后就可以使用了。

1.宏定义__no_init

#define __no_init __attribute__((zero_init))

2.在工程选项中配置__no_init

Project -> Options for Targets -> Target,里面右下有个NoInit,这个就是需要我们配置的区域(可设定某一区域);

2ea89077eb6a5118623e977a40e7f558.png

3.使用方法

比如定义变量:Cnt_NoInit

__no_init uint16_t Cnt_NoInit;

提示:不能初始化这个变量(也就是定义时不要赋值)。

IAR中中使用__no_init

在IAR中“__no_init”属于是一个关键字,你会发现在使用这个修饰符之后,字体都是关键字颜色。

直接使用即可,类似上面定义一个不被初始化的变量:

__no_init uint16_t Cnt_NoInit;

参考源码

这里给大家分享两个简单的Demo(源码),Keil和IAR工程实现的功能一样。

源代码:

__no_inituint16_t Cnt_NoInit;
uint16_t Cnt_Init = 100;


int main(void)
{
  System_Initializes();
  printf("Start...\n");  //复位打印


  while(1)
  {
    printf("Cnt_NoInit = %d\n", Cnt_NoInit);   //打印变量
    Cnt_NoInit++;


    if(Cnt_NoInit > 1000)
    {
      Cnt_NoInit = 0;
    }


    printf("Cnt_Init = %d\n", Cnt_Init);
    Cnt_Init++;
    if(Cnt_Init > 1000)
    {
      Cnt_Init = 0;
    }


    LED_ON;  
    TIMDelay_Nms(500);
    LED_OFF;
    TIMDelay_Nms(500);
    NVIC_SystemReset(); //系统复位
  }
}

被Cnt_NoInit修饰,则会打印如下消息:

Start...
Cnt_NoInit = 0
Cnt_Init = 100


Start...
Cnt_NoInit = 1
Cnt_Init = 100


Start...
Cnt_NoInit = 2
Cnt_Init = 100


Start...
Cnt_NoInit = 3
Cnt_Init = 100

如果不被修饰:

uint16_t Cnt_NoInit;
uint16_t Cnt_Init = 100;

如果不被修饰:则会打印如下消息:

Start...
Cnt_NoInit = 0
Cnt_Init = 100


Start...
Cnt_NoInit = 0
Cnt_Init = 100


Start...
Cnt_NoInit = 0
Cnt_Init = 100


Start...
Cnt_NoInit = 0
Cnt_Init = 100

相信聪明的你,看了上面例子会明白为什么没有初始化的变量“Cnt_NoInit”在变化,而初始化了的“Cnt_Init”一直不变。

------------ END ------------

6345fa6cd5a675370c0dea4f5cf35276.gif

●专栏《嵌入式工具

●专栏《嵌入式开发》

●专栏《Keil教程》

●嵌入式专栏精选教程

关注公众号回复“加群”按规则加入技术交流群,回复“1024”查看更多内容。

142632f4aa2f4fd7936798519c6273ec.jpeg

a4dae1266efcf83de8e4b4e634929967.png

点击“阅读原文”查看更多分享。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

单片机变量不被初始化的实现方法 的相关文章

随机推荐

  • 紧急!公开招录50名工程师升名校研究生!基层人员均可报名提升!

    2023全国高等教育 硕士研究生报名须知 教育部 国家发改委 财政部联合印发 关于加快新时代研究生教育改革发展的意见 xff0c 表示要将 硕士研究生招生规模稳步扩大 并且 xff0c 教育部明确提出要扩大研究生招生规模 为积极落实国家研究
  • 嵌入式开发,数据手册为啥是重要的文档?

    关注 43 星标公众号 xff0c 不错过精彩内容 作者 strongerHuang 微信公众号 strongerHuang 做嵌入式开发 xff0c 特别是底层驱动相关的开发 xff0c 不管是软件还是硬件工程师 xff0c 能熟练阅读数
  • 分享一款基于C语言实现的FIFO模块

    关注 43 星标公众号 xff0c 不错过精彩内容 作者 strongerHuang 微信公众号 strongerHuang FIFO在嵌入式应用的非常广泛 xff0c 可以说有数据收发的地方 xff0c 基本就有FIFO的存在 xff0c
  • 免费开源EDA软件KiCad 7.0.2 发布、Qt 6.2.8 LTS版本正式发布

    免费开源EDA软件KiCad 7 0 2 发布 Nordic推出第四代低功耗无线SoC Qt 6 2 8 LTS版本正式发布 xff08 点击链接 xff0c 阅读原文 xff09 更多视频 xff0c 可以到我视频号查看 xff1a 点击
  • hadoop中输入文件用LongWritable和IntWritable的区别

    xfeff xfeff 这里的LongWritable的key是线的偏移量 xff0c 表示该行在文件中的位置 xff0c 而不是行号 这里的IntWritable的key是行号
  • 嵌入式开发常用的几款虚拟机

    关注 43 星标公众号 xff0c 不错过精彩内容 作者 入门小站 说起虚拟机 xff0c 相信作为技术人员的小伙伴们不会感到陌生 虚拟机的使用场景非常多 xff0c 如搭建测试环境 在 Windows 系统中安装 Linux 或在 Mac
  • "软件开发生命周期"有几个阶段?

    关注 43 星标公众号 xff0c 不错过精彩内容 作者 情报小哥 ID 嵌入式情报局 很多初学软件编程的小伙伴 xff0c 只顾着 编程 xff0c 其他开发相关的一些 技能 很少关注 如果你想以后进入大公司 xff0c 除了写代码之后
  • GUI付费与免费的选择,看了价格你就知道了

    更多视频 xff0c 可以到我视频号查看 xff1a 点击 阅读原文 查看更多分享
  • 通信协议考虑的几点问题

    关注 43 星标公众号 xff0c 不错过精彩内容 素材来源 网络 来源 嵌入式大杂烩 嵌入式开发在很多场景下都需要进行通讯 xff0c 那么通讯协议就必不可少 xff0c 有代表性的通讯协议是如下三种 xff1a 从上表可以看到 xff0
  • 带你看看“了不起的”芯片!

    今天给大家分享一本新书 了不起的芯片 xff0c 文末再送大家5本 xff01 任何一本书的背后都有一段不为人知的曲折故事 xff0c 在此和大家分享一下本书作者写这本书的心路历程 01 为什么要写这本书 xff1f 这是一个人人都在谈论芯
  • Wireshark几个常用技巧

    关注 43 星标公众号 xff0c 不错过精彩内容 作者 假面生 素材来源 CSDN 经典的开源的网络抓包工具 Wireshark 相信大部分人 xff08 或者搞过网络 xff09 的人都知道它 xff0c 用过的人基本了解它的强大功能
  • 预约直播 | 2023年STM32峰会线上直播开启报名!

    点击上方 关注STM32 点击下方文章了解峰会详情 xff1a 速速报名 xff5c 与创新邂逅 xff0c 与生态交融 xff0c 来STM32峰会激发你的创造力 先睹为快 xff01 STM32 中国峰会精彩DEMO导引 文末有奖 约吗
  • 一视频带你了解Apache开源协议

    更多视频 xff0c 可以到我视频号查看 xff1a 点击 阅读原文 查看更多分享
  • 嵌入式程序上下文切换和解耦的工具

    关注 43 星标公众号 xff0c 不错过精彩内容 作者 NevermindZZT C语言是一种面向过程的语言 xff0c 做嵌入式项目的时候 xff0c 如果不变相面向对象 xff0c 项目到后期很难做好 xff0c 且不容易维护 今天就
  • 嵌入式开发成本太高

    关注 43 星标公众号 xff0c 不错过精彩内容 作者 strongerHuang 微信公众号 strongerHuang 最近一段时间 xff0c 给大家整理了一些嵌入式开发常用软件工具的价格 xff0c 有网友直呼 xff1a 嵌入式
  • 服务交付的项目:建立PM牢固的客户关系

    在竞争激烈的市场中 xff0c 基于服务的企业需要利用任何机会将自己与 xff08 通常非常相似的 xff09 竞争对手区分开来 虽然实施 系统细节和服务管理都很重要 xff0c 但也许区分您的业务的最佳方式是根据您的服务质量建立牢固的客户
  • ST发布新的工具链和软件包、Source Insight难得一更新

    MicroPython 诞生 10 周年 ST发布新的工具链和软件包 Source Insight难得一更新 xff08 点击链接 xff0c 阅读原文 xff09 更多视频 xff0c 可以到我视频号查看 xff1a 点击 阅读原文 查看
  • 蓝牙演进及其发展史

    关注 43 星标公众号 xff0c 不错过精彩内容 来源 ittbank 目前 xff08 2023年5月 xff09 xff0c 最新的蓝牙5 4标准已经出来了 xff0c 那么 xff0c 你知道蓝牙这些年都经历过什么吗 xff1f 下
  • 嵌入式固件升级防变砖的几种方法

    关注 43 星标公众号 xff0c 不错过精彩内容 来源 CSDN 汽车软件Boot程序的主要作用是刷新App程序 在一个具体客户项目中 xff0c Boot也是客户需求的一部分 xff0c 跟随项目也有软件开发计划 xff08 有的为了和
  • 单片机变量不被初始化的实现方法

    关注 43 星标公众号 xff0c 不错过精彩内容 作者 strongerHuang 微信公众号 strongerHuang 最近有读者问了一个这样的问题 xff1a 看门狗复位之后 xff0c 能不能保持复位之前的状态 xff1f 这种问