0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

“看门狗“VS“打狗棒”,谁胜谁负?(STM32篇)—MCU抗干扰实验系列专题(3)

jf_09510355 来源:jf_09510355 作者:jf_09510355 2023-02-08 09:15 次阅读

后台有许多读者留言说先弄点干货。今天应读者要求,我们先来一篇干货。大家有什么要求,欢迎留言,关于MCU的应用、测试要求,我们都会尽量满足。

在上两期文章和视频中,为了公平起见,所有的MCU使用的是同一个工程程序,(不同的MCU,时钟和GPIO的配置略有不同,使用宏定义区分MCU),除了使用滴答时钟和基本GPIO操作外,没有任何抗干扰手段,全靠MCU内部自身的抗干扰能力进行的测试。结果,只有芯源CW32MCU没有彻底死机外,其它均有死机现象。

这种死机现象,在我们实际开发产品时,是禁止发生的。为了对付这种干扰,除了硬件上有些技术对策,那软件上又有些什么呢?

当然是我们最熟悉的看门狗了。“看门狗”这个神器在“古老的年代”51时期,那是没有的,需要在外面加一个“昂贵”的芯片来实现。当然,现在新时代,所有的ARM MCU基本上都标配了看门狗外设。

看门狗是啥,我们来看一下,STM32芯片的用户手册,关于看门狗的介绍。

poYBAGPC2hqAB2FxAATprU4H4t4143.png

▲图1

这里我们就不详细展开其内容了。直接来看核心代码。

 
//摘要:
/*
系统时钟,使用内部高速HSI倍数,系统时钟为48M。
*/
//Programed by Cache.Lee 2023.1.4

#include "stm32f0xx.h"
#include "stm32f0xx_gpio.h"

//GPIOA
#define SEGA GPIO_Pin_10
#define SEGB GPIO_Pin_9
#define SEGC GPIO_Pin_8

//GPIOB
#define SEGD GPIO_Pin_14
#define SEGE GPIO_Pin_15

//GPIOA
#define SEGF GPIO_Pin_11
#define SEGG GPIO_Pin_12

//GPIOB
#define SEGDP GPIO_Pin_13

//num:需要显示的数字,no:0显示左边数码管,1显示右边数码管
void SEG_DisplayNum(unsigned int num, unsigned int no)  
{
    GPIO_ResetBits(GPIOA,0xffff);//关段码、位码
    GPIO_ResetBits(GPIOB,0xffff);//关段码、位码
  
    switch(num) //开段码
    {
        case 0: //ABCDEF
            GPIO_SetBits(GPIOA,SEGA|SEGB|SEGC|SEGF);
            GPIO_SetBits(GPIOB,SEGD|SEGE);
            break;        
        case 1: //BC
            GPIO_SetBits(GPIOA,SEGB|SEGC);
            break;        
        case 2: //ABDEG
            GPIO_SetBits(GPIOA,SEGA|SEGB|SEGG);
            GPIO_SetBits(GPIOB,SEGD|SEGE);
            break;        
        case 3: //ABCDG            
            GPIO_SetBits(GPIOA,SEGA|SEGB|SEGC|SEGG);
            GPIO_SetBits(GPIOB,SEGD);      
            break;
        case 4://BCFG
             GPIO_SetBits(GPIOA,SEGF|SEGB|SEGC|SEGG);         
            break;
        case 5://ACDFG
            GPIO_SetBits(GPIOA,SEGA|SEGC|SEGG|SEGF);
            GPIO_SetBits(GPIOB,SEGD);              
            break;
        case 6: //ACDEFG
            GPIO_SetBits(GPIOA,SEGA|SEGC|SEGG|SEGF);
            GPIO_SetBits(GPIOB,SEGD|SEGE);   
            break;
        case 7: //ABC
            GPIO_SetBits(GPIOA,SEGA|SEGB|SEGC);
           break;
        case 8: //ABCDEFG
            GPIO_SetBits(GPIOA,SEGA|SEGB|SEGC|SEGG|SEGF);
            GPIO_SetBits(GPIOB,SEGD|SEGE); 
            break;
        case 9: //ABCDFG
            GPIO_SetBits(GPIOA,SEGA|SEGB|SEGC|SEGG|SEGF);
            GPIO_SetBits(GPIOB,SEGD); 
           break;
        case 10: //DP 显示DP  
           GPIO_SetBits(GPIOB,SEGDP); 
           break;
        default:
            break;          
    }
    if(no==1)
       GPIO_SetBits(GPIOB,GPIO_Pin_12);
    else 
       GPIO_SetBits(GPIOB,GPIO_Pin_11);//关位码
}

void GPIOInit(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;

  //数码管断码位码 IO初始化
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);   
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);


  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
}


