查看: 666|回复: 0

CH32V103应用教程——IWDG

[复制链接]

41

主题

168

帖子

3226

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3226
发表于 2021-11-27 18:38:47 | 显示全部楼层 |阅读模式
本章教程通过给PA13引脚(KEY2)置低电平进行喂狗,并通过串口调试助手打印显示程序运行状态,具体如下:
当PA13引脚未连接高电平(按下KEY2),即有喂狗,串口打印显示:Feed dog success;
当PA13引脚连接高电平,即无喂狗,串口打印显示:Feed dog fail,Reset。4秒后复位成优盘模式,无打印。

1、IWDG简介及相关函数介绍
独立看门狗(IWDG)通常用来检测逻辑错误和外部环境干扰引起的软件故障,其时钟源来自于LSI,可独立于主程序之外运行,适用于对精度要求低的场合。独立看门狗可看作为一个12位递减计数器,当计数器的值从某个值递减到0后,系统会产生一个复位信号;若在计数器未递减到0之前刷新计数器的值,则不会产生复位信号,此过程即是喂狗。

CH32V103独立看门狗的时钟来源 LSI 时钟分频,其功能在停机和待机模式时仍能正常工作。其具有12位自减型计数器,当看门狗计数器自减到 0 时,将产生系统复位,所以超时时间为(重装载值+1)个时钟,最大可达 26.2s,最小可达 100us。关于CH32V103 独立看门狗具有说明,可参考CH32V103应用手册。

独立看门狗相关函数和定义分布在文件ch32v10x_iwdg.c和ch32v10x_iwdg.h文件中,关于这两文件的函数具体介绍如下:
  1. void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess);
  2. void IWDG_SetPrescaler(uint8_t IWDG_Prescaler);
  3. void IWDG_SetReload(uint16_t Reload);
  4. void IWDG_ReloadCounter(void);
  5. void IWDG_Enable(void);
  6. FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG);
复制代码
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相关程序编写时,若需用到上述函数,直接在程序进行调用即可。

2、硬件设计
本教程通过PA13引脚接GND引脚进行喂狗,开发板已经设置KEY2按键,按下PA13接地。

3、软件设计
独立看门狗喂狗操作步骤如下:
  • 取消寄存器写保护;
  • 设置独立看门狗的预分频系数和重装载值;
  • 重载计数值喂狗;
  • 启动看门狗。

  1. /*******************************************************************************
  2. * 函数名  : IWDG_Feed_Init
  3. * 描述    : IWDG初始化.
  4. * 输入    : prer:预分频器值; rlr:重装载寄存器的值
  5. * 返回    : None
  6. *******************************************************************************/
  7. void IWDG_Feed_Init( uint16_t prer, uint16_t rlr )
  8. {
  9.     IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //使能取消IWDG_PR和IWDG_RLR寄存器的写保护,
  10.     IWDG_SetPrescaler(prer);                      //设置预分频器值
  11.     IWDG_SetReload(rlr);                          //设置重装载寄存器的值
  12.     IWDG_ReloadCounter();                         //将重装载寄存器的值放入到计数器中
  13.     IWDG_Enable();                                //使能IWDG
  14. }
复制代码

PA13引脚设置为上拉输入
  1. /*******************************************************************************
  2. * 函数名  : GPIOx_Init
  3. * 描述    : GPIO初始化.
  4. * 输入    : None
  5. * 返回    : None
  6. *******************************************************************************/
  7. void GPIOx_Init(void)
  8. {
  9.   GPIO_InitTypeDef GPIO_InitStructure;
  10.   RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE ); //使能GPIOA时钟
  11.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;        //配置GPIO引脚,PA13,KEY2
  12.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;    //配置GPIO模式为上拉输入
  13.   GPIO_Init( GPIOA, &GPIO_InitStructure);          //GPIO初始化
  14. }
复制代码

检测PA13是否按下函数
  1. /*******************************************************************************
  2. * 函数名  : GPIOx_Connet
  3. * 描述    : 获取GPIO值.
  4. * 输入    : None
  5. * 返回    : None
  6. *******************************************************************************/
  7. uint8_t GPIOx_Connet(void)
  8. {
  9.   if(digitalRead(PA13) == 0)        //当PA13引脚连接高电平,返回值为1,否则返回0;
  10.   {
  11.     return 0;
  12.   }
  13.   return 1;
  14. }
