Cortex-M0的BOD中断及重启-掉电检测的可利用性+BOD汇编启动

简介: 掉电检测的可利用性

BOD

Brown-Out Detection,又称掉电检测,一般用来检测单片机电源掉到一定电压之后执行相应操作。

有些产品由于受外围电路的影响,在断电时会存在残余电压,使得单片机仍能运行(一般情况下是外设停止,但内核运行),这样变会出现单片机无法正常复位,更严重点如果电压不稳会导致内核pc指针跑飞,造成程序灾难。

为了避免这个现象,我们可以在单片机程序中加入BOD检测功能,使单片机在检测到掉电到一定电压后,能够执行复位操作。

BOD分为几个等级:如下

#define BOD_INT_RESV    (0 << 2)                                        /* Reserved                     */
#define BOD_INT_LVL1    (1 << 2)                                        /* 2.3 ~2.4                     */
#define BOD_INT_LVL2    (2 << 2)                                        /* 2.6 ~2.7                     */
#define BOD_INT_LVL3    (3 << 2)                                        /* 2.8 ~2.9                     */
                                                                        /* BOD复位电压                  */
#define BOD_RST_RESV    (0 << 0)                                        /* Reserved                     */
#define BOD_RST_LVL1    (1 << 0)                                        /* 2.1 ~2.2                     */
#define BOD_RST_LVL2    (2 << 0)                                        /* 2.4 ~2.5                     */
#define BOD_RST_LVL3    (3 << 0)                                        /* 2.6 ~2.8                     */

我们可以根据自己的需要选择不同的等级,需要考虑的是外设的工作电压,如E2Prom,Flash等。

BOD初始化代码如下,一般放置在main函数的初始进行初始化。笔者用的是NXP的一款芯片。

void BODInit(void)
{
    LPC_SYSCON->BODCTRL = BOD_INT_LVL3 |                                /* BOD中断电压2.8 ~ 2.9         */
                          BOD_RST_LVL2 |                                /* BOD复位电压2.4 ~ 2.5         */
                          BOD_RST_ENABLE;                               /* BOD复位功能使能              */
    
    NVIC_EnableIRQ(BOD_IRQn);                                           /* 打开BOD中断                  */
}



int main (void)
{
    SystemInit();                                                       /* 初始化目标板,切勿删除       */
    GPIOInit();                                                         /* GPIO初始化                   */
    BODInit();                                                          /* BOD初始化                    */
    
    if ((LPC_SYSCON->SYSRSTSTAT & BOD_RESET) == BOD_RESET) {            /* 掉电复位,LED闪烁            */
        LPC_SYSCON->SYSRSTSTAT  |= BOD_RESET;                           /* 清除掉电复位标志位           */
        while (1) {
            LPC_GPIO_PORT->PIN[0] &= ~LED;                              /* 点亮LED                      */
            myDelay(100);                                               /* 延时 100ms                   */
            LPC_GPIO_PORT->PIN[0] |=  LED;                              /* 熄灭LED                      */
            myDelay(100);                                               /* 延时 100ms                   */
        }
    } else {
        while (1) {
            LPC_GPIO_PORT->PIN[0] &= ~LED;                              /* 上电复位,点亮LED            */
        }
    }
}

关于BOD汇编启动

既然我们可以在初始化的时候配置BOD的参数,那为什么还需要用汇编启动呢?

考虑之一是单片机内核从启动代码启动到运行到main函数的时候,需要有及ms的延时,虽然时间在ms级,但是对于一些严格要求的程序和产品,芯片在上电时由于电压抖动会导致芯片PC值跑飞,由于此时还没有初始化BOD,因此无法完成复位。

解决办法之一便是在启动代码中增加BOD初始化,使BOD在运行在main函数之前便完成初始化,可防止上电电压抖动造成的不必要的影响。

启动代码中汇编BOD的初始化代码如下。

首先声明BOD初始化程序。

; Cortex-M version
;

        MODULE  ?cstartup

        ;; Forward declaration of sections.
        SECTION CSTACK:DATA:NOROOT(3)

        SECTION .intvec:CODE:NOROOT(2)

        EXTERN  __iar_program_start
        EXTERN  SystemInit
        EXTERN  BODInit      //声明BOD函数
        EXTERN  IRC_Only_SystemInit

        PUBLIC  __vector_table
        PUBLIC  __vector_table_0x1c
        DATA
__vector_table
        DCD     sfe(CSTACK)                 ; Top of Stack
        DCD     Reset_Handler               ; Reset Handler
        DCD     NMI_Handler                 ; NMI Handler
        DCD     HardFault_Handler           ; Hard Fault Handler

然后在程序执行main之前加入执行BODinit的代码段。

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Default interrupt handlers.
;;
        THUMB
        
        PUBWEAK Reset_Handler
        SECTION .text:CODE:REORDER:NOROOT(2)
Reset_Handler
        LDR     R0, =BODInit          //加入BODInit 此函数体在main中
        BLX     R0
        LDR     R0, =SystemInit
        BLX     R0
        LDR     R0, =__iar_program_start
        BX      R0

这样便可完成BOD的汇编启动。

相关文章
|
2天前
|
Unix 编译器 Linux
操作系统的启动和中断
操作系统的启动和中断
20 0
|
2天前
|
监控
硬件看门狗--保护你的硬件不宕机
常用的都是软件看门狗,需要依赖MCU内部的独立看门狗或者窗口看门狗,本次使用的是硬件看门狗,硬件上更加稳定可靠
|
7月前
|
传感器 调度
什么是中断系统?
一、什么是中断系统 中断系统是计算机系统中的一种机制,它允许外部设备和程序请求处理器的注意力,以便进行特定的操作。当一个中断请求被触发时,处理器会暂停当前正在执行的程序,转而执行与中断相关的程序或服务例程。中断系统可以提高计算机系统的效率和响应速度,因为它允许处理器在等待某些事件的同时执行其他任务。常见的中断包括硬件中断(例如键盘输入、鼠标移动、网络数据传输等)和软件中断(例如操作系统调度、系统调用等)。 二、中断系统的特点 中断系统具有以下特点: 1. 实时性:中断系统能够及时响应外部设备的请求,提高计算机系统的响应速度和效率。 2. 可靠性:中断系统能够保证中断请求的可靠性,确保外部设备的
190 0
|
8月前
|
Windows Python
MicroPython 玩转硬件系列3:上电自动执行程序
MicroPython 玩转硬件系列3:上电自动执行程序
|
8月前
|
存储 缓存 Linux
RISC-V SiFive U54内核——中断和异常详解
RISC-V SiFive U54内核——中断和异常详解
|
9月前
定时中断实验【嵌入式系统】
定时中断实验【嵌入式系统】
66 0
|
存储 负载均衡 安全
MIPS架构深入理解6-异常和中断
MIPS架构深入理解6-异常和中断
|
Shell
vxworks错误状态
vxworks错误状态
272 0
vxworks错误状态
|
内存技术
【嵌入式】位带操作+咬尾中断+晚到中断 解析
位带操作 什么是位带操作? 对32MB SRAM 别名区的访问映射为对1MB SRAM的bit-band 区的访问。 对32MB 外设别名区的访问映射为对1MB 外设bit-band 区的访问。
635 0
详解中断系统
本文针对地详解了中断系统
223 0