STM32的复位方式:硬件复位、软件复位(看门狗复位和系统复位)

您所在的位置:网站首页 看门狗2localization STM32的复位方式:硬件复位、软件复位(看门狗复位和系统复位)

STM32的复位方式:硬件复位、软件复位(看门狗复位和系统复位)

2023-12-10 01:07| 来源: 网络整理| 查看: 265

STM32的复位方式:硬件复位、软件复位(看门狗复位和系统复位)。

1.硬件复位: 硬件复位通过给NRST引脚输入低电平复位单片机。 2、看门狗复位: 独立看门狗和窗口看门狗。

(1)独立看门狗 STM32的独立看门狗由内部专门的40Khz低速时钟驱动,即主时钟发生故障,它也仍然有效,这里我们需要注意独立看门狗的时钟不是准确的40Khz,而是在30~60Khz之间变化的一个时钟,只是我们估算以40Khz来计算,看门狗对时间要求不是很精确,时钟有点偏差还是可以接受的。

1.2.1工作原理:**** 在**键值寄存器(IWDG_KR)**中写入0XCCCC,开始启用独立看门狗,此时计数器开始从其复位值OXFFF递减计数,当计数器计数到末尾0X000的时候,会产生一个复位信号(IWDG_RESET),无论何时,只要寄存器IWDG_KR中被写入0XAAAA,IWDG_RLR中的值就会被重新加载到计数器中从而避免产生看门狗复位。 还有两个寄存器,一个预分频寄存器(IWDG_PR)。该寄存器是用来设置看门狗的时钟分频系数,最低为4,最高位256,虽然是32位寄存器,我们只使用了最低3位。 另一个重装载寄存器。该寄存器用来保存重装载到计数器中的值。该寄存器也是一个 32 位寄存器,但是只有低 12 位是有效的。 **预分频寄存器(IWDG_PR)和重载寄存器(IWDG_RLR)**的写保护 :IWDG_PR和IWDG_RLR寄存器具有写保护功能,要想修改这两个寄存器的值,首先要向IWDG_KR中写入0X5555。以不同的值写入这个寄存器或者重装载(写入0XAAAA)都会重新启动写保护。 独立看门狗由内部低速时钟LSI提供计数时钟,8 位分频,12位计数,需要定期喂狗(重载数值 ReloadCounter),如果计数值减为0了,还没有重载数值,则会响应复位事件。 1.2.2启动过程:

1.2.2.1向IWDG_KR中写入0X5555 通过这一步我们取消了IWDG_PR和IWDG_RLR的写保护,下一步我们设置他们初值。 设置IWDG_PR和IWDG_RLR的初值。 我们计算一下看门狗的喂狗时间(看门狗溢出时间)计算公式

Tout=((42^prer)rlr)/40

其中Tout就是看门狗溢出时间(单位ms),prer是看门狗时钟预分频值(IWDG_PR值),范围为0~7,rlr位看门狗重载值(IWDG_RLR)。比如我们设置prer为4,rlr的值为625,我们就可以计算得到Tout=64*625/40=1000ms,这样,看门狗的溢出时间就是1S,只要在这一秒钟内,有一次吸入0XAAAA到IWDG_KR,就不会导致看门狗复位(写入多次也是可以的)(由于看门狗的时钟不是准确40Khz,所以喂狗不要太晚,以免发生看门狗复位)。

1.2.2.2向IWDG_KR中写入0XAAAA 通过这句可以将重载寄存器(IWDG_RLR)中的计数初值载入到看门狗计数器中(也可以时钟该命令喂狗)。

1.2.2.3向IWDG_KR中写入0XCCCC 通过这句我们就启动了STM32的看门狗了,使能了看门狗,在程序里面我们就必须间隔一定的时间就喂狗,否则导致程序复位,利用这一点,我们通过一个LED来指示是否复位,验证独立看门狗 举例:正点原子独立看门狗 源文件:

//时间计算(大概):Tout=((4*2^prer)*rlr)/40 (ms). void IWDG_Init(u8 prer,u16 rlr) { //第一步0X5555 IWDG_WriteAessCmd(IWDG_WriteAess_Enable); //使能对寄存器IWDG_PR和IWDG_RLR的写操作IWDG_SetPrescaler(prer); //设置IWDG预分频值:设置IWDG预分频值为64IWDG_SetReload(rlr); //设置IWDG重装载值//第二步0XAAAA IWDG_ReloadCounter(); //按照IWDG重装载寄存器的值重装载IWDG计数器//第三步0xCCCC IWDG_Enable(); //使能IWDG} //喂独立看门狗 void IWDG_Feed(void) { IWDG_ReloadCounter();//reload } 主函数源文件:

