打印

【连载】STM8L051F3_15_IWDG应用

[复制链接]
1031|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
caijie001|  楼主 | 2018-5-24 18:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本文介绍STM8L051F3的IWDG相关知识。内容分为以下几部分:
  • IWDG简介
  • IWDG复位
1、IWDG简介IWDG(Independent watchdog):独立看门狗。独立看门狗外设可以用于解决系统由于硬件或软件产生的故障。独立看门狗的时钟是LSI时钟作为时钟源,所以当主时钟故障它也能够保持工作。
往IWDG_KR寄存器写入0xCC时,独立看门狗开始从复位值0xFF向下计数,当计数值达到0x00时产生一个AWDG复位。一旦使能,独立看门狗就能通过IWDG_PR和AWDG_RLR寄存器进行配置,IWDG_PR寄存器用于配置计数器时钟的预分频,当往AWDG寄存器写入KEY_REFRESH(0xAA)值时,独立看门狗将装载AWDG_RLR值进行刷新来防止看门狗复位产生。IWDG_PR和IWDG_RLR寄存器是写保护的,如果想要修改它们就要往IWDG_KR寄存器写入KEY_ACCESS(0x55)值,写入0xAA会重新恢复写保护。IWDG模块的框图如下:


独立看门狗可以通过两种方法开启:
  • 软件使能:在IWDG_KR寄存器写入0xCC
  • 硬件使能:配置选项字节IWDG_HW位,重新上电时会自动打开独立看门狗功能
独立看门狗的溢出时间可以根据下表设置:


独立看门狗IWDG理解及应用可分为以下几部分:
  • IWDG一共有3个寄存器
    • IWDG_KR
    • IWDG_PR
    • IWDG_RLR
  • IWDG_RLR与IWDG_PR寄存器用于配置计数器溢出时间,但默认处于写保护状态,需要往 IWDG_KR寄存器写入0x55来解除写保护
  • 往IWDG_KR寄存器写入0xCC用于启动IWDG
  • 往IWDG_KR寄存器写入0xAA用于刷新IWDG(喂狗)
2、IWDG复位2.1 IWDG配置本小节介绍如何使用IWDG,并通过KEY来触发一次IWDG复位,然后通过LED2来表示(LED2表示有IWDG复位产生)。使用的例程:STM8L051F3_15_IWDG。例程的内容为:配置EXTI,配置IWDG(溢出时间约为431ms),在主函数中每300ms对LED1状态取反和IWDG进行刷新一次以防止系统复位,并且检测标志位。当KEY按下时进入中断,标志位被置位,循环中检测到标志位不为0,进入死循环,从而IWDG没有刷新导致系统复位,复位后在主函数初始化时检测有IWDG复位发生,LED2点亮。IWDG的配置步骤如下:
1)使能LSI时钟,等待LSI时钟稳定
2)使能IWDG
3)设置IWDG时钟分频64
4)设置IWDG重装载值256(溢出时间约为431.16ms)
5)开启IWDG计时
2.2 例程介绍IWDG配置函数(在main.c文件下)如下所示:
static void IWDG_Config(void)
{
  /* 使能LSI时钟 */
  CLK_LSICmd(ENABLE);
  /* 等待LSI时钟稳定 */
while(CLK_GetFlagStatus(CLK_FLAG_LSIRDY)== RESET);
  /* 使能IWDG */
  IWDG_Enable();
  /* 使能写 IWDG_PR 和 IWDG_RLR 寄存器 */
  IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
  /* 设IWDG的时钟预分频为64 */
  IWDG_SetPrescaler(IWDG_Prescaler_64);
  /* 设置重装载值为256,看门狗复位时间为:(256*64) / 38000 = 431.16ms */
  IWDG_SetReload(0xff);
  /* 重装载看门狗,开始计时 */
  IWDG_ReloadCounter();
}
中断函数(在stm8l15x_it.c文件下)如下:
INTERRUPT_HANDLER(EXTI4_IRQHandler,12)
{
    /* In order to detect unexpected events during development,
       it is recommended to set a breakpoint on the following instruction.
    */
  //清除中断标志位
  EXTI_ClearITPendingBit(EXTI_IT_Pin4);
  //延迟消抖
  delay_ms(10);
  //松手检测
while(GPIO_ReadInputDataBit(KEY_GPIO_PORT, KEY_GPIO_PINS)== 0);
  //标志位置1
  EXTI_Flags = 1;
}
主函数如下:
void main(void)
{
  LED_Init();   //初始化LED
  EXTI_Init();  //EXTI初始化
  IWDG_Config();//IWDG初始化
  enableInterrupts();   //开总中断
  /* 检测系统复位是否由IWDG复位引起 */
if(RST_GetFlagStatus(RST_FLAG_IWDGF)!= RESET)
{
    /* 是:点亮LED2 */
    GPIO_ResetBits(LED2_GPIO_PORT, LED2_GPIO_PINS);
    /* 清除IWDG标志位 */
    RST_ClearFlag(RST_FLAG_IWDGF);
}
else
    /* 否:关闭LED2 */
    GPIO_SetBits(LED2_GPIO_PORT, LED2_GPIO_PINS);
while(1)
{
if(EXTI_Flags != 0) //检测标志位
{
      EXTI_Flags = 0;   //标志位清零
while(1);
}
    IWDG_ReloadCounter();       //每300ms,IWDG喂狗
    GPIO_ToggleBits(LED1_GPIO_PORT, LED1_GPIO_PINS); //切换LED1状态
    delay_ms(300);
}
}
使用ST-LINK把程序下载到开发板,LED1闪烁,按一下KEY(长按效果一样),LED2亮。

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:21ic公开课专区:http://open.21ic.com/ 21ic资料下载中心:http://dl.21ic.com/ 21ic项目外包中心:http://project.21ic.com/ 杰杰欢迎大家有空常来赛事专区逛逛

131

主题

3790

帖子

63

粉丝