Någon som förstår det där med DMA i STM32?
Re: Någon som förstår det där med DMA i STM32?
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?
Re: Någon som förstår det där med DMA i STM32?
Det är enkelt. Det är sigma delta ADC med noll referens. Enligt databladet så ger den då värden mellan -0x8000 till 0x8000.
Men sådant kan enkelt kastas om till uint16 så man får 0 till 0xFFFF.
Notera att detta är en 16-bit ADC. Väldigt noggrann.
Men sådant kan enkelt kastas om till uint16 så man får 0 till 0xFFFF.
Notera att detta är en 16-bit ADC. Väldigt noggrann.
Re: Någon som förstår det där med DMA i STM32?
Efter några försök så har jag lyckats för första gången att programmera en STM32 med register endast. Det var att läsa databladet rätt mycket.
Det jag har gjort här är att jag sätter förstärkningen hos en SDADC. 1/2x till 32x i förstärkning. Det är bra.
Jag börjar med att kolla om SDADC är redo.
Sedan så sätter jag init mode till 1
Sedan kollar jag på svaret jag får från registret.
Där efter om allt är OK, dvs isAtInitMode blev inte false. Då sätter jag förstärkningen. Jag hade tidigare problem med att sätta förstärkningen då jag glömde nollställa bitten.
Sedan stänger jag ned initsaliseringen.
Detta är bättre än STM32:egna HAL-funktioner för att sätta förstärkningen. Nu sätter jag endast förstärkningen, och inget annat.
Det jag har gjort här är att jag sätter förstärkningen hos en SDADC. 1/2x till 32x i förstärkning. Det är bra.
Jag börjar med att kolla om SDADC är redo.
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);
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
- JimmyAndersson
- Inlägg: 26308
- Blev medlem: 6 augusti 2005, 21:23:33
- Ort: Oskarshamn (En bit utanför)
- Kontakt:
Re: Någon som förstår det där med DMA i STM32?
” Efter några försök så har jag lyckats för första gången att programmera en STM32 med register endast.”
Grattis!
Det tar tid i början, men efter hand så kommer man ihåg ganska mycket utantill och resten kan man snabbt hitta, eftersom man lärt sig var det finns. Så på sikt går faktiskt ”registerprogrammering” fortare för att nå från noll till färdigt.
Men det finns ju inget som säger att man måste välja *ett* sätt och enbart använda det.
(Sedan finns det egentligen inget som heter ”registerprogrammering, men det är en annan sak. )
Grattis!
Det tar tid i början, men efter hand så kommer man ihåg ganska mycket utantill och resten kan man snabbt hitta, eftersom man lärt sig var det finns. Så på sikt går faktiskt ”registerprogrammering” fortare för att nå från noll till färdigt.
Men det finns ju inget som säger att man måste välja *ett* sätt och enbart använda det.
(Sedan finns det egentligen inget som heter ”registerprogrammering, men det är en annan sak. )
Re: Någon som förstår det där med DMA i STM32?
Tackar!
Jag valde registerprogrammering (LL (Low Level programmering som det egentligen kallas)) för att jag behövde skriva till enskilda register endast. STM's HAL är helt underbart, men det är väldigt grovt.
Jag måste dock säga att ST's referensmanualer var något oförklarade. Jag menar, efter man har satt hsdadc->Instance->CR1 |= 0x1 << 31 ; så måste man vänta tills hsdadc->Instance->ISR blir & (0x1 << 31) blir större än 0
Det står här inget hur länge man bör vänta. Men jag antar att detta är något som alla processorer beter sig?
Det finns ALLTID kontrollregister. Du sätter ALLTID kontroller registret först, sedan väntar du på interruptregistret?
Jag valde registerprogrammering (LL (Low Level programmering som det egentligen kallas)) för att jag behövde skriva till enskilda register endast. STM's HAL är helt underbart, men det är väldigt grovt.
Jag måste dock säga att ST's referensmanualer var något oförklarade. Jag menar, efter man har satt hsdadc->Instance->CR1 |= 0x1 << 31 ; så måste man vänta tills hsdadc->Instance->ISR blir & (0x1 << 31) blir större än 0
Det står här inget hur länge man bör vänta. Men jag antar att detta är något som alla processorer beter sig?
Det finns ALLTID kontrollregister. Du sätter ALLTID kontroller registret först, sedan väntar du på interruptregistret?
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
- JimmyAndersson
- Inlägg: 26308
- Blev medlem: 6 augusti 2005, 21:23:33
- Ort: Oskarshamn (En bit utanför)
- Kontakt:
Re: Någon som förstår det där med DMA i STM32?
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.
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)
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.
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.
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)
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.
Re: Någon som förstår det där med DMA i STM32?
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.
Så alla processorer, t.ex. AVR, PIC, NPX, Infineon, Intel har detta beteende?
Jag har liksom väldigt svårt att veta vad man ska kolla efter. Troligtvis har det med att jag har bara kört STM32 och STM själva säger att dom ger inget stöd för LL programmering. Endast CubeMX och HAL. Dom verkar lyckas bra också med det då många f.d Arduino-användare använder STM32. Jag gillar verkligen STM32 för att dom är billiga jämfört vad man får tillbaka. Nuvarande STM32 är F373 processorn och den har nästan allt man kan önska sig, utom ethernet. USB har den och det fungerar bra
Jag skulle aldrig kunna programmera en processor igenom att kolla referensmanualen. Jag måste ha ett kodexempel först.
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.
Just nu använder jag DMA på Input Capture och SDADC för att varje gång jag loggar med dessa med interrupt, så stannar LCD skärmen. Men med DMA så är det fritt fram för en annan process att utföra det tråkiga