复制代码

所有程序代码:
  1. #include <CH32V103.h>
  2. #include "HardwareSerial.h"

  3. /*******************************************************************************
  4. * 函数名  : GPIOx_Init
  5. * 描述    : GPIO初始化.
  6. * 输入    : None
  7. * 返回    : None
  8. *******************************************************************************/
  9. void GPIOx_Init(void)
  10. {
  11.   GPIO_InitTypeDef GPIO_InitStructure;
  12.   RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE ); //使能GPIOA时钟
  13.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;        //配置GPIO引脚,PA13,KEY2
  14.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;    //配置GPIO模式为上拉输入
  15.   GPIO_Init( GPIOA, &GPIO_InitStructure);          //GPIO初始化
  16. }

  17. /*******************************************************************************
  18. * 函数名  : GPIOx_Connet
  19. * 描述    : 获取GPIO值.
  20. * 输入    : None
  21. * 返回    : None
  22. *******************************************************************************/
  23. uint8_t GPIOx_Connet(void)
  24. {
  25.   if(digitalRead(PA13) == 0)        //当PA13引脚连接高电平,返回值为1,否则返回0;
  26.   {
  27.     return 0;
  28.   }
  29.   return 1;
  30. }

  31. /*******************************************************************************
  32. * 函数名  : IWDG_Feed_Init
  33. * 描述    : IWDG初始化.
  34. * 输入    : prer:预分频器值; rlr:重装载寄存器的值
  35. * 返回    : None
  36. *******************************************************************************/
  37. void IWDG_Feed_Init( uint16_t prer, uint16_t rlr )
  38. {
  39.     IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //使能取消IWDG_PR和IWDG_RLR寄存器的写保护,
  40.     IWDG_SetPrescaler(prer);                      //设置预分频器值
  41.     IWDG_SetReload(rlr);                          //设置重装载寄存器的值
  42.     IWDG_ReloadCounter();                         //将重装载寄存器的值放入到计数器中
  43.     IWDG_Enable();                                //使能IWDG
  44. }

  45. int main(void)
  46. {
  47.   CH32_Init();
  48.   Serial1.begin(115200);
  49.   GPIOx_Init();                              //相应引脚初始化
  50.   IWDG_Feed_Init( IWDG_Prescaler_32, 4000 ); // 3.2s IWDG reset
  51.   while(1)
  52.   {
  53.     if( GPIOx_Connet() == 0 )              //PA13==0,即PA13连接低电平
  54.     {
  55.         IWDG_ReloadCounter();               //Feed dog
  56.         Serial1.print("Feed dog success\r\n");
  57.         delay(300);
  58.     }
  59.     else
  60.     {
  61.         Serial1.print("Feed dog fail,Reset\r\n");
  62.         delay(300);
  63.     }
  64.   }
  65.   return 1;
  66. }

复制代码

4.演示验证
在天问Block插入USB左边的TypeC口下载这个程序,再插入右侧的USB口,打开软件监视器。上位机波特率设置成115200,点击“连接串口”。按下KEY1(RUN)键,程序运行,监视器显示如下图:
无标题.png
串口输出:Feed dog fail,Reset
3.2秒后,复位停止输出。

再按KEY1键继续运行,串口不断输出:Feed dog fail,Reset;
每3.2秒内按一次KEY2键,串口输出:Feed dog success ,同时完成一次喂狗。开发板就不会复位,如果超3.2秒不按KEY2,开发板就复位到优盘状态,串口就没有输出。

源代码在范例代码->CH32V外设代码范例->4.IWDG.hd






回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|好好搭搭在线 ( © 好好搭搭在线 浙ICP备19030393号-1 )

GMT+8, 2024-5-24 12:43 , Processed in 0.101665 second(s), 25 queries .

Powered by Discuz!

© 2001-2024 Comsenz Inc.

快速回复 返回顶部 返回列表