首页 > 编程知识 正文

stm32死机看门狗不复位(硬件看门狗芯片电路图)

时间:2023-05-04 06:55:27 阅读:75385 作者:250

首先复制度娘的东西:

在由单片机构成的微型计算机系统中,单片机的工作经常受到外界电磁场的干扰,程序弹出,陷入死循环,程序的正常工作中断, 由于单片机控制的系统不能继续运行,整个系统陷入停滞状态,导致意想不到的结果,考虑到实时监测单片机的工作状态,单片机

简而言之,看门狗不断监视着我们运行的程序。 我们必须在规定时间的有效时间内进行“喂狗”操作。 这样,看门狗就能知道我们的程序运行正常。 如果我们的程序因为外部原因飞走了,就不能操作喂狗了。 看门狗饿得受不了,他会重置我们的单片机,重新启动程序。

看门狗分为独立看门狗和窗口看门狗,独立看门狗比较简单,但其安全性当然不如窗口看门狗高。 让我简单介绍一下这两条狗。1、独立看门狗(IWDOG)

独立看门狗由专用低速总线驱动,即使http://www.Sina.com/(http://www.Sina.com/)、主时钟发生故障也能工作。 这可能就是让这只狗成为独立看门狗的理由。 独立看门狗适用于需要在主程序外完全独立工作且要求时间精度的看门狗的情况。

向键值寄存器(IWDG_KR )写入0xCCCC,启用独立看门狗。 此时,计数器从复位值0xFFF开始递减,计数器值计数到0x000时产生复位信号(IWDG_RESET )。

键值寄存器IWDG_KR中的0xAAAA (一般称为喂狗,0xAAAA不是计数器中加载的值,实际加载到计数器中的值是根据分频系数和所需的超时时间计算的) ),自动重新

如果程序异常,就不能正常喂狗,系统会复位。

用于独立号犬的库函数如下所示

