Forum: Mikrocontroller und Digitale Elektronik STM32 - ADC-DMA1-IRQ-Handler macht Unsinn


von Walter T. (nicolas)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,
angefangen hat die Problemstellung in einem anderen Thread ( 
Beitrag "Re: STM32: Suche Hilfe zu ADC" ), hat 
sich aber inhaltlich schon ein Stück davon entfernt, so daß ein neuer 
Thread sinnvoll erscheint.

Ich nutze auf einem STM32F103 den ADC1, um zyklisch 10 ADC-Kanäle 
abzufragen und per DMA in ein Array zu schreiben. Nachdem alle Kanäle 
digitalisiert sind, soll der Inhalt des Arrays mit ein paar kleinen 
Berechnungen in einem struct gespeichert werden. Dazu nutze ich den 
Interrupt-Handler vom DMA ( DMA1_Channel1_IRQHandler ).

Um das Ganze zu testen, werden in der Hauptschleife (zu finden in 
edm_test_adc() ) die Inhalte des Arrays zyklisch auf einem Display 
dargestellt und fernerhin die daraus berechneten Werte des structs 
(gls_adc). Die Werte des Arrays sehen immer plausibel aus (und ändern 
sich auch passend zu den testhalber angeschlossenen Potis). Die daraus 
berechneten Inhalte des struct sind aber völlig inplausibel. Es sieht so 
aus, als hätte das Array zum Zeitpunkt des Interrupts andere Werte als 
beim Auslesen aus der Hauptschleife.

Um die Sache noch etwas verwirrender zu machen, kopiere ich die 
gesampleten Werte in zwei globale Variablen (gl_a und gl_b). Werden die 
Variable explizit initialisiert, also:
1
volatile uint16_t gl_a = 0;
2
volatile uint16_t gl_b = 0;
so sieht man in ihnen die gleichen merkwürdigen Werte, wie sie auch dem 
Struct zugrundeliegen. Werden sie dageben implizit initialisiert, also:
1
volatile uint16_t gl_a;
2
volatile uint16_t gl_b;
stürzt die Interrupt-Routine ab, sollte darin hineingeschrieben werden.

Deswegen habe ich zwei Fragen:
 1. Wie kann es sein, daß ein Array in einem IRQ-Handler anders 
ausgelesen ist als sonst und
 2. Wieso initialisiert der ARM-GCC globale Variablen nicht implizit mit 
0?

Viele Grüße
W.T.

Edit: Die Variable uint16_t ADC1ConvertedValues[NCHANNEL+1] ist 
natürlich volatile, ich kann nur Anhänge nicht mehr nachträglich 
austauschen.

von Dr. Sommer (Gast)


Lesenswert?

Walter Tarpan schrieb:
> 2. Wieso initialisiert der ARM-GCC globale Variablen nicht implizit mit
> 0?
Doch, macht er. Wenn was anderes drinsteht hast du ungültige 
Speicherzugriffe / Buffer-Overflows oder so. Mach mal einen Data 
watchpoint drauf...

von Ert (Gast)


Lesenswert?

mach ein extern aus dem volatile

von Walter T. (nicolas)


Angehängte Dateien:

Lesenswert?

Ich habe mal eine Minimalversion gebastelt, die sich "builden" läßt. Es 
sind wegen des Display doch nocht recht viele Dateien, aber alles für 
das Problem relevante befindet sich im Ordner "common/src_edm/".

Ert schrieb:
> mach ein extern aus dem volatile

In der einen Datei ist es "volatile" und in der anderen "extern 
volatile" - wie sich die Sache gehört.

Dr. Sommer schrieb:
> Wenn was anderes drinsteht hast du ungültige
> Speicherzugriffe / Buffer-Overflows oder so. Mach mal einen Data
> watchpoint drauf...

Beim Minimalbeispiel tritt dieses eine Problem nicht mehr auf... beim 
vollen Beispiel wurde ab "ADC_Init" ein Wert dort hineingeschrieben. Da 
muß ich mir die Speicherbelegung vom "großen" Beispiel nochmal ansehen- 
da mußte ich nämlich auch zum ersten Mal die "MAX_STRING_SIZE" 
hochsetzen, um den Variableninhalt mit printf darstellen zu können.

Es bleibt also die Frage nach der merkwürdigen Belegung der Variablen.

Gibt es die Möglichkeit, in einen Interrupt-Handler einen Breakpoint zu 
setzen?

: Bearbeitet durch User
von Walter T. (nicolas)


Lesenswert?

Man kann im IRQ-Handler einen Breakpoint setzen, er erscheint nur nicht 
im Rechtsklick-Menu.

Jetzt bin ich wirklich baff: Der Wert für den Kanal POTI_UPDWM_ADCCH 
(=ADC_Channel_13) steht im Array an Stelle 2 und nicht an Stelle 3 wie 
erwartet:

ADC1ConvertedValues[0]  1857  --> SEN-
ADC1ConvertedValues[1]  1748  --> SEN+
ADC1ConvertedValues[2]  387   --> UPDO
ADC1ConvertedValues[3]  1586  --> SEN+
ADC1ConvertedValues[4]  0     --> ISOLL
ADC1ConvertedValues[5]  1412  --> SEN+
ADC1ConvertedValues[6]  0     --> T_OFF
ADC1ConvertedValues[7]  1332  --> SEN+
ADC1ConvertedValues[8]  0     --> T_ON
ADC1ConvertedValues[9]  1294  --> SEN+
ADC1ConvertedValues[10]  17476

Warum ist die Tabelle um einen Eintrag versetzt?

P.S.: Die Eingänge ADC_SENSE0_ADCCH und ADC_SENSE1 floaten noch frei, 
die Werte sind also nicht verwunderlich. Nur wo sie eingetragen sind (0 
1 3 5 7 und 9) wundert mich.

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.