B001-Atmega16-带电复位后不清0的.noinit变量

发布者:SereneMeadow7最新更新时间:2022-02-12 来源: eefocus关键字:Atmega16 手机看文章 扫描二维码
随时随地手机看文章

AVR单片机原理与GCC编程实践》P117讲到AVR代码段时,提到了.bss段中包含了一个很有意思的.noinit段。


.noinit段描述:

.bss段的变量在芯片启动的 .init4阶段会被清0,但是定义在 .bss的 .noinit段中的变量在 .init4阶段不会被清0。

单片机不掉电复位后, .noinit段的这些变量的值依然存在,可以继续使用。


.noinit段的定义方法:int bar __attribute__ ((section (".noinit")));


不能指定初值,因为这些变量是在 .bss段。


.noinit段变量的复位测试:

也就是说、如果我在.noinit段定义一个变量,按下开发板的复位键(单片机不掉电复位),这个变量的值不会被清0。


下面是测试代码,我在.noinit段定义了变量bar,初值未知。


8bit的bar正好可以用连接在PORTB的8个LED灯来显示它的数值。


每次进入程序后、bar++,所以每按一次复位键,bar对应的8个LED灯的二进制数值就加1(二进制计数器)。


测试代码:

#include

uint8_t bar __attribute__ ((section(".noinit")));

 

int main(void)

{

    bar++;

    DDRB  = 0xFF;

    PORTB = 0xFF;

    PORTB = bar;

    while(1)  {  }

    return 0;

}


测试结果:

我的8个LED是低推的,所以点亮的LED对应的引脚逻辑值是0,熄灭的LED对应的引脚逻辑值是1。


于是得到下面的结果:

程序下载到开发板后,这一次bar的初值是00000001(这次比较巧),每按一次复位键,bar的值都加1了。


重新下载程序后,bar的初值也会自己加1,也相当于单片机不掉电复位。


------------------------------------------------------------------------------------------------------------------------

使用.noinit特性测试BOD掉电:

2016.05.30


今天发现.noinit的特性还可以测试BOD掉电。


依然是使用上面的代码中的.noinit,加上PA0输出脉冲,同时查看PORTB的二进制计数器来得知复位次数。


代码如下:

int main(void)

{

    // PA0为输出口

    DDRA  = (IO_OUTPUT << DDA0);

 

    // 记录复位次数

    _noinit_using();

 

    while(1)

    {

        // PA0拉高

        PORTA = (1 << PA0);

        // 维持0.5秒

        delay_ms(500);

        // PA0拉低

        PORTA &= ~(1 << PA0);

        // 维持0.5秒

        delay_ms(500);

    }

    return 0;

}

其中的_noinit_using()如下:


volatile uint8_t v_noinit __attribute__ ((section(".noinit")));

 

// ==========================================================================================================

// 通过观察PORTB上的8位LED的状态得知复位次数

// ==========================================================================================================

void _noinit_using(void)

{

    v_noinit++;

    // 8位LED,低推

    DDRB  = 0xFF;

    PORTB = 0xFF;

    PORTB = v_noinit;

}

测试结果:

1、当前芯片BOD监测的电压是4.0V

2、使用.noinit可以测试复位次数(二进制计数器)

3、每次将电压源电压低到<3.7V,就会引发复位,而PORTB的二进制计数器就会加1

4、而且低到1V以下,复位后依然可以记住上一次的.noinit变量的值,大概是没有完全掉电的缘故

5、正常工作时可以看到PA0的脉冲,复位时中断。


------------------------------------------------------------------------------------------------------------------------

使用.noinit特性测试看门狗WDT:

在另一篇测试WDT效果的文章中,还是用这个.noinit+二进制计数器的方法测试了WDT的复位:


http://blog.csdn.net/manon_des_source/article/details/51540217

关键字:Atmega16 引用地址:B001-Atmega16-带电复位后不清0的.noinit变量

上一篇:B001-Atmega16-中断(GCC-AVR)-(ques=3)
下一篇:B001-Atmega16-PORTA的定义-(ques=1)

小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved