Forum: Mikrocontroller und Digitale Elektronik STM32L010 - Wie ADC Kanäle wechseln?


von M. G. (ixil96)


Lesenswert?

Hallo,

ich möchte 3 Messungen an den Pins PA4 (ADC_IN4), PA5 (ADC_IN5) und PA6 
(ADC_IN6) durchführen.
Grundsätzlich funktioniert die ADC conversion, aber sobald sich ein 
Messwert auf einem Kanal ändert werden die anderen Kanäle mit 
beeinflusst.

Irgendwie scheint der Kanalwechsel mit sConfig.Channel = ADC_CHANNEL_xy; 
nicht zu funktionieren.
1
/* Temperatur Innen (PA4) */
2
sConfig.Channel = ADC_CHANNEL_4;
3
HAL_ADC_ConfigChannel(&hadc, &sConfig);
4
ADC_Conversion();
5
...
6
...
7
...
8
/* Temperatur Aussen (PA5) */
9
sConfig.Channel = ADC_CHANNEL_5;
10
HAL_ADC_ConfigChannel(&hadc, &sConfig);
11
ADC_Conversion();
12
...
13
...
14
...
15
16
// Hier die ADC-Initialisierung
17
18
static void MX_ADC_Init(void)
19
{
20
  ADC_ChannelConfTypeDef sConfig = {4};
21
22
  /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) 
23
  */
24
  hadc.Instance = ADC1;
25
  hadc.Init.OversamplingMode = DISABLE;
26
  hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
27
  hadc.Init.Resolution = ADC_RESOLUTION_12B;
28
  hadc.Init.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
29
  hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
30
  hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
31
  hadc.Init.ContinuousConvMode = DISABLE;
32
  hadc.Init.DiscontinuousConvMode = DISABLE;
33
  hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
34
  hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
35
  hadc.Init.DMAContinuousRequests = DISABLE;
36
  hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
37
  hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
38
  hadc.Init.LowPowerAutoWait = DISABLE;
39
  hadc.Init.LowPowerFrequencyMode = DISABLE;
40
  hadc.Init.LowPowerAutoPowerOff = DISABLE;
41
  if (HAL_ADC_Init(&hadc) != HAL_OK)
42
  {
43
    Error_Handler();
44
  }
45
}

von Stefan F. (Gast)


Lesenswert?

M. G. schrieb:
> sobald sich ein Messwert auf einem Kanal ändert werden die
> anderen Kanäle mit beeinflusst.

Das ist völlig normal, solange die Eingänge offen in der Luft herum 
hängen oder mit einer zu hochohmigen Quelle angetrieben werden. Jetzt 
wäre also dein Schaltplan von Interesse.

von M. G. (ixil96)


Angehängte Dateien:

Lesenswert?

Hier der Schaltplanausschnitt

Die ADCs hängen nicht in der Luft! An ADC4 und an ADC5 hängt jeweils ein 
100k NTC.

An ADC6 hängt ein 10k-Poti (Wenn ich hier den Widerstand verändere, 
ändern sich auch die Werte von ADC4 und ADC5)

Z.B:

adcVal4 = 1772
adcVal5 = 1772
adcVal6 = 1745

Dann ändere ich den Widerstand an ADC6 und bei der nächst folgenden 
Conversion erhalte ich:

adcVal4 = 1096
adcVal5 = 1097
adcVal6 = 1110

Meine Conversion sieht so aus:
1
void ADC_Conversion(void)
2
{
3
  adcRawValue = 0;
4
5
  for(int i=0; i<50; i++)
6
  {
7
    HAL_ADC_Start(&hadc);
8
    if (HAL_ADC_PollForConversion(&hadc, 5) == HAL_OK)
9
    {
10
      adcRawValue += HAL_ADC_GetValue(&hadc);
11
    }
12
  }
13
}

von Stefan F. (Gast)


Angehängte Dateien:

Lesenswert?

M. G. schrieb:
> An ADC4 und an ADC5 hängt jeweils ein 100k NTC.

100kΩ ist sicher zu hochohmig. Bei AVR werden 10kΩ als Maximum 
empfohlen, bei STM32 wird es sicher ähnlich sein.

Grund: Im ADC befindet sich ein Kondensator, der schnell genug 
(innerhalb der Sampling Time) umgeladen werden muss. Wenn die Quelle zu 
hochohmig ist, dauert das zu lange.

von M. G. (ixil96)


Lesenswert?

Deine Argumente sind sicher zu beachten, wobei ich habe das gleiche 
Projekt mit einem STM32L476 im Test. Da funktioniert alles ohne 
Probleme.

Ich habe jetzt auch die sampling time mit
1
hadc.Init.SamplingTime = ADC_SAMPLETIME_79CYCLES_5;
auf 79,5 Zyklen erhöht und zwischen den ADC conversions ein delay von 
100ms eingefügt. Es ändert sich aber nichts.

von Stefan F. (Gast)


Lesenswert?

Probiere mal zum Vergleich einen anderen Code: 
http://stefanfrings.de/stm32/stm32l0.html#analog

von Gerd E. (robberknight)


Lesenswert?

Stefanus F. schrieb:
> M. G. schrieb:
>> An ADC4 und an ADC5 hängt jeweils ein 100k NTC.
>
> 100kΩ ist sicher zu hochohmig.

