ADC und Ausgabe auf LCD

Gast #4318850
Lesenswert?

Guten Abend zusammen,

trotz Lesens aller möglichen Seiten gelingt es mir nicht,
das beiliegende Prg. so zu gestalten, wie ich's gern hätte.
Hardware STK200, ATmega88, LCD an PortD.
Die Hardware funktioniert mit Bascom wie gewünscht.
LCD Library v. Peter Fleury (PORT geändert). Auch das zugehörige
Testprogramm funktioniert einwandfrei.
Problem: lcd_puts(buffer); gibt nicht die erwarteten 0....1023 aus
sondern eine eher zufällige zweistellige Zahl.
Wo kann der Fehler liegen, im ADC Wandlerteil oder bei der Umwandlung 
mit utoa?
Danke für ev. Hinweise

Toni


#include <stdlib.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <avr/io.h>
#include <inttypes.h>
#include "lcd.h"

uint16_t readADC(uint8_t channel)
 {
  uint8_t i;
  uint8_t ADC_temp;
  uint8_t ADCH_temp;
  uint16_t result = 0;


  // Den ADC aktivieren und Teilungsfaktor auf 64 stellen
  ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);

  // Kanal des Multiplexers waehlen
  // Avcc als Referenzspannung verwenden
  ADMUX = channel  | (0<<REFS1) | (1<<REFS0);

  // Den ADC initialisieren und einen sog. Dummyreadout machen
  ADCSRA |= (1<<ADSC);
  while(ADCSRA & (1<<ADSC));

  // Jetzt 3x die analoge Spannung am Kanal "channel" auslesen
  // und dann Durchschnittswert ausrechnen.
  for(i=0; i<3; i++) {
    // Eine Wandlung
    ADCSRA |= (1<<ADSC);
    // Auf Ergebnis warten...
    while(ADCSRA & (1<<ADSC));

    //Ergebnisregister auslesen
        ADC_temp = ADCL;
        ADCH_temp = ADCH;
    ADC_temp += (ADCH_temp << 8);

    result += ADC_temp;
  }


  // ADC wieder deaktivieren
  ADCSRA &= ~(1<<ADEN);

  result /= 3;

  return result;
}

int main(void)
 {

  char buffer[7];
  //Auslesen der analogen Spannung an ADC0,
  //In result steht das Ergebnis.
  uint16_t result = readADC(0);


  //initialize display, cursor blinkt
    lcd_init(LCD_DISP_ON_CURSOR_BLINK);

  //clear display and home cursor
    lcd_clrscr();

  //integer in ASCII umwandeln
  utoa( result , buffer, 10);

  lcd_puts("Ergebnis:\n");
  lcd_puts(buffer);

  return 0
  }
#4318950
Lesenswert?

In C brauchst du diesen 'komplizierten' Teil
1
ADC_temp = ADCL; ADCH_temp = ADCH;
2
ADC_temp += (ADCH_temp << 8);
3
result += ADC_temp;

überhaupt nicht. Du verwendest einfach das Pseudo-Register 'ADC' und der 
Compiler dröselt das alles richtig auf und setzt die Werte für dich 
zusammen
1
  for(i=0; i<3; i++) {
2
    // Eine Wandlung
3
    ADCSRA |= (1<<ADSC);
4
    // Auf Ergebnis warten...
5
    while(ADCSRA & (1<<ADSC));
6
    //Ergebnisregister auslesen
7
    result += ADC;
8
  }

Siehe auch den ADC Abschnitt im AVR-GCC-Tutorial
#4319237
Lesenswert?

Toni schrieb:
> Das hatte ich auch versucht, aber irgendwie trotzdem
> die falsch deklarierte Variable im Spiel gehabt!

:-)
Wie kann eine Variable, die gar nicht gebraucht wird und daher im Code 
gar nicht mehr existiert, falsch deklariert sein?
:-)

(genau das ist der springende Punkt. Da geht es nicht nur darum, dass 
der Code kürzer wird. Es geht auch darum, dass durch die Vereinfachung 
auch Fehlerquellen wegfallen)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren