DWT-ZĂ€hler

Ein kleiner Hinweis zu einer sehr nĂŒtzlichen Sache, die im DWT-Modul (Data Watchpoint and Trace Unit) von stm32 enthalten ist.

Das DWT-Modul selbst ist eine ziemlich komplizierte Sache (siehe hier, S. 75), und er ist fĂŒr das Debuggen verantwortlich. Es handelt sich jedoch nicht um das Modul als Ganzes, sondern um eine seiner Komponenten - einen TaktzĂ€hler (im Folgenden DWT-ZĂ€hler).

TatsĂ€chlich ist der DWT-ZĂ€hler nur ein 32-Bit-Register, dessen Wert sich mit jedem nachfolgenden Taktzyklus um eins erhöht. Wir können in dieses Register schreiben und daraus lesen, was bedeutet, dass wir damit die AusfĂŒhrungszeit einiger Programmteile in Messungen messen und Mikrosekundenverzögerungen organisieren können. Dieser ZĂ€hler ist völlig unabhĂ€ngig.

Um die AusfĂŒhrungszeit eines Teils eines Programms oder einer Funktion zu messen, mĂŒssen Sie dies tun ...

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

Bild
Gemessene HAL_Delay (1000) bei einer Frequenz von 72 MHz.

Um Mikrosekundenpausen zu organisieren, mĂŒssen Sie eine Datei delay_micros.h ... erstellen.

 #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__ 

... und zum Projekt hinzufĂŒgen.

In main.c erstellen Sie eine Aufnahme ...

 #include "delay_micros.h" 

Initialisieren Sie vor einer Endlosschleife den ZĂ€hler ...

 DWT_Init(); 

Und die Verzögerung tut dies ...

 delay_us(100); // 100  

Die fertige Datei kann hier entnommen werden .

Das ist alles.

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


All Articles