Re: Någon som förstår det där med DMA i STM32?
Postat: 18 augusti 2021, 23:57:47
Jag skulle vara lite misstänksam till ett värde som -32768...
Kommer det överhuvud taget från en ADC?
Kommer det överhuvud taget från en ADC?
Svenskt forum för elektroniksnack.
https://elektronikforumet.com/forum/
Kod: Markera allt
/* 0: Check if SDADC is ready */
if(hsdadc->State != HAL_SDADC_STATE_READY)
Error_Handler();
Kod: Markera allt
/* 1: Enter init-mode for the control register */
hsdadc->Instance->CR1 |= SDADC_CR1_INIT;
Kod: Markera allt
uint32_t tickstart = HAL_GetTick();
bool isAtInitMode = true;
/* Wait for INITRDY bit on SDADC_ISR */
while ((hsdadc->Instance->ISR & SDADC_ISR_INITRDY) == (uint32_t) RESET) {
if ((HAL_GetTick() - tickstart) > 200) {
isAtInitMode = false;
}
}
Kod: Markera allt
/* 2: If init mode, then set gain and offset registers */
if(isAtInitMode){
switch(configuration_index){
case SDADC_CONF_INDEX_0:
hsdadc->Instance->CONF0R &= ~(0b111 << 20); /* Clear */
hsdadc->Instance->CONF0R |= SDADC_gain << 20; /* Bits 22:20 GAIN0[2:0]: */
break;
case SDADC_CONF_INDEX_1:
hsdadc->Instance->CONF1R &= ~(0b111 << 20); /* Clear */
hsdadc->Instance->CONF1R |= SDADC_gain << 20;
break;
case SDADC_CONF_INDEX_2:
hsdadc->Instance->CONF1R &= ~(0b111 << 20); /* Clear */
hsdadc->Instance->CONF2R |= SDADC_gain << 20;
break;
}
}
Kod: Markera allt
/* 3: Leave init-mode for the control register */
hsdadc->Instance->CR1 &= ~(SDADC_CR1_INIT);
Kod: Markera allt
/* Program configuration register with parameters */
tmp = (uint32_t)((uint32_t)(hsdadc->Instance) + \
SDADC_CONFREG_OFFSET + \
(uint32_t)(ConfIndex << 2UL));
*(__IO uint32_t *) (tmp) = (uint32_t) (ConfParamStruct->InputMode | \
ConfParamStruct->Gain | \
ConfParamStruct->CommonMode | \
ConfParamStruct->Offset);
Lite sent, kom hem från en god vänn, men svarar ändå.JimmyAndersson skrev: ↑20 augusti 2021, 23:18:00 Precis så.
Först berättar man hur man vill ha det. Sedan ber man processorn att den ska säga till när det blir ett interrupt.
Sen rullar det på och varje gång ett interrupt inträffar så hanterar man det (t.ex nollställer någon interrupt-flagga) och gör vad som ska göras när man får ett interrupt. T.ex sparar värdet från AD’n.
Just nu håller jag på att logga mätvärden till ett SD-kort och det fungerar bra. Jag har ofta använt mig av detta logik.Jo just det ja:
Det här med timers eller interrupt:
Interrupt är lämpligast när man vill fånga något som händer exakt just när det händer. (T.ex en larm-ingång som måste hanteras med mikrosekunds reaktionstid.)
Timers är lämpligast när man med jämna mellanrum vill kolla något. (T.ex batteri-status)
Kod: Markera allt
loop_time = start - stop;
start = GetTime();
time += loop_time;
if(time>= sample_time) {
/* Utför loggning */
time = 0;
}
Jag hade valt DMA. Orsaken har med att vill man läsa värdet i realtid så krävs det ytterligare processorkraft.Så för att läsa av en spänning löpande, som en multimeter, så hade jag valt timers istället för interrupt.
Annars lär du få interrupt när varenda liten bit ändras. Skulle man då presentera varenda förändring på en display så skulle man inte hinna läsa av något, så det vore slöseri med resurser (CPU) som kunde ha gett viktigare delar mer uppmärksamhet.