Сам по себе модуль DWT достаточно сложная штуковина (почитать можно тут стр. 75), а отвечает он за отладку. Однако речь не о модуле в целом, а об одной из его составляющих — счётчика тактов (далее счётчик DWT).
По сути, счётчик DWT это просто 32-х битный регистр, значение в котором увеличивается на единичку с каждым последующим тактом. Мы можем писать в этот регистр и читать из него, а значит можем с его помощью измерять время выполнения каких-то кусков программы в тактах, и организовывать микросекундные задержки. Этот счётчик полностью независимый.
Чтоб измерить время выполнения какого-либо участка программы или функции, нужно сделать так…
#define DWT_CYCCNT *(volatile uint32_t*)0xE0001004 #define DWT_CONTROL *(volatile uint32_t*)0xE0001000 #define SCB_DEMCR *(volatile uint32_t*)0xE000EDFC char str[16] = {0,}; uint32_t count_tic = 0; SCB_DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;// разрешаем использовать DWT DWT_CONTROL|= DWT_CTRL_CYCCNTENA_Msk; // включаем счётчик DWT_CYCCNT = 0;// обнуляем счётчик // здесь кусок измеряемого участка программы count_tic = DWT_CYCCNT; // кол-во тактов snprintf(str, 16, "Takt %lu\n", count_tic); HAL_UART_Transmit(&huart1, (uint8_t*)str, strlen(str), 1000);

Измерил HAL_Delay(1000) на частоте 72МГц.
Для организации микросекундных пауз нужно создать файл delay_micros.h…
#ifndef __DELAY_US_H__ #define __DELAY_US_H__ #ifdef __cplusplus extern "C" { #endif /******************************************************************************/ /* Подключение заголовочных файлов используемых модулей */ #include "main.h" //#define DWT_CONTROL *(volatile unsigned long *)0xE0001000 //#define SCB_DEMCR *(volatile unsigned long *)0xE000EDFC /******************************************************************************/ /* inline func */ __STATIC_INLINE void DWT_Init(void) { CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; // разрешаем использовать счётчик DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; // запускаем счётчик } __STATIC_INLINE void delay_us(uint32_t us) { uint32_t us_count_tic = us * (SystemCoreClock / 1000000U); DWT->CYCCNT = 0U; while(DWT->CYCCNT < us_count_tic); } #ifdef __cplusplus } #endif #endif //__DELAY_US_H__
… и добавить его в проект.
В main.c создать инклюд…
#include "delay_micros.h"
Перед бесконечным циклом инициализировать счётчик…
DWT_Init();
А задержку делаем так…
delay_us(100); // 100 микросекунд
Готовый файл можно взять тут.
Это всё.
ссылка на оригинал статьи https://habr.com/ru/post/476582/
Добавить комментарий