int main(void)
{
  unsigned long i;
  unsigned int num=0;

  for(i=0;i<60000;i++);   //上电延时
  GPIOInit();  

  /* IWDG timeout equal to 250 ms (the timeout may varies due to LSI frequency
     dispersion) */
  /* Enable write access to IWDG_PR and IWDG_RLR registers */
  IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);

  /* IWDG counter clock: LSI/32 */
  IWDG_SetPrescaler(IWDG_Prescaler_32);

  /* Set counter reload value to obtain 250ms IWDG TimeOut.
     Counter Reload Value = 250ms/IWDG counter clock period
                          = 250ms / (LSI/32)
                          = 0.25s / (LsiFreq/32)
                          = LsiFreq/(32 * 4)
                          = LsiFreq/128
   */
  IWDG_SetReload(40000/128);
  /* Reload IWDG counter */
  IWDG_ReloadCounter();
  /* Enable IWDG (the LSI oscillator will be enabled by hardware) */
  IWDG_Enable();
  SEG_DisplayNum(10,1);
  for(i=0;i<60000;i++);  

  while(1)
  {


     num++;
     if(num>=100)num=0;
      SEG_DisplayNum(num/10,0);
      for(i=0;i<60000;i++);   //延时

      SEG_DisplayNum(num%10,1);
      for(i=0;i<60000;i++);   //延时

      SEG_DisplayNum(num/10,0);
      for(i=0;i<60000;i++);   //延时    
      IWDG_ReloadCounter(); //喂狗 

      SEG_DisplayNum(num%10,1);
      for(i=0;i<60000;i++);   //延时

      SEG_DisplayNum(num/10,0);       
      for(i=0;i<60000;i++);   //延时

      SEG_DisplayNum(num%10,1);
      for(i=0;i<60000;i++);   //延时
      IWDG_ReloadCounter();  //喂狗 
  }
}

这里的代码与上期代码不同,我们使用官方标准库来重新编写。其中数码管的动态扫描没有使用滴答时钟,而是在主程序中直接用延时来完成。区别于之前的代码,我们增加了独立看门狗的功能。看门狗的喂狗操作在MAIN函数的大循环里,数码管的动态扫描中实现。

当程序发生死机时,MAIN函数的大循环将暂停运行,数码管随机显示最近一次数值,不进行动态扫描,所以,只有一位数码管显示。同时,喂狗暂停。当看门狗时间到,将发生看门狗复位操作,系统将重新复位运行。这样程序就实现了看门狗复位功能。

在实验中,由于打狗棒电压干扰的威力巨大,STM32芯片被打坏了几个引脚。驱动A、F、G的端口功能异常,而且芯片略烫,应该是引脚被打坏了。但不影响下载,其它位码显示正常。

除了看门狗复位,还有一种软件复位方式。当MCU发生硬件失效时,会进入Hardfault中数函数。Hardfault是优先级别为-1的固定类型中断,无需初始化设置。常常在MCU死机时,不知明的会进入Hardfault中断。因此,在Hardfault中断函数中,添加软件复位功能也是一种防死机现象的方法。代码如下



void HardFault_Handler(void)
{
  unsigned int j;
  /* Go to infinite loop when Hard Fault exception occurs */
  while (1)
  {
        SEG_DisplayNum(10,0);
        for(j=0;j<60000;j++);
        for(j=0;j<60000;j++);
        for(j=0;j<60000;j++);
        for(j=0;j<60000;j++);
        for(j=0;j<60000;j++);
        for(j=0;j<60000;j++);

        NVIC_SystemReset();  
  }
}

审核编辑黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • mcu
    mcu
    +关注

    关注

    146

    文章

    16984

    浏览量

    350251
  • 看门狗
    +关注

    关注

    10

    文章

    559

    浏览量

    70734
  • STM32
    +关注

    关注

    2266

    文章

    10870

    浏览量

    354736
  • 时钟
    +关注

    关注

    10

    文章

    1720

    浏览量

    131347
  • 抗干扰
    +关注

    关注

    4

    文章

    316

    浏览量

    34540
