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

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

3天内不再提示

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

jf_09510355 来源:jf_09510355 作者:jf_09510355 2023-01-17 13:16 次阅读

上一期文章,我们讲了基于STM32的抗干扰方法:增加硬件失效时软件复位及看门狗功能。这期我们将介绍基于CW32 的抗干扰问题。

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

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

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

CW32在抗干扰测试时,也偶有自身复位现象。当然如果我们增加了看门狗抗干扰威廉希尔官方网站 ,那设计出来的产品不是更稳定吗!

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

poYBAGPGIZOATvvBAAOzOz6MGOE736.png

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

//系统时钟配置为48M HSI倍数
#include "main.h"
#include "cw32f030_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_WritePin(CW_GPIOA,0xffff,GPIO_Pin_RESET);//关段码、位码
    GPIO_WritePin(CW_GPIOB,0xffff,GPIO_Pin_RESET);//

switch(num) //开断码
    {
case 0: //ABCDEF
            GPIO_WritePin(CW_GPIOA,SEGA|SEGB|SEGC|SEGF,GPIO_Pin_SET);
            GPIO_WritePin(CW_GPIOB,SEGD|SEGE,GPIO_Pin_SET);
break;        
case 1: //BC
            GPIO_WritePin(CW_GPIOA,SEGB|SEGC,GPIO_Pin_SET);
break;        
case 2: //ABDEG
            GPIO_WritePin(CW_GPIOA,SEGA|SEGB|SEGG,GPIO_Pin_SET);
            GPIO_WritePin(CW_GPIOB,SEGD|SEGE,GPIO_Pin_SET);
break;        
case 3: //ABCDG            
            GPIO_WritePin(CW_GPIOA,SEGA|SEGB|SEGC|SEGG,GPIO_Pin_SET);
            GPIO_WritePin(CW_GPIOB,SEGD,GPIO_Pin_SET);      
break;
case 4://BCFG
             GPIO_WritePin(CW_GPIOA,SEGF|SEGB|SEGC|SEGG,GPIO_Pin_SET);         
break;
case 5://ACDFG
            GPIO_WritePin(CW_GPIOA,SEGA|SEGC|SEGG|SEGF,GPIO_Pin_SET);
            GPIO_WritePin(CW_GPIOB,SEGD,GPIO_Pin_SET);              
break;
case 6: //ACDEFG
            GPIO_WritePin(CW_GPIOA,SEGA|SEGC|SEGG|SEGF,GPIO_Pin_SET);
            GPIO_WritePin(CW_GPIOB,SEGD|SEGE,GPIO_Pin_SET);   
break;
case 7: //ABC
            GPIO_WritePin(CW_GPIOA,SEGA|SEGB|SEGC,GPIO_Pin_SET);
break;
case 8: //ABCDEFG
            GPIO_WritePin(CW_GPIOA,SEGA|SEGB|SEGC|SEGG|SEGF,GPIO_Pin_SET);
            GPIO_WritePin(CW_GPIOB,SEGD|SEGE,GPIO_Pin_SET); 
break;
case 9: //ABCDFG
            GPIO_WritePin(CW_GPIOA,SEGA|SEGB|SEGC|SEGG|SEGF,GPIO_Pin_SET);
            GPIO_WritePin(CW_GPIOB,SEGD,GPIO_Pin_SET); 
break;
case 10: //DP 显示DP  
           GPIO_WritePin(CW_GPIOB,SEGDP,GPIO_Pin_SET); 
break;
default:
break;          
    }
if(no==1)
        PB12_SETHIGH();//开位码
else
        PB11_SETHIGH();//开位码
}

void RCC_Configuration(void)
{
/* 0. HSI使能并校准 */
  RCC_HSI_Enable(RCC_HSIOSC_DIV6);

/* 1. 设置HCLK和PCLK的分频系数*/
  RCC_HCLKPRS_Config(RCC_HCLK_DIV1);
  RCC_PCLKPRS_Config(RCC_PCLK_DIV1);

/* 2. 使能PLL,通过PLL倍频到64MHz */
  RCC_PLL_Enable(RCC_PLLSOURCE_HSI, 8000000, 6);     // HSI 默认输出频率8MHz

  __RCC_FLASH_CLK_ENABLE();
  FLASH_SetLatency(FLASH_Latency_3);   

/* 3. 时钟切换到PLL */
  RCC_SysClk_Switch(RCC_SYSCLKSRC_PLL);
  RCC_SystemCoreClockUpdate(48000000);  
}


void GPIOInit(void)
{  
  GPIO_InitTypeDef GPIO_InitStruct;

  __RCC_GPIOB_CLK_ENABLE();
  __RCC_GPIOA_CLK_ENABLE();

//数码管断码位码 IO初始化
  GPIO_InitStruct.IT = GPIO_IT_NONE; //LED1 
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pins = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12;
  GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
  GPIO_Init(CW_GPIOA, &GPIO_InitStruct);  

  GPIO_InitStruct.Pins = GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
  GPIO_Init(CW_GPIOB, &GPIO_InitStruct);   
}


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

  IWDT_InitTypeDef IWDT_InitStruct = {0};  

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

  RCC_Configuration(); //时钟配置
  GPIOInit();           //数码管GPIO初始化

//使用独立看门狗功能   
  CW_SYSCTRL->APBEN1_f.IWDT = 1U;    //使能IWDT模块
  IWDT_InitStruct.IWDT_ITState = ENABLE;
  IWDT_InitStruct.IWDT_OverFlowAction = IWDT_OVERFLOW_ACTION_INT;   //溢出后产生中断不复位
  IWDT_InitStruct.IWDT_Pause = IWDT_SLEEP_PAUSE;
  IWDT_InitStruct.IWDT_Prescaler = IWDT_Prescaler_DIV4;
  IWDT_InitStruct.IWDT_ReloadValue = (IWDT_FREQ >> 2) / 1000 * 280 - 1;  // 由于IWDT的时钟为RC10K, 设置为280实际溢出时间为256ms左右
  IWDT_InitStruct.IWDT_WindowValue = 0xFFF;
  IWDT_Init(&IWDT_InitStruct);
  IWDT_Cmd();

  __disable_irq(); 
  NVIC_EnableIRQ(WDT_IRQn);
  __enable_irq();  


while(1)
  {
      num++; //一个循环,数据加1
if(num>=100)num=0; //限数0-99

      SEG_DisplayNum(num/10,0);  //显示数据十位
for(i=0;i<60000;i++);   //延时

      SEG_DisplayNum(num%10,1);  //显示数据个位
for(i=0;i<60000;i++);   //延时
       IWDT_Refresh();  //喂狗

      SEG_DisplayNum(num/10,0);  //显示数据十位
for(i=0;i<60000;i++);   //延时    
      IWDT_Refresh();  //喂狗

      SEG_DisplayNum(num%10,1);  //显示数据个位
for(i=0;i<60000;i++);   //延时


      SEG_DisplayNum(num/10,0);    //显示数据十位  
for(i=0;i<60000;i++);   //延时
      IWDT_Refresh();  //喂狗

      SEG_DisplayNum(num%10,1);  //显示数据个位
for(i=0;i<60000;i++);   //延时
      IWDT_Refresh(); //喂狗
  }
}

//CW32看门狗中断函数
void WDT_IRQHandler(void)
{
unsigned int j;

if(CW_IWDT->SR & IWDT_SR_OV_Msk) 
  { //独立看门狗溢出发生    
    IWDT_ClearOVFlag(); /*清除标志 */

while (1)
    {
        SEG_DisplayNum(10,1); //显示右测数码管的小数点位

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();  //软件复位,系统重新运行。
    }
  }
}

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

当程序发生死机时,MAIN函数的大循环将暂停运行,数码管随机显示最近一次数值,不进行动态扫描,所以,只有一位数码管显示。同时,喂狗暂停。

看门狗的代码配置为产生中断不复位。与STM32不同,看门狗可以停止复位,先进中断。因此,当看门狗时间到,进入看门狗中断函数WDT_IRQHandler()中,在中断函数中,将右则数码管小数点显示出来,并进行软件复位。这样通过小数点显示再判断看门狗事件的发生。

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

poYBAGPGIaeABvgmAAME_-HYLjc962.png

Hardfault中断函数中代码如下

void HardFault_Handler(void)
{
  /* USER CODE BEGIN HardFault_IRQn */

    unsigned int j;
  /* USER CODE END HardFault_IRQn */
  while (1)
  {
    /* USER CODE BEGIN W1_HardFault_IRQn */
    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();
    }
    /* USER CODE END W1_HardFault_IRQn */
  }
}

34这就是CW32关于看门狗的一个介绍。

CW32芯片本身在内部设计的时候充分考虑了各种ESD抗干扰手段,所以即使软件上不加任何软件抗干扰处理,它自身已经有比较强的抗干扰能力了。然后,所以我们做实验的结果,没有STM32那么明显,就是加看门狗和不加看门狗都没那么明显,它本身就可以扛得住各种干扰了。

但是,一个规范性的程序,一个可靠性的软硬设计都非常重要。建议用户在产品开发的时候,还是应该把看门狗功能加上去。因为外面可能有雷击,有各种电网的波动,各种意外。那么当意外发生的时候,MCU不能死机,但可以复位,可以重新运行,不能死锁。所以我们要养成良好的编程习惯,养成良好的产品设计思维,要把我们抗干扰这个手段加上去,这也是我们给大家一直来做这个抗干扰实验的一个目的和意义所在。

