搜索
bottom↓
回复: 0

《ATK-DFPGL22G之FPGA开发指南_V1.0》第十四章 独立看门狗实验

[复制链接]

出0入234汤圆

发表于 2023-6-7 14:36:16 | 显示全部楼层 |阅读模式
1)实验平台:正点原子 DFZU2EG_4EV MPSoC开发板
2)购买链接:https://item.taobao.com/item.htm?&id=692368045899
3)全套实验源码+手册+视频下载地址:http://www.openedv.com/thread-340252-1-1.html
4)正点原子官方B站:https://space.bilibili.com/394620890
5)正点原子FPGA交流群:994244016 lQLPJxaFi2zaB4UWWrDAMgIsFEW2pwLb3abnwDMA_90_22.png
lQDPJxaFi2nfFizMjM0CbLCPlxn_FVheIQLb3aGrwFQA_620_140.jpg

lQLPJxaFi2nfFhLMkM0BXrDNvOUyeU_FPgLb3aGvQNIA_350_144.png


第十四章 独立看门狗实验


本章介绍APM32E103独立看门狗(IWDT)的使用,独立看门狗能够帮助CPU在进入错误状态或程序跑飞时进行复位。通过本章的学习,读者将学习到IWDT的使用。
本章分为如下几个小节:
14.1 硬件设计
14.2 程序设计
14.3 下载验证


14.1 硬件设计
14.1.1 例程功能

1. 程序运行后,开发板板载的LED0因不停的复位而闪烁,但如果按下KEY_UP按键进行喂狗,那么就不会产生复位,LED0也就保持常亮,一旦超过看门狗的溢出时间(Tout=1000毫秒)没有按下KEY_UP按键进行喂狗,那么就会进行复位,LED0也就会熄灭一次。
14.1.2 硬件资源
1. LED
        LED0 - PB5
2. 按键
        KEY_UP - PA0
3. 独立看门狗
14.1.3 原理图
本章实验使用的独立看门狗为APM32E103的片上资源,因此并没有相应的连接原理图。
14.2 程序设计
14.2.1 Geehy标准库的IWDT驱动

在使用IWDT前,需要先对其进行初始化,在初始化操作中要开启IWDT并配置IWDT的预分频系数和重装载值,预分频系数和重装载值就决定了IWDT单次溢出的时间,因此这两个值应该根据实际的应用场景妥善进行设置,若IWDT的溢出时间太长,则对异常情况的反应将变得迟钝,但若设置地太短,则会误触发复位,因此需要妥善设置。使用IWDT的具体步骤如下:
①:启动IWDT
②:使能访问IWDT相关寄存器
③:配置预分频系数
④:配置重装载值
⑤:在IWDT溢出前不断地进行“喂狗”操作
在Geehy标准库中对应的驱动函数如下:
①:使能IWDT
该函数用于使能IWDT,其函数原型如下所示:
void IWDT_Enable(void);
该函数的形参描述,如下表所示:
lQLPJyCFXMkiuAYszQIRsAa1XR_Ia6lhBHbAhk4A3wA_529_44.png
表14.2.1.1 函数IWDT_Enable()形参描述

该函数的返回值描述,如下表所示:
lQLPJyE7Qvygs8YtzQIQsDRcO5PwXNDEBHbAk_4AuwA_528_45.png
表14.2.1.2 函数IWDT_Enable()返回值描述

该函数的使用示例,如下所示:
#include "apm32e10x.h"
#include "apm32e10x_iwdt.h"

void example_fun(void)
{
    /* 使能IWDT */
    IWDT_Enable();
}
②:使能访问IWDT相关寄存器
该函数用于使能访问IWDT相关寄存器,只有使能访问了IWDT相关的寄存器,才能配置其预分频系数和重装载值,其函数原型如下所示:
void IWDT_EnableWriteAccess(void);
该函数的形参描述,如下表所示:
lQLPJxpEpvKkx2YszQISsIQ5gzzIJXsWBHa_x0CA3wA_530_44.png
表14.2.1.3 函数IWDT_EnableWriteAccess()形参描述

该函数的返回值描述,如下表所示:
lQLPJxrD-xhvJmYszQISsFfl1jAiC7GCBHa-9JhAqQA_530_44.png
表14.2.1.4 函数IWDT_EnableWriteAccess()返回值描述

该函数的使用示例,如下所示:
#include "apm32e10x.h"
#include "apm32e10x_iwdt.h"

void example_fun(void)
{
    /* 使能访问IWDT相关寄存器 */
    IWDT_EnableWriteAccess();
}
③:配置IWDT预分频系数
该函数用于配置IWDT的预分频系数,预分频系数决定了IWDT计数的频率,其函数原型如下所示:
void IWDT_ConfigDivider(uint8_t div);
该函数的形参描述,如下表所示:
lQLPJwJAd6s-usZWzQIRsPdRg3kWzXkvBHa__TJAuwA_529_86.png
表14.2.1.5 函数IWDT_ConfigDivider()形参描述

该函数的返回值描述,如下表所示:
lQLPJw84H6AX5cYtzQITsPY9LckWDfWuBHa_2qMAuwA_531_45.png
表14.2.1.6 函数IWDT_ConfigDivider()返回值描述

该函数的使用示例,如下所示:
#include "apm32e10x.h"
#include "apm32e10x_iwdt.h"

void example_fun(void)
{
    /* 配置IWDT的预分频系数为32 */
    IWDT_ConfigDivider(IWDT_DIVIDER_32);
}
④:配置IWDT的重装载值
该函数用于配置IWDT的重装载值,重装载值用于决定IWDT从“喂狗”到溢出时计数的个数,其函数原型如下所示:
void IWDT_ConfigReload(uint16_t reload);
该函数的形参描述,如下表所示:
lQLPJxk85iECfMYrzQIRsAFi9mYqOtZxBHbAK98AuwA_529_43.png
表14.2.1.7 函数IWDT_ConfigReload()形参描述

该函数的返回值描述,如下表所示:
lQLPJxK8hdK3wgYszQITsD1tkcprxPLfBHbANmOAuwA_531_44.png
表14.2.1.8 函数IWDT_ConfigReload()返回值描述

该函数的使用示例,如下所示:
#include "apm32e10x.h"
#include "apm32e10x_iwdt.h"

void example_fun(void)
{
    /* 配置IWDT的重装载值为875 */
    IWDT_ConfigReload(875);
}
⑤:重装载IWDT
该函数用于重装载IWDT,也就是所谓的“喂狗”,其函数原型如下所示:
void IWDT_Refresh(void);
该函数的形参描述,如下表所示:
lQLPJwzo86Z_3GYszQITsDOf_z5o7cPnBHa-5BPA9AA_531_44.png
表14.2.1.9 函数IWDT_Refresh()形参描述

该函数的返回值描述,如下表所示:
lQLPJwyXGPCTS8YrzQISsFhZYTg20KAaBHbAFMdA3wA_530_43.png
表14.2.1.10 函数IWDT_Refresh()返回值描述

该函数的使用示例,如下所示:
#include "apm32e10x.h"
#include "apm32e10x_iwdt.h"

void example_fun(void)
{
    /* 重装载IWDT(喂狗) */
IWDT_Refresh();
}
14.2.2 看门狗驱动
本章实验的看门狗驱动主要负责向应用层提供IWDT初始化和喂狗的操作函数,本章实验中,看门狗驱动的驱动代码包括wdt.c和wdt.h两个文件。
看门狗驱动中,IWDT的初始化函数,如下所示:
/**
* @brief       初始化独立看门狗
* @param       prer: IWDT_PRESCALER_4~IWDG_PRESCALER_256,对应4~256分频
* @arg         分频因子 = 4 * 2^prer. 但最大值只能是256!
* @param       rlr: 自动重装载值,0~0XFFF.
* @note        时间计算(大概):Tout=((4 * 2^prer) * rlr) / 40 (ms).
*              预分频数为64,重载值为625,溢出时间约为1s
* @retval      无
*/
void iwdt_init(uint8_t prer, uint16_t rlr)
{
    IWDT_EnableWriteAccess();   /* 使能对寄存器IWDT的写操作 */
    IWDT_ConfigDivider(prer);   /* 设置IWDG分频系数 */
    IWDT_ConfigReload(rlr);     /* 重装载值 */
    IWDT_Enable();              /* 初始化IWDG并启动 */
}
IWDT的初始化函数中使能了IWDT并配置其预分频系数和重装载值,并进行了一次“喂狗”防止IWDT一使能就溢出引发复位。
看门狗驱动中,IWDT的“喂狗”函数,如下所示:
/**
* @brief        喂独立看门狗
* @param        无
* @retval        无
*/
void iwdt_feed(void)
{   
    IWDT_Refresh();        /* 重装载独立看门狗计数器 */
}
该函数很简单,就是重装载IWDT的计数值。
14.2.3 实验应用代码
本实验的应用代码,如下所示:
int main(void)
{
    NVIC_ConfigPriorityGroup(NVIC_PRIORITY_GROUP_4);   /* 设置中断优先级分组为组4 */
    sys_apm32_clock_init(15);                          /* 配置系统时钟 */
    delay_init(120);                                   /* 初始化延时功能 */
    usart_init(115200);                                /* 初始化串口 */
    led_init();                                        /* 初始化LED */
    key_init();                                        /* 初始化按键 */
    delay_ms(100);                                     /* 延时100ms */
    iwdt_init(IWDT_DIVIDER_64, 625);                   /* 预分频数为64,重载值为625,溢出时间约为1s */
    LED0(0);                                           /* 先点亮LED0 */
   
    while (1)
    {
        if (key_scan(1) == WKUP_PRES)                  /* 如果WK_UP按下,则喂狗 */
        {
            iwdt_feed();                               /* 喂狗 */
        }
        delay_ms(10);
    }
}
可以看到应用代码中,LED初始化后,LED0会处于默认的熄灭状态100毫秒,随后初始化IWDT并点亮LED0,接着在while循环中重复判断KEY_UP按键是否被按下,若按下则进行“喂狗”操作,若在IWDT溢出前都为按下KEY_UP按键,则IWDT会触发复位,复位会导致LED0熄灭大约100毫秒(便于观察)。
14.3 下载验证
在完成编译和烧录操作后,可以看到板子上的LED0每间隔一段时间(大约4秒)就闪烁一次,这是因为IWDT不断地溢出,导致的复位。接下来若以时间间隔小于1秒(大约)的速度频繁地按下KEY_UP按键,则可以在IWDT溢出前及时“喂狗”,具体的现象为LED0不再闪烁。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-6 07:16

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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