本帖最后由 lilijin1995 于 2022-11-2 10:40 编辑
#申请原创#@21小跑堂
3.5 Eg5_IWDG这一节,我们将向大家介绍如何使用CH32V003 的独立看门狗(以下简称 IWDG)。CH32V003 内部自带了 2 个看门狗:独立看门狗(IWDG)和窗口看门狗(WWDG)。这一章我们只介绍独立看门狗,窗口看门狗将在下一节介绍。在本节中,我们将通过按键 PC1作为KEY1来喂狗,也是释放响应。 独立看门狗(IWDG)通常用来检测逻辑错误和外部环境干扰引起的软件故障,其时钟源来自于LSI,可独立于主程序之外运行,适用于对精度要求低的场合。独立看门狗可看作为一个12位递减计数器,当计数器的值从某个值递减到0后,系统会产生一个复位信号;若在计数器未递减到0之前刷新计数器的值,则不会产生复位信号,此过程即是喂狗。 IWDG 时钟源来自于 LSI,可独立于主程序之外运行,适用于对精度要求低的场合。独立看门狗的时钟来源 LSI 时钟分频,其功能在停机和待机模式时仍能正常工作。当看门狗计数器自减到 0 时,将会产生系统复位,所以超时时间为(重装载值+1)个时钟。 独立看门狗相关函数和定义分布在文件ch32v00x_iwdg.c和ch32v00x_iwdg.h文件中,关于这两文件的函数具体介绍请看软件设计部分
3.5.1硬件设计:本节配置按键 PC1作为KEY1来喂狗。
系统设有独立看门狗(IWDG)用来检测逻辑错误和外部环境干扰引起的软件故障。 3.5.2 软件设计:本节的代码设计,主要在我们的MyBSP目录下的IWDG.c中先介绍 IWDG_Feed_Init函数,该函数代码如下:
/*********************************************************************
* @fn IWDG_Init
*
* [url=home.php?mod=space&uid=247401]@brief[/url] Initializes IWDG.
*
* @param IWDG_Prescaler: specifies the IWDG Prescaler value.
* IWDG_Prescaler_4: IWDG prescaler set to 4.
* IWDG_Prescaler_8: IWDG prescaler set to 8.
* IWDG_Prescaler_16: IWDG prescaler set to 16.
* IWDG_Prescaler_32: IWDG prescaler set to 32.
* IWDG_Prescaler_64: IWDG prescaler set to 64.
* IWDG_Prescaler_128: IWDG prescaler set to 128.
* IWDG_Prescaler_256: IWDG prescaler set to 256.
* Reload: specifies the IWDG Reload value.
* This parameter must be a number between 0 and 0x0FFF.
*
* [url=home.php?mod=space&uid=266161]@return[/url] none
*/
void IWDG_Feed_Init(u16 prer, u16 rlr)
{
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
IWDG_SetPrescaler(prer);
IWDG_SetReload(rlr);
IWDG_ReloadCounter();
IWDG_Enable();
}
IWDG_WriteAccessCmd操作的是IWDG 控制寄存器( IWDG_CTLR),描述如下:
我们可以跳转到定义,可以发现:IWDG_WriteAccessCmd,IWDG_ReloadCounter,IWDG_Enable; 以上三个函数均是操作IWDG_CTLR寄存器; 其中, IWDG_WriteAccessCmd是0x5555,允许修改R16_IWDG_PSCR和R16_IWDG_RLDR 寄存器; IWDG_ReloadCounter是0xAAAA,喂狗。加载 IWDG_RLDR 寄存器值到独立看门狗计数器中; IWDG_Enable是0xCCCC:启动看门狗; 最后IWDG_SetPrescaler(prer)和IWDG_SetReload(rlr)分别设置的是分频因子寄存器( IWDG_PSCR )以及重装载值寄存器( IWDG_RLDR ); 再有就是我们要实现的按下按键喂狗代码(释放喂狗): void IWDG_Handle(void)
{
static uint8_t bounce=0;
if(KEY1)
{
bounce=1;
}else{
if(bounce)
{
bounce=0;
printf("Feed dog\r\n");
IWDG_ReloadCounter(); //Feed dog
Delay_Ms(10);
}
}
}
最后总结一下
1.1、void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess)
功 能:启用或禁用对IWDG_PSCR和IWDG_RLDR寄存器的写入访问。
输 入:WDG_WriteAccess:对IWDG_PSCR和IWDG_RLDR寄存器的写入访问的新状态。IWDG_WriteAccess_Enable:启用对IWDG_PSCR和IWDG_RLDR寄存器的写入访问;IWDG_WriteAccess_Disable:禁用对IWDG_PSCR和IWDG_RLDR寄存器的写入访问。
1.2、void IWDG_SetPrescaler(uint8_t IWDG_Prescaler)
功 能:设置IWDG预分频器值。
输 入:IWDG_Prescaler:指定IWDG预分频器值(4、8、16、34、64、128、256)。
1.3、void IWDG_SetReload(uint16_t Reload)
功 能:设置IWDG重新加载值。
输 入:Reload:指定IWDG Reload值。此参数必须是介于0和0x0FFF之间的数字。
1.4、void IWDG_ReloadCounter(void)
功 能:使用重新加载寄存器中定义的值重新加载IWDG计数器。
输 入:无
1.5、void IWDG_Enable(void)
功 能:启用IWDG(已禁用对IWDG_PSCR和IWDG_RLDR寄存器的写入访问)
输 入:无
1.6、FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG)
功 能:检查是否设置了指定的IWDG标志。
输 入:IWDG_FLAG:指定要检查的标志。IWDG_FLAG_PVU:正在进行预分频器值更新。IWDG_FLAG_RVU:正在进行重新加载值更新。
在进行IWDG相关程序编写时,若需用到上述函数,直接在程序进行调用即可
3.5.3 下载验证:可以看到每隔4S左右复位,喂狗可以延迟复位时间;
3.5.4 入门视频:
|