int main(void){ delay_init(); //延时函数初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级uart_init(115200); //串口初始化为115200LED_Init(); //初始化与LED连接的硬件接口KEY_Init(); //按键初始化 delay_ms(500); //让人看得到灭IWDG_Init(4,625); //与分频数为64,重载值为625,溢出时间为1s LED0=0; //点亮LED0while(1){if(KEY_Scan(0)==WKUP_PRES){IWDG_Feed();//如果WK_UP按下,则喂狗}delay_ms(10);}; } (2)窗口看门狗

这里我们的 WWDG_CR 只有低八位有效,T[6:0]用来存储看门狗的计数器值, 随时更新的,每个窗口看门狗计数周期(4096×2^ WDGTB)减 1。当该计数器的值从 0X40 变 为 0X3F 的时候,将产生看门狗复位。 WDGA 位则是看门狗的激活位,该位由软件置 1,以启动看门狗,并且一定要注意的是该 位一旦设置,就只能在硬件复位后才能清零了。

该位中的 EWI 是提前唤醒中断,也就是在快要产生复位的前一段时间(T[6:0]=0X40)来 提醒我们,需要进行喂狗了,否则将复位!因此,我们一般用该位来设置中断,当窗口看门狗 的计数器值减到 0X40 的时候,如果该位设置,并开启了中断,则会产生中断,我们可以在中 断里面向 WWDG_CR 重新写入计数器的值,来达到喂狗的目的。注意这里在进入中断后,必 须在不大于 1 个窗口看门狗计数周期的时间(在 PCLK1 频率为 36M 且 WDGTB 为 0 的条件下, 该时间为 113us)内重新写 WWDG_CR,否则,看门狗将产生复位!

最后我们要介绍的是状态寄存器(WWDG_SR),该寄存器用来记录当前是否有提前唤醒 的标志。该寄存器仅有位 0 有效,其他都是保留位。当计数器值达到 40h 时,此位由硬件置 1。 它必须通过软件写 0 来清除。对此位写 1 无效。即使中断未被使能,在计数器的值达到 0X40 的时候,此位也会被置 1。

窗口看门狗工作原理: 窗口看门狗(WWDG)通常被用来监测由外部干扰或不可预见的逻辑条件造成的应用程序 背离正常的运行序列而产生的软件故障。除非递减计数器的值在 T6 位(WWDG->CR 的第六位) 变成 0 前被刷新,看门狗电路在达到预置的时间周期时,会产生一个 MCU 复位。在递减计数 器达到窗口配置寄存器(WWDG->CFR)数值之前,如果 7 位的递减计数器数值(在控制寄存器中) 被刷新, 那么也将产生一个 MCU 复位。这表明递减计数器需要在一个有限的时间窗口中被刷 新。他们的关系可以用图 12.1.1 来说明:

图 12.1.1 中,T[6:0]就是 WWDG_CR 的低七位,W[6:0]即是 WWDG->CFR 的低七位。T[6:0] 就是窗口看门狗的计数器,而 W[6:0]则是窗口看门狗的上窗口,下窗口值是固定的(0X40)。 当窗口看门狗的计数器在上窗口值之外被刷新,或者低于下窗口值都会产生复位。 上窗口值(W[6:0])是由用户自己设定的,根据实际要求来设计窗口值,但是一定要确保 窗口值大于 0X40,否则窗口就不存在了。 窗口看门狗的超时公式如下: Twwdg=(4096×2^WDGTB×(T[5:0]+1)) /Fpclk1; 其中: Twwdg:WWDG 超时时间(单位为 ms) Fpclk1:APB1 的时钟频率(单位为 Khz) WDGTB:WWDG 的预分频系数 T[5:0]:窗口看门狗的计数器低 6 位 根据上面的公式,假设 Fpclk1=36Mhz,那么可以得到最小-最大超时时间表如表 12.1.1 所 示: 窗口看门狗由APB1(RCC_APB1Periph_WWDG)提供计数时钟,2 位分频,7位计数,需要定期喂狗(更新计数值),如果计数值减为0x40了,还未更新计数值,则会响应复位事件。

步骤如下: 1)使能 WWDG 时钟 2)设置窗口值和分频数 3)开启 WWDG 中断并分组 4) 设置计数器初始值并使能看门狗 5) 编写中断服务函数

正点原子程序: 源程序

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); //使能看门狗 , 设置 counter . WWDG_ClearFlag();//清除提前唤醒中断标志位 WWDG_NVIC_Init();//初始化窗口看门狗 NVICWWDG_EnableIT(); //开启窗口看门狗中断 } //重设置WWDG计数器的值 void WWDG_Set_Counter(u8 t) {WWDG_Enable(t);//使能看门狗 , 设置 counter . } //窗口看门狗中断服务程序 void WWDG_NVIC_Init() {NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn; //WWDG中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //抢占2,子优先级3,组2 NVIC_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(); //清除提前唤醒中断标志位LED1=!LED1; //LED状态翻转} 主程序:

int main(void){ delay_init(); //延时函数初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级uart_init(115200); //串口初始化为115200LED_Init();KEY_Init(); //按键初始化 LED0=0;delay_ms(300); WWDG_Init(0X7F,0X5F,WWDG_Prescaler_8);//计数器值为7f,窗口寄存器为5f,分频数为8 while(1){LED0=1; } } 3、系统复位: 系统复位是置位同一个寄存器中的 SYSRESETREQ 位。这种复位则会波及整个芯片上的电路:它会使Cortex-M3处理器把送往系统复位发生器的请求线置为有效。但是系统复位发生器不是Cortex-M3的一部分,而是由芯片厂商实现,因此不同的芯片对此复位的响应也不同。因此,读者需要认真参阅芯片规格书,明白当发生片内复位时,各外设和功能模块都会回到什么样的初始状态,或者有哪些功能模块不受影响(比如,STM32系列的芯片有后备存储区,该区就被特殊对待)。

大多数情况下,复位发生器在响应 SYSRESETREQ 时,它也会同时把Cortex-M3处理器的系统复位信号(SYSRESETn)置为有效。通常,SYSRESETREQ不应复位调试逻辑。

这里有一个要注意的问题:从SYSRESETREQ被置为有效到复位发生器执行复位命令,往往会有一个延时。在此延时期间,处理器仍然可以响应中断请求。但我们的本意往往是要让此次执行到此为止,不要再做任何其它事情了。所以,最好在发出复位请求前,先把FAULTMASK置位。利用库函数: __set_FAULTMASK(1); //STM32程序软件复位 NVIC_SystemReset();

资料来源: 正点原子STM32F1开发指南。

更多推荐

看门狗,方式,硬件,系统,软件



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3