Contador DWT

Uma pequena observação sobre uma coisa muito útil incluída no módulo DWT (Data Watchpoint e Trace unit) disponível no stm32.

O módulo DWT em si é uma coisa bastante complicada (leia aqui p. 75), e ele é responsável pela depuração. No entanto, não estamos falando sobre o módulo como um todo, mas sobre um de seus componentes - um contador de relógio (a seguir denominado contador DWT).

De fato, o contador DWT é apenas um registro de 32 bits, cujo valor aumenta em um a cada ciclo de clock subsequente. Podemos escrever e ler nesse registro, o que significa que podemos usá-lo para medir o tempo de execução de algumas partes do programa em medidas e organizar atrasos de microssegundos. Este contador é completamente independente.

Para medir o tempo de execução de qualquer parte de um programa ou função, você precisa fazer isso ...

#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); 

imagem
HAL_Delay medido (1000) a uma frequência de 72 MHz.

Para organizar pausas de microssegundos, você precisa criar um arquivo 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__ 

... e adicione-o ao projeto.

Em main.c crie uma inclusão ...

 #include "delay_micros.h" 

Antes de um loop infinito, inicialize o contador ...

 DWT_Init(); 

E o atraso está fazendo isso ...

 delay_us(100); // 100  

O arquivo final pode ser obtido aqui .

Isso é tudo.

Source: https://habr.com/ru/post/pt476582/


All Articles