klar. Aber er hat jeweils 1 µF an den ADC-Pins. Das ist wesentlich 
Größer als der Sample-Kondensator des ADC und sollte bei langsamem 
Samplen helfen.

Was ist VREF-18 für eine Quelle?

Ist die stabil während des Messens und beim Umstellen des Potis -> 
Nachmessen mit Multimeter, evtl. auch mit Oszi auf Schwingen testen.

Wie sieht die Versorgung des STM32L010 aus? Ist die stabil?

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

Gerd E. schrieb:
> Aber er hat jeweils 1 µF an den ADC-Pins. Das ist wesentlich
> Größer als der Sample-Kondensator des ADC und sollte bei langsamem
> Samplen helfen.

Was ein Punkt wäre, den M.G. prüfen sollte. Haben die Kondensatoren 
zwischen den Messungen genug Zeit, sich zu erholen?

von M. G. (ixil96)


Angehängte Dateien:

Lesenswert?

VREF-18 ist eine 2V Spannungsreferenz (MCP1501-20)

Die Referenz ist lt. Oszi alles andere als stabil...eher ein schöner 
Sinusgenerator :-(

Wobei das sollte aber nicht das eigentliche Problem sein.

von M. G. (ixil96)


Lesenswert?

Stefanus F. schrieb:
> Gerd E. schrieb:
>> Aber er hat jeweils 1 µF an den ADC-Pins. Das ist wesentlich
>> Größer als der Sample-Kondensator des ADC und sollte bei langsamem
>> Samplen helfen.
>
> Was ein Punkt wäre, den M.G. prüfen sollte. Haben die Kondensatoren
> zwischen den Messungen genug Zeit, sich zu erholen?

Ich mache hier ein delay von 100ms zwischen den conversions

von Stefan F. (Gast)


Lesenswert?

M. G. schrieb:
> Wobei das sollte aber nicht das eigentliche Problem sein.

Sicher? Das ist doch (wie du schon erkannt hast) keine Referenz, die 
diesen Namen verdient hat.

von M. G. (ixil96)


Lesenswert?

So, ich habe die Referenz nun entfernt und die Versorgung von 3,3V auf 
die Pins geführt. Die Versorgungsspannung ist stabil, aber das Ergebnis 
ist das selbe.

Ich kann irgendwie die Channels nicht einstellen (wechseln) :-(

von Dennis (Gast)


Lesenswert?

M. G. schrieb:
> Ich kann irgendwie die Channels nicht einstellen (wechseln) :-(

Irgendwie solltest du das ReferenceManual konsultieren und den 
entsprechenden Register händisch setzen :-)

Dann ein Breakpoint und du hast eine klare Aussage was nicht 
funktioniert.

von M. G. (ixil96)


Lesenswert?

Dennis schrieb:
> M. G. schrieb:
>> Ich kann irgendwie die Channels nicht einstellen (wechseln) :-(
>
> Irgendwie solltest du das ReferenceManual konsultieren und den
> entsprechenden Register händisch setzen :-)

Nun ja, das kann man sicherlich machen, aber wofür gibt es dann die HAL 
Library? HAL sollte eben genau diese Arbeit (Studieren des Datenblattes) 
dem Programmierer zu einem großen Teil abnehmen.

von einfügen (Gast)


Lesenswert?

> HAL sollte eben genau diese Arbeit (Studieren des Datenblattes)
> dem Programmierer zu einem großen Teil abnehmen.

Ich wünsche Dir, dass Du Deinen Optimismus behältst, fürchte aber, dass
er leicht realitätsfremd ist.

HAL ist lediglich der mehr oder weniger abstrahierte Registerzugriff...

von Harry L. (mysth)


Lesenswert?

M. G. schrieb:
> HAL sollte eben genau diese Arbeit (Studieren des Datenblattes)
> dem Programmierer zu einem großen Teil abnehmen.

Gresser Irrtum!

HAL erspart dir in bestimmten Situationen Tipp-Arbeit, aber entbindet 
dich keinesfalls davon, die Hardware zu verstehen, die du nutzt, und das 
geht zwangsläufig über das Studium des Handbuch.

Ohne wirst du auch mit HAL weiter im Nebel stochern.

von Stefan F. (Gast)


Lesenswert?

M. G. schrieb:
> Nun ja, das kann man sicherlich machen, aber wofür gibt es dann die HAL
> Library? HAL sollte eben genau diese Arbeit (Studieren des Datenblattes)
> dem Programmierer zu einem großen Teil abnehmen.

Das tut sie auch, wenn man sie richtig anwendet und sie keinen Bug hat. 
Das Problem ist meiner Meinung nach die extrem knappe Dokumentation. 
Vollständig wird sie erst, wenn man zusätzlich das Referenzhandbuch 
versteht und in die Quelltexte der HAL schaut.

Ein Schritt weiter wäre dann, es ohne HAL selbst zu programmieren. Dann 
braucht man keine Bugs in fremdem Code zu vermuten/suchen. Allerdings 
sind die STM32 Controller nicht gerade trivial zu programmieren. Für 
meine erste ADC Abfrage brauchte ich einen ganzen Tag, bis sie 
funktionierte.

Egal wie man es macht, es ist immer ein Haken.

Es scheint mir am sinnvollsten, zuerst mal eine Weile ohne HAL zu 
programmieren, um sich mit dem Chip und seiner Doku vertraut zu machen. 
Danach kann man dann eventuell auf die HAL wechseln.

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.