收藏 人收藏

    评论

    相关推荐

    看门狗VS打狗棒”,?(CW32)——MCU抗干扰实验系列专题(4)

    为了公平起见,所有的MCU使用的是同一个工程程序,(不同的MCU,时钟和GPIO的配置略有不同,使用宏定义区分MCU),除了使用滴答时钟和基本GPIO操作外,没有任何抗干扰手段,全靠
    的头像 发表于 01-17 13:16 3445次阅读
    “<b class='flag-5'>看门狗</b>”<b class='flag-5'>VS</b>“<b class='flag-5'>打狗棒</b>”,<b class='flag-5'>谁</b><b class='flag-5'>胜</b><b class='flag-5'>谁</b><b class='flag-5'>负</b>?(CW32<b class='flag-5'>篇</b>)——<b class='flag-5'>MCU</b><b class='flag-5'>抗干扰</b><b class='flag-5'>实验</b><b class='flag-5'>系列</b><b class='flag-5'>专题</b>(4)

    STM32中的独立看门狗和窗口看门狗是什么

    在早期的MCU中是没有看门狗这种东西的,所以产品就很容易出现死机,跑飞的情况。为了避免这种情况的出现,后期的MCU都集成了看门狗的功能。但是目前看门
    的头像 发表于 02-20 17:47 2667次阅读
    <b class='flag-5'>STM32</b>中的独立<b class='flag-5'>看门狗</b>和窗口<b class='flag-5'>看门狗</b>是什么

    MCU独立看门狗和窗口看门狗的区别

    早期的MCU没有看门狗,就容易引起有些产品死机了不能重启工作。为了避免这个问题,后期的MCU在内部集成了看门狗的功能。
    发表于 03-03 09:18 742次阅读

    关于独立看门狗的一点经验

    stm32基本都内置两种看门狗(另外还有外置的看门狗芯片),窗口看门狗和独立看门狗,两种看门狗
    发表于 05-09 11:18 613次阅读
    关于独立<b class='flag-5'>看门狗</b>的一点经验

    什么是stm32看门狗?独立看门狗和窗口看门狗工作原理解析

    stm32有两个看门狗,独立看门狗和窗口看门狗,其实两者的功能是类似的,只是喂狗的限制时间不同。 独立看门狗
    的头像 发表于 11-06 11:48 2.7w次阅读
    什么是<b class='flag-5'>stm32</b><b class='flag-5'>看门狗</b>?独立<b class='flag-5'>看门狗</b>和窗口<b class='flag-5'>看门狗</b>工作原理解析

    STM32看门狗配置(独立看门狗IWDG和窗口看门狗WWDG)

    stm32自带两个看门狗模块,独立看门狗IWDG和窗口看门狗WWDG。看门狗主要作用是可用来检测和解决由软件错误引起的故障;当计数器达到给定
    发表于 11-09 17:17 8414次阅读
    <b class='flag-5'>STM32</b><b class='flag-5'>看门狗</b>配置(独立<b class='flag-5'>看门狗</b>IWDG和窗口<b class='flag-5'>看门狗</b>WWDG)

    独立看门狗实验-IWDG-M3

    关于STM32独立看门狗实验文档
    发表于 11-27 15:30 3次下载

    MCU独立看门狗与窗口看门狗的区别

    早期的MCU没有看门狗,就容易引起有些产品死机了不能重启工作。为了避免这个问题,后期的MCU在内部集成了看门狗的功能。为了满足更多使用场景,现在很多
    发表于 10-28 20:06 8次下载
    <b class='flag-5'>MCU</b>独立<b class='flag-5'>看门狗</b>与窗口<b class='flag-5'>看门狗</b>的区别

    MCU独立看门狗与窗口看门狗的区别

    关注+星标公众号,不错过精彩内容素材来源 | STM32早期的MCU没有看门狗,就容易引起有些产品死机了不能重启工作。为了避免这个问题,后期的MCU在内部集成了
    发表于 10-29 10:51 2次下载
    <b class='flag-5'>MCU</b>独立<b class='flag-5'>看门狗</b>与窗口<b class='flag-5'>看门狗</b>的区别

    MCU】基于STM32CubeMX 实现窗口看门狗 WWDG

    ”表示看门狗递减计数器只能在一个窗口时间内完成刷新,否则MCU将复位。(2)窗口看门狗一般用来监测由外部干扰或不可预见的逻辑条件造成的应用背离正常运行序列而产生的软件故障。(
    发表于 11-01 16:24 10次下载
    【<b class='flag-5'>MCU</b>】基于<b class='flag-5'>STM32</b>CubeMX 实现窗口<b class='flag-5'>看门狗</b> WWDG

    STM32学习心得十六:独立看门狗实验

    记录一下,方便以后翻阅~主要内容:1) 独立看门狗概述;2) 常用寄存器和库函数配置;3) 独立看门狗实验代码解读。官方资料:《STM32
    发表于 12-27 18:44 6次下载
    <b class='flag-5'>STM32</b>学习心得十六:独立<b class='flag-5'>看门狗</b><b class='flag-5'>实验</b>

    STM32:独立看门狗、窗口看门狗的配置

    STM32单片机的看门狗有独立看门狗和窗口看门狗之分,这两者的工作原理却完全不同。
    发表于 02-08 16:15 18次下载
    <b class='flag-5'>STM32</b>:独立<b class='flag-5'>看门狗</b>、窗口<b class='flag-5'>看门狗</b>的配置

    STM32中的独立看门狗和窗口看门狗

    一、前言 在早期的MCU中是没有看门狗这种东西的,所以产品就很容易出现死机,跑飞的情况。为了避免这种情况的出现,后期的MCU都集成了看门狗的功能。但是目前
    的头像 发表于 12-22 16:58 2057次阅读

    STM32中的独立看门狗和窗口看门狗

    在早期的MCU中是没有看门狗这种东西的,所以产品就很容易出现死机,跑飞的情况。为了避免这种情况的出现,后期的MCU都集成了看门狗的功能。但是目前看门
    的头像 发表于 01-30 14:38 1322次阅读
    <b class='flag-5'>STM32</b>中的独立<b class='flag-5'>看门狗</b>和窗口<b class='flag-5'>看门狗</b>