Compteur DWT

Une petite note sur une chose très utile incluse dans le module DWT (Data Watchpoint and Trace unit) disponible sur stm32.

Le module DWT lui-même est une chose assez compliquée (lire ici p. 75), et il est responsable du débogage. Cependant, nous ne parlons pas du module dans son ensemble, mais de l'un de ses composants - un compteur d'horloge (ci-après compteur DWT).

En fait, le compteur DWT n'est qu'un registre de 32 bits, dont la valeur augmente de un à chaque cycle d'horloge suivant. Nous pouvons écrire et lire à partir de ce registre, ce qui signifie que nous pouvons l'utiliser pour mesurer le temps d'exécution de certaines parties du programme en mesures, et organiser des retards en microsecondes. Ce compteur est totalement indépendant.

Pour mesurer le temps d'exécution de n'importe quelle partie d'un programme ou d'une fonction, vous devez le faire ...

#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 mesuré (1000) à une fréquence de 72 MHz.

Pour organiser les pauses en microsecondes, vous devez créer un fichier 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__ 

... et ajoutez-le au projet.

Dans main.c, créez une inclusion ...

 #include "delay_micros.h" 

Avant une boucle infinie, initialisez le compteur ...

 DWT_Init(); 

Et le retard le fait ...

 delay_us(100); // 100  

Le fichier terminé peut être récupéré ici .

C’est tout.

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


All Articles