mikrocontroller.net

Forum: Compiler & IDEs ADC Mega 128


Autor: Florian M. (skywalker79)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich versuche mich grade daran, den ADC vom Mega 128 in Gang zu bringen. 
Nach langem lesen vom Forum und dem Tutorial bin ich zu folgenden 
Quellcode gekommen:

#include <avr/io.h>



uint8_t i;
uint16_t result = 0;

void adc_init_ch0(void)     // Initialisierung von ADC-Kanal 0
{
  ADMUX = 0x00;       // Spannungsmessung an PA0
  ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); // ADC aktiviert, 
ADC Freilaufmodus, Vorteiler auf 128
  ADMUX |= (1<<REFS0)|(1<<REFS1);  // Interne Referenzspannung nutzen
  SFIOR = 0;            // Spezialfunktionen Ausschalten
}



void main(void)
{
  adc_init_ch0();

  ADCSRA |= (1<<ADSC);
  while (ADCSRA & (1<<ADSC)) // Dummy-Messung um den ADC warmlaufen zu 
lassen
  {
    ;
  }


  for(i=0;i<2;i++)
  {
    ADCSRA |= (1<<ADSC);                              // eine Wandlung 
"single conversion"
    while ( ADCSRA & (1<<ADSC) ) // auf Abschluss der Konvertierung 
warten
    {
      ;
    }
    result += ADCW;    / Wandlungsergebnisse aufaddieren
  }
    ADCSRA &= ~(1<<ADEN);                       // ADC deaktivieren

    result /= 2;           // Summe durch zwei teilen = arithm. 
Mittelwert


}

Testweise versuch ich den gemessenen Wert mit einem Referenzwert zu 
vergleichen und lasse je nachdem ob er höher oder niedriger als der 
gemessene Wert ist, eine LED leuchten.
Leider bekomme ich hierbei keine nachvollziehbaren Ergebnisse. Könnt Ihr 
mir sagen, ob der Code bis jetzt so richtig ist, bzw. was ich daran 
verbessern kann?

mfg Florian

Autor: Magnus Müller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Testweise versuch ich den gemessenen Wert mit einem Referenzwert zu
> vergleichen und lasse je nachdem ob er höher oder niedriger als der
> gemessene Wert ist, eine LED leuchten.
> Leider bekomme ich hierbei keine nachvollziehbaren Ergebnisse. Könnt Ihr
> mir sagen, ob der Code bis jetzt so richtig ist, bzw. was ich daran
> verbessern kann?

Der Code ist nicht vollständig.

* wo ist die Auswertung deines gemittelten Wertes?
* wo werden die LEDs abhängig vom Ergebnis gesetzt?
* warum läuft das (Test-)Programm nicht in einer Schleife?
* was meinst du mit "keine nachvollziehbaren Ergebnisse"?

Gruß,
Magnetus

Autor: Florian M. (skywalker79)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aufgerufen wird die Messung durch Übermittlung eines Zahlenwertes per 
RS232.

if (UDR1=='4')
  {
  uart_puts (status4); // Messung aktiviert
  adc_ch0();           // ruft Unterprogramm adc auf
  }


  if (UDR1=='5')
  {
  uart_puts (status5); // Messung gestoppt
  adc_ch1();           // ruft Unterprogramm adc auf
  }

das ganze läuft in einer Endlosschleife. Es soll also bei 
Zeichenübermittlung immer eine Messung durchgeführt werden.
mit adc_ch0 bzw. adc_ch1 wird das oben schon geschriebene aufgerufen.

void adc_ch0(void)
{
  adc_init_ch0();

  ADCSRA |= (1<<ADSC);
  while (ADCSRA & (1<<ADSC))                            // Dummy-Messung 
um den ADC warmlaufen zu lassen
  {
    ;
  }


  for(i=0;i<2;i++)
  {
    ADCSRA |= (1<<ADSC);                              // eine Wandlung 
"single conversion"
    while ( ADCSRA & (1<<ADSC) )                     // auf Abschluss 
der Konvertierung warten
    {
      ;
    }
    result += ADCW;                                   // 
Wandlungsergebnisse aufaddieren
  }
    ADCSRA &= ~(1<<ADEN);                                // ADC 
deaktivieren

    result /= 2;                                          // Summe durch 
zwei teilen = arithm. Mittelwert

    if (result < (2*1023)/5)
      batt_blinky();
  if (result > (2*1023)/5)
      uart_blinky();

}

hier mal nur für Kanal 0.
Mit keine nachvollziehbaren Ergebnisse meinte ich, das mal batt_blinky() 
und mal uart_blinky() aufgerufen wird, obwohl immer dieselbe Spannung am 
ADC hängt. Im Moment ist das zu Testzwecken einfach Masse.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da würde ich dir doch mal vorschlagen, das ganze abzuspecken,
extrem zu vereinfachen und den UART (den du offensichtlich
schon in Betrieb hast) dazu zu benutzen, die Messergebnisse
auszugeben. Wenn du das nicht willst, würde ich mal den
Messwert komplett auf einen Port ausgeben.

Mit extrem abspecken meine ich:
Nur einen Kanal messen
Eine simple Schleife in main, die
  * den ADC anwirft
  * auf das Ergebnis wartet
  * das Ergebnis auf Port oder UART ausgibt

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>    ADCSRA &= ~(1<<ADEN);                                // ADC
> deaktivieren

Ich seh zwar, dass du den ADC deaktivierst, ich seh aber nirgends
wo du den ADC aktivierst.

Autor: Magnus Müller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger wrote:
>>    ADCSRA &= ~(1<<ADEN);                                // ADC
>> deaktivieren
>
> Ich seh zwar, dass du den ADC deaktivierst, ich seh aber nirgends
> wo du den ADC aktivierst.

Das macht er gleich zu Beginn...

void adc_ch0(void)
{
  adc_init_ch0();
  ...
  ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); // ADC aktiviert
  ...
}

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Magnus Müller wrote:

> Das macht er gleich zu Beginn...

>
>   ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); // ADC aktiviert
> 

...mit dem höchstmöglichen Prescaler.  Wenn der ATmega128 mit seinen
standardmäßigen 1 MHz läuft, tickert der ADC dann mit 8 kHz.  Da wäre
es kein Wunder, dass die Ergebnisse nicht mehr zuverlässig sind.
Nicht nur, dass eine Messung endlos lange dauert, ich wage zu
bezweifeln, dass die sample&hold-Schaltung im Eingang die Spannung so
lange festklemmen kann.

Autor: Florian M. (skywalker79)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

so ich hab den Code jetzt mal ganz zusammengekürzt und lasse jetzt eine 
LED angehen bzw. ausgehen, wenn ich 2,5V bzw. 0V anlege.
Das funktioniert soweilt.
Also denk ich mal, das mein erster Code wohl zu kompliziert war und ich 
nie zum Messen gekommen bin

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]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [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.