Счётчик DWT

от автора

Маленькая заметка об очень полезной вещице входящей в состав модуля DWT (Data Watchpoint and Trace unit) имеющегося у stm32.

Сам по себе модуль 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); 

image
Измерил 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/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *