1.0 软件延时的缺点
2.0 硬件延时的方案
注意这种硬件延时的方式只在CoreTexM3以上的内核有效,低于该内核是无效的
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
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
|