打印
[其他ST产品]

STM32CUBE——使用DWT提供毫秒延迟

[复制链接]
532|41
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
起因
由于使用了CUBE,原子哥的延时就用不了,所以尝试其他延时函数:CUBE的HAL_Delay()和使用STM32的DWT(Data watchpoint trigger)

前言
为什么要学习这种延时的方法?

HAL_Delay实用程序函数:它建立在SysTick计时器上,当我们跑操作系统,就一般会占用一个硬件定时器——SysTick(也可以把其他定时器当成时钟),这样一来又难免产生冲突。
以便为在阻塞和非阻塞模式下工作的驱动程序提供两个版本。阻塞函数将使用我们今天将要开发的延迟实用程序(DWT)。非阻塞功能将由 SysTick 计时器处理

使用特权

评论回复
评论
王派oo 2022-8-31 17:25 回复TA
———————————————— 版权声明:本文为CSDN博主「煤炭的奇妙漂流」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/m0_46152804/article/details/123598771 
沙发
王派oo|  楼主 | 2022-8-31 17:30 | 只看该作者
系统图

使用特权

评论回复
板凳
王派oo|  楼主 | 2022-8-31 17:31 | 只看该作者
DWT_Initialization() 函数
要实现延时的功能,总共涉及到三个寄存器:DEMCR 、DWT_CTRL、DWT_CYCCNT,分别用于开启DWT功能、开启CYCCNT及获得系统时钟计数值。

使用特权

评论回复
地板
王派oo|  楼主 | 2022-8-31 17:32 | 只看该作者
uint32_t DWT_Delay_Init(void)
{
    /* 禁用 TRC */
    CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk; // ~0x01000000;
    /* 启动 TRC */
    CoreDebug->DEMCR |=  CoreDebug_DEMCR_TRCENA_Msk; // 0x01000000;

    /* Disable clock cycle counter */
    DWT->CTRL &= ~DWT_CTRL_CYCCNTENA_Msk; //~0x00000001;
    /* 启动  时钟周期计数器 */
    DWT->CTRL |=  DWT_CTRL_CYCCNTENA_Msk; //0x00000001;

    /* 重置时钟周期计数器值 */
    DWT->CYCCNT = 0;

    /* 3 NO OPERATION instructions 3空 */
   
    __ASM volatile ("NOP");
    __ASM volatile ("NOP");
    __ASM volatile ("NOP");

    /* 检查时钟周期计数器是否已启动*/
    if(DWT->CYCCNT)
    {
       return 0; /*clock cycle counter started*/
    }
    else
    {
      return 1; /*clock cycle counter not started*/
    }
}

使用特权

评论回复
5
王派oo|  楼主 | 2022-8-31 17:36 | 只看该作者
DEMCR寄存器
DEMCR寄存器为使能寄存器
    /* Disable TRC */
    CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk; // ~0x01000000;
    /* Enable TRC */
    CoreDebug->DEMCR |=  CoreDebug_DEMCR_TRCENA_Msk; // 0x01000000;

使用特权

评论回复
6
王派oo|  楼主 | 2022-8-31 17:38 | 只看该作者
24位置1对应0x01000000;

使用特权

评论回复
7
王派oo|  楼主 | 2022-8-31 17:39 | 只看该作者
DWT_CTRL寄存器
DWT_CTRL寄存器是时钟周期计数器
/* Disable clock cycle counter */
    DWT->CTRL &= ~DWT_CTRL_CYCCNTENA_Msk; //~0x00000001;
    /* 启动  时钟周期计数器 */
    DWT->CTRL |=  DWT_CTRL_CYCCNTENA_Msk; //0x00000001;
   

使用特权

评论回复
8
王派oo|  楼主 | 2022-8-31 17:42 | 只看该作者
第一位置"1"对应0x00000001

使用特权

评论回复
9
王派oo|  楼主 | 2022-8-31 17:43 | 只看该作者
DWT_CYCCNT寄存器
    /* 重置时钟周期计数器值 */
    DWT->CYCCNT = 0;

使用特权

评论回复
10
王派oo|  楼主 | 2022-8-31 17:45 | 只看该作者
它是一个向上的计数器,记录的是内核时钟运行的个数,内核时钟跳动一次,该计数器就加1,精度非常高,决定内核的频率是多少,如果是F103系列,内核时钟是72M,那精度就是1/72M = 14ns

使用特权

评论回复
11
王派oo|  楼主 | 2022-8-31 17:46 | 只看该作者
DWT_Delay_us() 函数
此函数使用DWT提供以微秒计的延迟

// 该函数使用DWT提供毫秒延迟
__STATIC_INLINE void DWT_Delay_ms(volatile uint32_t au32_milliseconds)
{
  uint32_t au32_initial_ticks = DWT->CYCCNT;
  uint32_t au32_ticks = (HAL_RCC_GetHCLKFreq() / 1000);
  au32_milliseconds *= au32_ticks;
  while ((DWT->CYCCNT - au32_initial_ticks) < au32_milliseconds);
}

使用特权

评论回复
12
王派oo|  楼主 | 2022-8-31 17:47 | 只看该作者
演示
以下是本实验的应用程序代码
#include "main.h"
#include "../util/Timer_Delay.h"
#include "../util/DWT_Delay.h"

void SystemClock_Config(void);
static void MX_GPIO_Init(void);

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    /* Initialize The TimerDelay*/
    TimerDelay_Init();

    while (1)
    {
        HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_0);
        delay_ms(100);
    }
}

使用特权

评论回复
13
王派oo|  楼主 | 2022-8-31 17:49 | 只看该作者
演示
以下是本实验的应用程序代码
#include "main.h"
#include "../util/Timer_Delay.h"
#include "../util/DWT_Delay.h"

void SystemClock_Config(void);
static void MX_GPIO_Init(void);

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    /* Initialize The TimerDelay*/
    TimerDelay_Init();

    while (1)
    {
        HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_0);
        delay_ms(100);
    }
}

使用特权

评论回复
14
王派oo|  楼主 | 2022-8-31 17:51 | 只看该作者

使用特权

评论回复
15
王派oo|  楼主 | 2022-8-31 17:52 | 只看该作者
总结一下:

a.先使能DWT外设,由内核调试寄存器DEM_CR的位24控制,写1使能。

b.使能CYCCNT寄存器,由DWT_CTRL的位0控制,写1使能。

c.使能CYCCNT寄存器之前,先清0。

使用特权

评论回复
16
chenci2013| | 2022-9-5 12:34 | 只看该作者
systick就行的

使用特权

评论回复
17
minzisc| | 2022-9-5 17:05 | 只看该作者
能够做us的延时吗

使用特权

评论回复
18
koala889| | 2022-9-5 20:14 | 只看该作者
要求精确么

使用特权

评论回复
19
updownq| | 2022-9-7 16:47 | 只看该作者
STM32CUBE开发程序简单多了

使用特权

评论回复
20
maqianqu| | 2022-9-7 19:25 | 只看该作者
定时器直接实现延时不好吗

使用特权

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

本版积分规则

16

主题

247

帖子

0

粉丝