[研电赛技术支持] GD 32 基于DWT实现硬件延时

[复制链接]
1367|0
 楼主| tpgf 发表于 2024-7-11 13:25 | 显示全部楼层 |阅读模式
1.0 软件延时的缺点


90764668f6c730ed6f.png

2.0 硬件延时的方案

69543668f6c81216fc.png

注意这种硬件延时的方式只在CoreTexM3以上的内核有效,低于该内核是无效的

88827668f6c86a2328.png

DWT里有一个32位的寄存器叫CYCCNT,它是一个向上计数器,记录的是内核时钟运行的次数,内核时钟跳动一次,该计数器就加1,如果内核时钟是120MHz,那精度就是1/120M = 8.3ns,而单片机程序的运行时间通常都是微秒级别的,所以DWT实现延时的精度是非常高的。

要实现DWT延时的功能,总共涉及到三个内核寄存器:DEMCR. DWT_CTRL、DWT_CYCCNT,分别用于开启DWT功能、开启CYCCNT及获得系统时钟计数值;当CYCCNT溢出之后,会清O重新开始向上计数。

如果内核时钟是120MHz,直接使用CYCCNT延时最大值为:232* 1/120M = 36S


73715668f6c8e3c8c9.png


46279668f6c94450da.png

28365668f6c9ab8ce9.png

20401668f6ca11e3cd.png

3325668f6ca7d8bf2.png

3.0 程序实现
DELAY.C 函数

#include <stdint.h>
#include "gd32f30x.h"

/**
***********************************************************
* @brief DWT初始化配置
* @param
* @return
***********************************************************
*/
void DelayInit(void)
{
        /* 关闭 TRC */
        CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk;
        /* 打开 TRC */
        CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;

        /* 关闭计数功能 */
        DWT->CTRL &= ~DWT_CTRL_CYCCNTENA_Msk;
        /* 打开计数功能 */
        DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;

        /* 计数清零 */
        DWT->CYCCNT = 0;
}

/**
***********************************************************
* @brief 微秒级延时函数
* @param nUs,最大延时时间( 2^32 / 内核主频 ) * 10^6 us
* @return
***********************************************************
*/
void DelayNus(uint32_t nUs)
{
        uint32_t tickStart = DWT->CYCCNT;

        /* 转换为nUs对应的时钟跳动次数rcu_clock_freq_get获取系统的时钟频率*/
        nUs *= (rcu_clock_freq_get(CK_AHB) / 1000000);

        /* 延时等待 */
        while ((DWT->CYCCNT - tickStart) < nUs);
}

/**
***********************************************************
* @brief 毫秒级延时函数
* @param nMs,延时时间n毫秒
* @return
***********************************************************
*/
void DelayNms(uint32_t nMs)
{
        for (uint32_t i = 0; i < nMs; i++)
        {
                DelayNus(1000);
        }
}


DELAY.H 延时函数头文件

#ifndef _DELAY_H_
#define _DELAY_H_
#include <stdint.h>


void DelayInit(void);
void DelayNus(uint32_t nUs);
void DelayNms(uint32_t nMs);

#endif
注:这里面的原理还没搞懂后续搞懂后继续详细的撰写自己的理解,参考自郭天祥老师的32位单片机教程,仅供学习参考【使用硬件延时的方式精度较高,相比于软件延时而言,在编写程序的时候尽量采用硬件延时的方式】。
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/qq_45973003/article/details/140316586

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

本版积分规则

2384

主题

17638

帖子

21

粉丝
快速回复 在线客服 返回列表 返回顶部