mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Atmega328 Hilfe mit ADC


Autor: 328_Hilfloser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

Ich benutze einen Atmega328 und möchte mit dem ADC ein 
Wiederstandsnetzwerk auswerten. Ich benutze den Quellcode aus dem 
AVR-GCC Tut.

Probiere jetzt schon seit 2 Tagen aber komme zu keinem Ergebnis, der 
Wert auf meinem Display zeigt immer 1023. Egal was ich versuche. An 
meiner Schaltung liegt es denk ich nicht.

Am Ausgang meines Netzwerkes liegen wie gewünscht Werte zwischen 0-5V 
an.
Ich Arbeite am mit einem Prozessortakt mit 20000000 Hz und einem ADC 
Vorteiler von 128.

Auf dem Atmega8 lief der Code noch ohne Probleme. Mit der Hilfe des 
Datenblattes komm ich leider auch nicht wirklich weiter. Irgendwas 
übersehe ich noch:( aber was?

/*************************************************************************
Initialisierung des ADW
*************************************************************************/
void ADW_int(char rs1, char rs0)
{
  /*setz Spannungsreferenz*/
  ADMUX = (rs1<<REFS1) | (rs0<<REFS0);
  /* RS1 RS0  Bedeutung
    0 / 0 = Externes AREF
    0 / 1 = Internes AVCC - Versorgungsspannung des Atmega
    1 / 0 = Reserviert
    1 / 1 = Interne Referenzspannung 1,1 V  */
  
  /* setzen des Frequenzvorteilers*/
  ADCSRA = (1<<ADPS0) | (1<<ADPS1) | (1<<ADPS2);
  /*ADPS2  ADPS1  ADPS0  Teilungsfaktor
    0    0    0    2
    0    0    1    2
    0    1    1    4
    1    0    0    16
    1    0    1    32
    1    1    0    64
    1    1    1    128  */
  
  /*muss zwischen 50-200kHz liegen
    bei 20Mhz kommt nur 128 in Frage ~ 156kHz*/
  
  /*ADC aktivieren*/
  ADCSRA = (1<<ADEN);
  
  /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
  also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
  ADCSRA |= (1<<ADSC);          // eine ADC-Wandlung ADSC startet die Wandlung
  while ( ADCSRA & (1<<ADSC) ) {      // auf Abschluss der Konvertierung warten 
  ;}
  
  /* ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten Wandlung nicht übernommen*/
  (void) ADC;    
  
}/*ADW_int*/


/*************************************************************************
ADW-Messung
*************************************************************************/
/* ADC Einzelmessung */
uint16_t ADC_Read( uint8_t channel )
{
  // Kanal waehlen, ohne andere Bits zu beeinflußen
  ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);
  ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
  while (ADCSRA & (1<<ADSC) ) {   // auf Abschluss der Konvertierung warten
  }
  return ADC;                // ADC auslesen und zurückgeben
}

/*MUX3...0
0000  ADC0
0001  ADC1
0010  ADC2
0011  ADC3
0100  ADC4
0101  ADC5
0110  ADC6
0111  ADC7
1000  ADC8*/

/*ADMUX Register
7  REFS1  - Referenzspannung
6  REFS0  - Referenzspannung
5  ADLAR
4  -
3  MUX3  - Kanalwahl
2  MUX2  - Kanalwahl
1  MUX1  - Kanalwahl
0  MUX0  - Kanalwahl*/


/* ADC Mehrfachmessung mit Mittelwertbbildung */
/* beachte: Wertebereich der Summenvariablen */
uint16_t ADC_Read_Avg( uint8_t channel, uint8_t nsamples )
{
  uint32_t sum = 0;
  
  for (uint8_t i = 0; i < nsamples; ++i ) {
    sum += ADC_Read( channel );
  }
  
  return (uint16_t)( sum / nsamples );
}




Testweise rufe ich derzeit so die Funktionen auf:
int main(void)
{
  /* Lokale Variablen */
  uint16_t adw_result = 0;
  /* Konfiguration des LCD */
  lcd_init();
  /* ADW initialisieren*/
  ADW_int(0, 1);
  /* Interrupts global an */
  sei();
  _delay_ms(1000);
    while(1)
    {

        /* Überwacht das Umschalten des Drehschalters */
        adw_result =  ADC_Read_Avg(0,5);
          
          
        char itoa_buf_text_1[5];
          
        lcd_clear();
        lcd_setcursor(0,1);
        lcd_string("ADW - ");

          
        itoa(adw_result, itoa_buf_text_1,10);
        lcd_string(itoa_buf_text_1);
          
        adw_result = 0;
        _delay_ms(100);
    }
}

Ich kann meinen Fehler einfach nicht finden:(
Lg der 328__Verzweifelte

Autor: Matthias S. (Firma: matzetronics) (mschoeldgen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
328_Hilfloser schrieb:
> ADCSRA = (1<<ADEN);

Hmm, überleg doch mal, was mit den vorher gesetzten Prescaler Bits 
passiert, wenn diese Zeile abgearbeitet wird.

328_Hilfloser schrieb:
> Auf dem Atmega8 lief der Code noch ohne Probleme.

Sicher? Kann ich fast nicht glauben.

: Bearbeitet durch User
Autor: 328_Hilfloser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmmm da bin ich wohl sogar zu blöd für Copy & Paste...
Das wars danke:)
Auch wenn ich nicht so recht verstehe wie das passiert ist xD

LG

Autor: tigi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bin momentan beim gleichen Problem...was hast du jetzt also hier 
verändert damit dein Code funktioniert?

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.