审核编辑:汤梓红

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

    关注

    5978

    文章

    43762

    浏览量

    617854
  • mcu
    mcu
    +关注

    关注

    142

    文章

    15644

    浏览量

    342399
  • 看门狗
    +关注

    关注

    10

    文章

    511

    浏览量

    70126
  • 抗干扰
    +关注

    关注

    4

    文章

    306

    浏览量

    34243
  • GPIO
    +关注

    关注

    16

    文章

    1104

    浏览量

    50343
  • CW32
    +关注

    关注

    1

    文章

    96

    浏览量

    189
  • 武汉芯源
    +关注

    关注

    1

    文章

    56

    浏览量

    120
收藏 人收藏

    评论

    相关推荐

    CW32在“打狗棒”的闪电攻击下的波形分析——MCU抗干扰实验系列专题(6)

    震惊于CW32的强抗干扰能力,今天决定对它进行好的单独测试。看看“打狗棒”的干扰信号是怎么样的?CW32又是怎么抗得住这些来自外界的强烈能量
    的头像 发表于 02-08 09:22 2108次阅读
    <b class='flag-5'>CW32</b>在“<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>(6)

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

     在上两期文章和视频中,为了公平起见,所有的MCU使用的是同一个工程程序,(不同的MCU,时钟和GPIO的配置略有不同,使用宏定义区分MCU),除了使用滴答时钟和基本GPIO操作外,没有任何
    的头像 发表于 02-08 09:15 1432次阅读
    “<b class='flag-5'>看门狗</b>“<b class='flag-5'>VS</b>“<b class='flag-5'>打狗棒</b>”,谁胜谁负?(STM32篇)—<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>(3)

    基于stm32f4看门狗配置和实验代码

    基于stm32f4看门狗配置和实验代码以下本人对stm32f4xx的独立看门狗和窗口看门狗学习
    发表于 07-30 07:33

    看门狗电路

    一、独立看门狗STM32的独立看门狗由内部专门的40Khz低速时钟驱动,即使主时钟发生故障,它也仍然有效。看门狗的原理:单片机系统在外界的干扰下会出现程序跑飞的现象导致出现死循环,
    发表于 07-30 06:02

    独立看门狗实验教程

    独立看门 看门狗实验网上有很多实验教程,比较典型的有正点原子的实验教程,野火的
    发表于 07-30 07:18

    看门狗是什么 看门狗分哪几类

    首先来介绍下看门狗是个神魔东西,在现实工业设备设计中需要考虑环境中电磁干扰等一系列干扰,这些干扰会影响单片机的正常工作(会出现程序莫名跑飞)
    发表于 08-02 09:20

    stm32-看门狗(独立看门狗,窗口看门狗)精选资料分享

    基于野火教程的看门狗实验器材:stm32c8t6,LED灯,按键一个。实验一:独立看门狗1. 实验原理。2.
    发表于 08-02 08:07

    窗口看门狗(WWDG)实验 精选资料分享

    窗口看门狗(WWDG)实验上一我们介绍了独立看门狗IWDG,这一我们来学习下窗口看门狗(以下
    发表于 08-02 08:33

    窗口看门狗之喂狗

    喂狗:重新把装载寄存器中的值装载至计数寄存器或者直接往计数寄存器写入数据,保证mcu不会复位。被狗咬:没有及时喂狗或者喂狗过于频繁,后者只存在于窗口看门狗,在独立看门狗中不存在喂狗过快还被狗咬的现象
    发表于 08-02 09:50

    看门狗实验概述

    看门狗实验概述也就是保证程序能正常执行,如果程序执行异常,可以使系统复位。 STM32看门狗的分类: 这次主要学习独立看门狗的相关知识,独立看门狗
    发表于 08-02 07:50

    独立看门狗实验

    独立看门狗实验独立看门狗概述常用寄存器和库函数配置编写独立看门狗实验一. 概述在单片机构成的微型计算机系统中,由于单片机的工作常常会受到来自
    发表于 08-02 08:01

    【嵌入式系统】独立看门狗原理+看门狗实验分析 精选资料推荐

    【嵌入式系统】独立看门狗原理+看门狗实验分析1、看门狗模块概述在由单片机构成的微机系统中,由于单片机工作常常会受到来自外界电磁场干扰导致程序
    发表于 08-03 06:27

    从一颗MCU芯片开始,降低抗干扰成本——MCU抗干扰实验系列专题(11)

    ,是很有必要的。“真金不怕红炉火!” 像CW32这种MCU,在各种“土法”攻击下,基本都能活下来的,应该是不错的选择!咱们“MCU研究实验室”做了11个
    发表于 02-09 20:31

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

      早期的MCU没有看门狗,就容易引起有些产品死机了不能重启工作。为了避免这个问题,后期的MCU在内部集成了看门狗的功能。  为了满足更多使用场景,现在很多
    发表于 03-17 16:30