voidiwdg _ writeaccesscmd (uint 16 _ ti wdg _ write access; //取消写保护:0x5555有效voidiwdg _ set prescaler (uint8_ ti wdg _ prescaler ); //设置预分频系数:写为prvoidiwdg _ set reload (uint 16 _ tre load ); //重载值设置:写rlrvoidiwdg_reloadcounter(void ); //写给狗(0xAAAA至krvoidiwdg_enable ) (void ); //启用看门狗:在krflagstatusiwdg _ getflagstatus (uint 16 _ ti wdg _ flag )中写入0xCCCC; //状态:重载/预分频更新是预分频寄存器和重载寄存器的写保护,因此在设置这两个寄存器的值时,必须先解除写保护(调用相关函数即可)。

独立的看门狗操作程序

1、解除寄存器写保护: IWDG_WriteAccessCmd (; 2、设置独立号犬的预分频系数,时钟: IWDG_SetPrescaler (; 3、设置看门狗重载值,设置溢出时间: IWDG_SetReload (; 4、看门狗IWDG_Enable (); 5、APP给狗: IWDG_ReloadCounter (); 溢出时间计算: tout=(42^prer ) RLR )/40 ) m3 )相关代码如下

//独立看门狗的初始化//prer:分频数:0~7 (只有后3位有效! //分频因子=4*2^prer .但最大值只有256! //RLR:重载寄存器值:低11位有效//时间计算(大约) :tout=((4*2^prer ) rlr )/40(ms ).voidiwdg_init ) u8prer 设置IWDG预分频值iwdg_setreload(RLR ); 设置IWDG重载值IWDG_ReloadCounter (; iwdg计数器IWDG_Enable (; 启用//iwdg }//为独立监控犬提供voidiwdg_feed(void ) { IWDG_ReloadCounter ); //reload }这里的时间计算是指设定多长时间必须给狗喂食。 根据以上公式,选择分频系数和重装值,就可以得到给这条狗喂食的时间。 你必须在这个时间内至少抽出一次喂狗的时间。 (即使一直给,也至少要给一次。 否则,单片机就会复位。 ) ) ) ) ) )

LSI总线

窗口监视由时钟频率40KHz驱动,2、窗口看门狗(WWDOG)

说到看门狗,其实它的基本原理和独立看门狗一样,但我们又在喂狗的时候做了手脚,在

独立看门狗中,我们可以从计数器的值一直减到0的中间的任何时刻都可以进行喂狗,但是在窗口看门狗中,我们规定只能在某一个时间段内进行喂狗,举个栗子,假如说我们计数器是从100减到0,我们现在规定只能在计数器为80—30这个段内进行喂狗(这也就是窗口这个名词的来源),否则我们看门狗就会产生一个复位信号,从而使单片机复位,从这可以看出来,窗口看门狗的安全性比独立看门狗要高一些,毕竟它喂狗的时间段缩短了,这样就会降低由于程序跑飞而误打误撞的去执行喂狗操作的几率了。
对于窗口看门狗,我们不能太早喂狗,也不能太晚喂狗,最晚喂狗时间所对应的计数器值为0X3FH
我们来看一张图

当计数器的值T6:0>W6:0的值,也就是此时我们还处于上窗口,假如说我们现在喂狗,也就是把WWDG_CR置1,这时与门输出1,经过一个或门,输出1,然后我们又使能了WDGA位(使能这一位就相当于开启了窗口看门狗),然后又经过一个与门输出1,所以此时就会产生复位,即我们不能在上窗口之前进行喂狗(即不能太早喂狗)。第二种情况是我们不能等到计数器减到0X3FH之后再喂狗,因为到达0X3FH的时候,T6位就会由高跳变为低(0X40是0100 0000,0X3F是0011 1111),此时他经过一个非门和或门,再加上WDGA位也置1了(即开启了窗口看门狗),此时就会复位,即我们也不能太晚喂狗。
对于窗口看门狗,我们可以建立一个提前唤醒中断EWI,用来提醒我们去喂狗,即当计数器减到0X40的时候,产生一个中断,我们在这个中断里面去执行喂狗操作,这样就能够保持这个狗狗不闹腾了(即它不会让单片机复位了)。关于此中断,有一个中断标志位EWIF,这个标志位是当计数器减到0X40的时候,由硬件置1,当我们进入到中断服务函数并且执行完喂狗之后,需要用软件把这一位清零。

窗口看门狗配置过程如下

1、使能看门狗时钟: RCC_APB1PeriphClockCmd();2、 设置分频系数: WWDG_SetPrescaler();3、 设置上窗口值: WWDG_SetWindowValue();4、 开启提前唤醒中断并分组(可选): WWDG_EnableIT(); NVIC_Init();5、 使能看门狗: WWDG_Enable();6、 喂狗: WWDG_SetCounter();7、 编写中断服务函数 WWDG_IRQHandler();

部分代码如下

//保存WWDG计数器的设置值,默认为最大. u8 WWDG_CNT=0x7f; //初始化窗口看门狗 //tr :T[6:0],计数器值 //wr :W[6:0],窗口值 //fprer:分频系数(WDGTB),仅最低2位有效 //Fwwdg=PCLK1/(4096*2^fprer). void WWDG_Init(u8 tr,u8 wr,u32 fprer){ RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); // WWDG时钟使能WWDG_CNT=tr&WWDG_CNT; //初始化WWDG_CNT. WWDG_SetPrescaler(fprer);设置IWDG预分频值WWDG_SetWindowValue(wr);//设置窗口值WWDG_Enable(WWDG_CNT); //使能看门狗,设置计数器初值 WWDG_ClearFlag();//清除提前唤醒中断标志位 WWDG_NVIC_Init();//初始化窗口看门狗 NVICWWDG_EnableIT(); //开启窗口看门狗中断} //重设置WWDG计数器的值void WWDG_Set_Counter(u8 cnt){ WWDG_Enable(cnt);//使能看门狗 ,设置 counter . }//窗口看门狗中断服务程序void WWDG_NVIC_Init(){NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn; //WWDG中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //抢占2,子优先级3,组2NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //抢占2,子优先级3,组2 NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; NVIC_Init(&NVIC_InitStructure);//NVIC初始化}void WWDG_IRQHandler(void){WWDG_SetCounter(WWDG_CNT); //当禁掉此句后,窗口看门狗将产生复位WWDG_ClearFlag(); //清除提前唤醒中断标志位}

这里面我们注意到这样的语句

u8 WWDG_CNT=0x7f; WWDG_CNT=tr&WWDG_CNT; //初始化WWDG_CNT.

我们把送入的初值的最高位利用与的操作给清零了,这是因为在窗口看门狗的控制寄存器中(也就是计数器中)的最高位是控制窗口看门狗是否使能的控制位,这一位不参与计数,所以我们需要把最高位给清零,然后再在后面使能这个最高位,即开启窗口看门狗

关于使能和设置计数器初值是使用一个函数来完成的,即WWDG_Enable(WWDG_CNT); //使能看门狗,并设置计数器初值
关于两只小狗狗就先说到这吧
(话说我现实中还是很喜欢小狗狗的)

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。