Forum: Mikrocontroller und Digitale Elektronik Kontinuierliche ADC Werte vom STM8


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Hallo,
ich habe hier eine kleine Schaltung mit einem STM8L051F3 (verwende zum 
Entwickeln gerade ein STM8L152C6), bei der ich eine analoge Spannung 
messen muss und die dann auf einen I2C Bus geben muss. Um das ganze 
möglichst einfach zu halten, wollte ich den ADC starten, in der ISR des 
ADC den Wert speichern und aus der ISR das samplen wieder starten. In 
einer Hauptschleife würde ich den Wert da ab und zu nehmen und auf den 
I2C Bus schreiben. Die ISR wird auch ausgeführt, allerdings bekomme ich 
in der ISR keine sinvollen Werte (wechselnde Werte im Bereich ~0x7ed bis 
0x80d).

Der Dokumentation nach, müsste das "eigentlich" ganz einfach sein: ADC 
anschalten, "single conversion mode" auswählen, DMA ausschalten, den 
richtigen Kanal wählen und Messung starten. Das ich den richtigen Kanal 
gewählt habe, habe ich schon drei mal überprüft (pin PB0, Channel 18). 
Was mich ein wenig wundert, dass in der ISR neben, dem "End of 
Conversion" Flag, auch das "Overrun" Flag gesetzt ist. Es sollte aber 
nur der EOC Interrupt enabled sein.

Hier meine Initialisierung:
1
void ADC_Init(void)
2
{
3
    CLK->PCKENR2 |= 0x01; /* Enable clock to ADC */
4
5
    // Switch on ADC
6
    ADC1->CR1 = 1;
7
    delay( 2 ); // 2 ms
8
9
    /* reset all interrupt flags */
10
    ADC1->SR &= ~0x07;
11
12
    /* disable DMA for single conversion */
13
    ADC1->SQR[1] |= 0x80;
14
15
    /* PB0 (channel 18) for STM8L051F3 and STM8L152C6 */
16
    ADC1->SQR[2] = 1 << (18 - 16);
17
18
    /* 12 bit resolution
19
       Interruptenable for end of conversion
20
       single conversion
21
       Conversion start
22
       ON */
23
    ADC1->CR1 = 0x09;
24
25
    /* conversion start */
26
    ADC1->CR1 |= 2;
27
}

und hier die ISR:
1
void ADCInterruptHandle (void) __interrupt( 18 )
2
{
3
    uint8_t low, high;
4
5
    low  = ADC1->DRL;
6
    high = ADC1->DRH;
7
8
    voltage = low | ( high << 8 );
9
10
    /* conversion start */
11
    ADC1->CR1 |= 2;
12
}

Im Moment lese ich den `voltage` Wert in der Hauptschleife einmal in der 
Sekunde aus und schreibe Ihn aus Terminal / Uart.

Kann hier jemand helfen? Irgend welche Tipps, hilfreichen Kommentare?

Schönen Dank im Voraus,
Torsten

von Torsten C. (torsten_c) Benutzerseite


Lesenswert?

Torsten Robitzki schrieb:
> Bereich ~0x7ed bis 0x80d

Das sind 0x7FD plusminus 0,8%, ist doch gut.

Haben VDDA (PIN 11) und VDD (PINs 10 + 39) getrennte Spannungsregler?

Oder benutzt Du VREF (PIN12) und ein TL431/TL432 oder so?

Sind VSSA (PIN 9) und VSS (PIN 40) mit einem SMD-Ferrit entkoppelt?

Falls nicht, ist das Ergebnis etwa so, wie ich es erwarten würde.

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Hallo Torsten,

Torsten C. schrieb:
> Torsten Robitzki schrieb:
>> Bereich ~0x7ed bis 0x80d
>
> Das sind 0x7FD plusminus 0,8%, ist doch gut.

Ja, aber: Ich habe die gleichen Werte, wenn ich 0V am Pin anlege und 
wenn ich 3,3Volt anlegen :-(

> Haben VDDA (PIN 11) und VDD (PINs 10 + 39) getrennte Spannungsregler?

Ich werde aus dem Schaltplan nicht so ganz schlau 
(http://www.st.com/st-web-ui/static/active/en/resource/technical/document/user_manual/CD00278045.pdf), 
ich glaube aber eher nein.

> Oder benutzt Du VREF (PIN12) und ein TL431/TL432 oder so?

Sprich, externe Spannungsreferenz? Nein.

> Sind VSSA (PIN 9) und VSS (PIN 40) mit einem SMD-Ferrit entkoppelt?

Die liegen beide auf Masse.

> Falls nicht, ist das Ergebnis etwa so, wie ich es erwarten würde.

Ich aber nicht ;-) Klingt so, als wenn ich doch auf dem flashcen Kanal 
messe?

Einen Fehler habe ich schon gefunden. Laut Datenblatt muss ich zuerst 
das hi-Byte und dann das lo-Byte lesen. Im Ergebnis macht das leider 
keinen Unterschied.

Schönen Dank,
Torsten

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Juhu, ich habe den Fehler gefunden. Der Header von ST macht aus den vier 
Registern SQR1-SQR4 ein Array! Und dem entsprechend ist ADC1->SQR1 
natürlich ADC1->SQR[ 0 ] :-)

Kryptischer geht's nimmer!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.