Ich verwende die HAL-Bibliothek und die Funktion namens HAL_TIM_PWM_PulseFinishedCallback, um die DAC-Ausgabe am Ende jedes Impulses zu aktualisieren. Hier ist der zugehörige Abschnitt des Codes:
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
if(htim -> Instance == TIM3)
{
if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
{
ValDAC1 = ValDAC1 + step_DAC1;
if(ValDAC1 > 4095)
{
ValDAC1 = 4095;
}
DAC1->DHR12R1 = currValDAC1;
pulsCount++;
if(pulsCount > numP)
{
HAL_TIM_PWM_Stop_IT(&htim3, TIM_CHANNEL_1);
}
}
}
if(htim -> Instance == TIM8)
{
if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
{
if(pulsCount > numP)
{
HAL_TIM_PWM_Stop_IT(&htim8, TIM_CHANNEL_2);
for(int i = 0; i<ValDAC1; i++)
{
DAC1->DHR12R1 = ValDAC1 - i;
//Need some uS delay here
}
DAC1->DHR12R1 = 0;
}
}
}
}
Und nach einer gewissen Anzahl von Impulsen geht der DAC wie in der obigen for-Schleife auf Null. Aber ich brauche eine Verzögerung zwischen jedem für die Iteration, wie im Kommentar oben als "Benötigen Sie hier eine US-Verzögerung" gezeigt. Ich brauche dort keine Präzision, aber einige Mikrosekunden Verzögerung. Wie könnte das möglich sein?
Wenn es Ihnen egal ist, ob es blockiert (OP sagt es nicht), können Sie eine weitere for-Schleife mit einem nop
Innere einfügen.
Fügen Sie diese Zeile irgendwo in die Datei ein (compilerspezifisch).
asm volatile("nop");
oder
__asm__("nop");
Dieses ST-Forum sagt, dass die letztere Syntax verwendet werden soll
Fügen Sie dann in Ihrer for-Schleife diese Schleife hinzu
for( int idx = MAX_LOOP; idx != 0; idx-- )
{
nop;
}
asm volatile("nop");
, um Inklusion zu erzwingen.asm
Syntax ist Compiler-spezifisch. Ich habe der Antwort ein weiteres Formular hinzugefügt. Sie sollten in der Dokumentation Ihres Compilers/Ihrer IDE nachsehen.DWT_Initialization()-Funktion
uint32_t DWT_Delay_Init(void)
{
/* Disable TRC */
CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk; // ~0x01000000;
/* Enable TRC */
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; // 0x01000000;
/* Disable clock cycle counter */
DWT->CTRL &= ~DWT_CTRL_CYCCNTENA_Msk; //~0x00000001;
/* Enable clock cycle counter */
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; //0x00000001;
/* Reset the clock cycle counter value */
DWT->CYCCNT = 0;
/* 3 NO OPERATION instructions */
__ASM volatile ("NOP");
__ASM volatile ("NOP");
__ASM volatile ("NOP");
/* Check if clock cycle counter has started */
if(DWT->CYCCNT)
{
return 0; /*clock cycle counter started*/
}
else
{
return 1; /*clock cycle counter not started*/
}
}
DWT_Delay_us() Funktion
// This Function Provides Delay In Microseconds Using DWT
__STATIC_INLINE void DWT_Delay_us(volatile uint32_t au32_microseconds)
{
uint32_t au32_initial_ticks = DWT->CYCCNT;
uint32_t au32_ticks = (HAL_RCC_GetHCLKFreq() / 1000000);
au32_microseconds *= au32_ticks;
while ((DWT->CYCCNT - au32_initial_ticks) < au32_microseconds-au32_ticks);
}
DWT_Delay_ms() Funktion
// This Function Provides Delay In Milliseconds Using DWT
__STATIC_INLINE void DWT_Delay_ms(volatile uint32_t au32_milliseconds)
{
uint32_t au32_initial_ticks = DWT->CYCCNT;
uint32_t au32_ticks = (HAL_RCC_GetHCLKFreq() / 1000);
au32_milliseconds *= au32_ticks;
while ((DWT->CYCCNT - au32_initial_ticks) < au32_milliseconds);
}
Quellen:
__STATIC_INLINE
, (b) selbst definiert #define __STATIC_INLINE static inline
, oder (c) einfach __STATIC_INLINE durch ersetzen static inline
.-au32_ticks
Bedingung in der Schleife: while ((DWT->CYCCNT - au32_initial_ticks) < au32_microseconds-au32_ticks);
? Würde dies nicht zu um 1µs zu kurzen Verzögerungen führen? Und der volatile
Qualifizierer für das Argument erscheint unnötig, da CYCCNT selbst bereits volatil sein sollte?volatile
Qualifizierer ist notwendig, um zu verhindern, dass der Compiler "kluge" Optimierungen am Argument selbst vornimmt. Ich kann nur vermuten, dass der Zweck darin -au32_ticks
besteht, die verlorene Zeit vor dem Eintritt in die Schleife aufzuholen while
. Wenn ich einen STM32 zur Hand hätte, würde ich einige Messungen mit einem Oszilloskop machen.CYCCNT
als deklariert wird volatile
. Übrigens, danke für den Link zum 'Compiler Explorer'. Scheint ein ziemlich nützliches Online-Tool zu sein.
Kartmann