Forum: Mikrocontroller und Digitale Elektronik STM 32 IRQHandler


von AndererStudent (Gast)


Lesenswert?

Guten Tag,

Habe ein Problem mit dem ADC auf meinem STM32F3 Nucleo Board. Zwar komme 
ich einmal in meine
1
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* AdcHandle)
2
{
3
   i = HAL_ADC_GetValue(AdcHandle);
4
}

rein. Aber das wars dann auch. Meine adc_init() lautet:
1
void adc_init (void)
2
{
3
4
  ADC_ChannelConfTypeDef sConfig = {0};
5
6
  hadc1.Instance = ADC1;
7
  hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
8
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
9
  hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
10
  hadc1.Init.ContinuousConvMode = DISABLE;
11
  hadc1.Init.DiscontinuousConvMode = DISABLE;
12
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
13
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
14
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
15
  hadc1.Init.NbrOfConversion = 1;
16
  hadc1.Init.DMAContinuousRequests = DISABLE;
17
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
18
  hadc1.Init.LowPowerAutoWait = DISABLE;
19
  hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
20
21
  HAL_ADC_Init(&hadc1);
22
23
24
  sConfig.Channel = ADC_CHANNEL_1;
25
  sConfig.Rank = ADC_REGULAR_RANK_1;
26
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
27
  sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
28
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
29
  sConfig.Offset = 0;
30
31
  HAL_ADC_ConfigChannel(&hadc1, &sConfig);
32
33
  HAL_ADC_Start_IT(&hadc1);
34
  HAL_NVIC_EnableIRQ(ADC1_IRQn);
35
  HAL_NVIC_SetPriority(ADC1_IRQn, 0, 0);
36
37
}

Meine Vermutung wäre, dass das Conversation Complete Flag nicht gelöscht 
wird und deshalb keine neue ausgeführt wird. Allerdings sollte die 
HAL_ADC_GetValue dieses Flag löschen. Hat jemand eine Idee wieso ich nur 
einmal reinkomme?

von pegel (Gast)


Lesenswert?

AndererStudent schrieb:
> hadc1.Init.ContinuousConvMode = DISABLE;

Wenn du das benutzt, musst du immer wieder die Wandlung selbst per 
Software starten. Denn:

  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;

von AndererStudent (Gast)


Lesenswert?

pegel schrieb:
> Wenn du das benutzt, musst du immer wieder die Wandlung selbst per
> Software starten. Denn:
>
>   hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;

Genau lesen sollte man können. Danke. In meinem DR Register des ADC1 
ändern sich die Werte passend zu der Spannung am Analogeingang. 
Allerdings habe ich ein neues Problem.

Wenn ich den ADC starte mit "HAL_ADC_Start_IT(&hadc1)", wird meine Main 
nicht mehr weiter verarbeitet. Scheint so als ob der Interrupt die Main 
dauerhaft unterbricht. Kann das sein? Sollte ich das Ergebnis mittels 
DMA weiterverarbeiten? Soory für die Fragen aber ist mein erster 
größeres Projekt. Bin quasi blutiger Anfänger.

von pegel (Gast)


Lesenswert?

In der HAL Lib sind prima Beispiele für alle Arten von ADC.
Probier die einfach aus. Es braucht nicht viel Tipparbeit um alle 
Möglichkeiten zu verstehen.

von AndererStudent (Gast)


Lesenswert?

pegel schrieb:
> In der HAL Lib sind prima Beispiele für alle Arten von ADC.
> Probier die einfach aus. Es braucht nicht viel Tipparbeit um alle
> Möglichkeiten zu verstehen.

War das ein indirektes Ja für den DMA? Habe schon paar Beispiele gesehen 
und auch gelesen, dass die Interrupts die Main() beeinflussen können, 
allerdings habe ich gedacht, das geschieht erst paar höherer Sample 
Rate?!

von pegel (Gast)


Lesenswert?

Ob DMA oder nicht kannst du selbst entscheiden.

Ich habe es noch nicht geschafft mit Interrupts die main zu behindern.

Vielleicht solltest du dir die Int Prioritäten genauer ansehen.

von Bernd K. (prof7bit)


Lesenswert?

AndererStudent schrieb:
> Scheint so als ob der Interrupt die Main
> dauerhaft unterbricht.

Wenn sowas passiert (auch bei anderen Interrupts) dann wird

* entweder das Interruptflag nicht zurückgesetzt.
* oder der Interrupt mit zu hoher Frequenz aufgerufen so daß der nächste 
Interrupt schon ansteht bevor der Interrupt überhaupt abgearbeitet ist.

Eins von beiden.

von AndererStudent (Gast)


Lesenswert?

pegel schrieb:
> Vielleicht solltest du dir die Int Prioritäten genauer ansehen.

Meinst du die Prioritäten beim NVIC? Ist doch relativ, da die main 
darüber steht?

von pegel (Gast)


Lesenswert?

Benutzt du jetzt ContinuousConvMode?

Dann mach mal die

  sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;

Zeit größer. Dann gibt es weniger Interrupts.

Und ja, es geht um den NVIC.

von AndererStudent (Gast)


Lesenswert?

pegel schrieb:
> Benutzt du jetzt ContinuousConvMode?
>
> Dann mach mal die
>
>   sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
>
> Zeit größer. Dann gibt es weniger Interrupts.
>
> Und ja, es geht um den NVIC.

Ja benutze jetzt ContinousConvMode. Handelte sich wirklich um die 
Sampletime. Weis aber nicht wieso die Standardmäßig zu hoch sein sollte. 
Naja muss dann wohl auf DMA zurückgreifen um sie wieder hoch zu 
bekommen. Es funktioniert bin aber dennoch verwirrt. Danke trotzdem

von pegel (Gast)


Lesenswert?

AndererStudent schrieb:
> auf DMA zurückgreifen um sie wieder hoch zu bekommen

Beachte aber dabei die AN über Zykluszeit <-> Genauigkeit um die beste 
Lösung für deine Aufgabe zu finden.

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.