STM8单片机复位源判断

最近在调试系统的时候,发现单片机老是复位,于是想着用程序来判断一个单片机的复位信号是来自于哪里。查找资料发现STM8单片机的复位源总共有9种

●NRST引脚产生的外部复位
● 上电复位(POR)
● 掉电复位(BOR)
● 独立看门狗复位
● 窗口看门狗复位
● 软件复位
● SWIM复位
● 非法操作码复位
● EMS复位:当一些关键的寄存器被破坏或错误加载时产生的复位

但是这9种复位源通过复位寄存器能看到的只有5种

复位状态寄存器(RST_SR)

位7:5 保留,必须保持为0。
位4 EMCF:EMC复位标志
位3 SWIMF:SWIM复位标志位
位2 ILLOPF:非法操作码复位标志位
位1 IWDGF:独立型看门狗复位标志位
位0 WWDGF:窗口型看门狗复位标志位
 

由于单片机没有用到看门狗,所以这两种看门狗复位用不到,SWIM复位是烧写程序或者仿真时用的。那就只剩下一个EMC复位、非法操作码复位可以判断。但是更希望看到的是单片机是电源不稳引起的掉电复位还是单片机复位引脚被干扰引起的NRST复位。但是寄存器中没有可以判断这两种复位源的标志位。那么能不能自己想办法来判断这两种复位源呢?

  首先分析一下掉电复位和NRST复位的区别,掉电复位也就是单片机完全断电,复位后内存中所有的东西会丢失。NRST复位时内存数据没有丢失,内存中的东西还是复位前存储的数据。那么根据这个特性是不是可以在内存中某个地址存数一个标志。复位后去读取这个标志,如果这个标志和存放的一样,说明单片机没有掉电,属于NRST复位。如果读取到的值不是存储的值那么说明单片机断电了,内存中存储的内容丢失了,属于掉电复位。那么这样就能区分开是掉电复位还是NRST复位了。

写个程序测试了一下,测试结果符合预期。

测试代码如下:

#include "iostm8s103F3.h"
#include "main.h"
#include "uart.h"
#include "stdio.h"

void SysClkInit( void )
{
    CLK_SWR = 0xe1;                  //HSI为主时钟源  16MHz CPU时钟频率
    CLK_CKDIVR = 0x00;               //CPU时钟0分频,系统时钟0分频
}

void main( void )
{
    __asm( "sim" );                             //禁止中断
    SysClkInit();
    Uart1_Init( 9600 );
    __asm( "rim" );                             //开启中断
    
    //复位源判断
    if( ( * ( u16* )( 0x000102 ) ) == 0x55 )    //判断0x000100这个地址中存储的值是不是0x55
    {
        printf( " key reset!\r\n" );                     //值等于0x55说明是程序写进去的,属于按键复位
    }
    else                                                        //如果这个地址的值不等于0x55 说明单片机是刚上电
    {
      printf( " power reset!\r\n" );                  //属于上电复位 然后将指定的值写入指定的地址,若单片机不断电,这个值就会一直保持不变
        * ( u16* )( 0x000102 ) = 0x55;
    }
    if( RST_SR_WWDGF )
    {
        printf( "wwdg reset!\r\n" );
    }
    if( RST_SR_IWDGF )
    {
        printf( "iwdg reset!\r\n" );
    }
    if( RST_SR_ILLOPF )
    {
        printf( "illop reset!\r\n" );
    }
    if( RST_SR_SWIMF )
    {
        printf( "swim reset!\r\n" );
    }
    if( RST_SR_EMCF )
    {
        printf( "emcf reset!\r\n" );
    }
    //WWDG_CR = 0x80;                    //启动独立看门狗
    //  IWDG_KR = 0xCC;                   //启动窗口看门狗
    while( 1 )
    {
    }
}


每次上电后先判断 0x000102 这个地址的值是不是0x55,如果不是说明单片机是刚上电,内存中的值是随机的。于是将0x000102这个地址中的值改为0x55,如果下一次单片机复位后读到这个地址的值是0x55的话,说明单片机没有掉电。属于复位引脚引起的复位。0x000102这个地址必须保证不会被程序用到,要不然在程序执行过程中值被改写,下次单片机复位后读到的值就不是0x55了。

其余的复位源直接去读取寄存器就可以了。

发布了76 篇原创文章 · 获赞 30 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_20222919/article/details/86548616