www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik A/D Wandler am ATMega16 immer 0


Autor: CarstenM (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich versuche vergebens bei meinem ATMega 16  mit 8 Mhz den A/D in 
betrieb zu nehmen.
Dazu habe ich das Beispiel aus dem Tutorial genommen und nur den ADC0 
mit 1,86V beschaltet. Eigentlich hätte ich erwartet nun einen Wert um 
744 zu bekommen aber es steht immer 0 drin.

Am Beispielprogramm habe ich den Prescaler auf 128 gesetzt und ADCL und 
ADCH nacheinander ausgelesen. Ansonsten ist es identisch.



Hat jemand eine Idee wo mein Fehler liegt?
void main(void)  

  char test_1 ="TEST123";
  uint16_t adcvalue_1;
  double adcvalue_2 = 0;
  
  while(1){
  adcvalue_1 = ReadChannel(0);         //Zwischenspeichern des Int-Wertes
  adcvalue_2 = adcvalue_1*0,0025;      //Umwandlung in double-Wert

  ftoa(test_1,adcvalue_2,2,1,0);      //Umwandlun double in char
  
  if(adcvalue_1 != 0)      
  {
    lcd_set_cursor(5,LINE0+10);      //Ausgabe auf dem LCD
    lcd_puts(small_font, test_1);    //Ausgabe auf dem LCD
    _delay_ms(400);
    }
  }



}

uint16_t ReadChannel(uint8_t mux)
{
  uint8_t i;
  uint16_t result;
 
  ADMUX = mux;
  ADMUX |= (1<<REFS1) | (1<<REFS0);
  ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);
  ADCSRA |= (1<<ADSC);
  while ( ADCSRA & (1<<ADSC) ) 
  {
     ;     
  }
  result = ADCL;
  result += (ADCH<<8);  
  result = 0;
 
  for( i=0; i<1; i++ )
  {
    ADCSRA |= (1<<ADSC); 
    while ( ADCSRA & (1<<ADSC) )
    {
      ;   
    }
    result = ADCL;
  result += (ADCH<<8);
  }
  ADCSRA &= ~(1<<ADEN);
 
  result /= 1; 
  return result;
}

Gruß
Carsten

Autor: Naja (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Welches Tutorial soll denn das gewesen sein? Kann man gleich mal 
sperren.

Das hier fand ich extrem lehrreich.

result /= 1;

Autor: CarstenM (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hehe,

dort stand mal:

result /= 4;

mit der for-schleife darüber sollte dann ein Mittelwert gebildet werden.
Aber die Schleife läuft zurzeit nur 1x. Ich wollte es nicht löschen, ich 
war da nur faul.

Naja und das Tutorial komm von hier ;)


http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

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

Bewertung
0 lesenswert
nicht lesenswert
Naja schrieb:
> Welches Tutorial soll denn das gewesen sein? Kann man gleich mal
> sperren.

Nö, wieso?
Es wäre besser erst mal C zu lernen, ehe man das Tutorial angreift :-)


Hier
  adcvalue_2 = adcvalue_1*0,0025;      //Umwandlung in double-Wert
multiplizierst du mit 0

Kommazahlen werden in Programmiersprachen immer in englischer 
Schreibweise, also mit Dezimalpunkt geschrieben.
  adcvalue_2 = adcvalue_1*0.0025;      //Umwandlung in double-Wert

dann klappts auch mit dem Auswerten.

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

Bewertung
0 lesenswert
nicht lesenswert
Das hier

  char test_1 ="TEST123";

gheht auch nicht.
Wie willst du eine komplette Zeichenkette in einer Variablen speichern, 
die gerade einmal 1 Zeichen aufnehmen kann?
Hat dein Compiler den dazu gar nichts gesagt?

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

Bewertung
0 lesenswert
nicht lesenswert
ftoa(test_1,adcvalue_2,2,1,0);      //Umwandlun double in char


was ist das für eine Funktion?

Die C-Standardfunktion dafür heisst zwar auch ftoa, die kann es aber 
nicht sein. Die hat andere Argumente.
Und schau dir die Argmuente dafür an. Die erste Zahl ist üblicherweise 
die komplette Anzahl an Stellen. Bei dir wären das 2. Das wird ein 
bischen eng wenn du Kommazahlen ausgibst. Bereits die Vorkommastelle und 
der Dezimalpunkt belegen die vorgesehenen 2 Zeichen.

Autor: CarstenM (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

danke für den Hinweis. Du hast recht es muss natürlich 0.0025 heißen.
Nur hast du leider folgendes übersehen:

[c]
if(adcvalue_1 != 0)
{
   lcd_set_cursor(5,LINE0+10);
   lcd_puts(small_font, test_1);
   _delay_ms(400);
}

Egal was in adcvalue_2 steht, angezeigt wir nur etwas, wenn adcvalue_1 
!=0 ist. Und darin sollte der Wert vom Register stehen.
Nur wieso ist das nicht so?

Muss ich die externe Beschaltung noch ergänzen? Oder reicht es einfach 
eine Spannung an ADC0 anzulegen?

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

Bewertung
0 lesenswert
nicht lesenswert
CarstenM schrieb:

> Egal was in adcvalue_2 steht, angezeigt wir nur etwas, wenn adcvalue_1
> !=0 ist. Und darin sollte der Wert vom Register stehen.
> Nur wieso ist das nicht so?

Wieso ist was nicht so?

Das möchte ich ganz gerne sehen, wie du auf einem LCD ausgibst, welches 
nicht initialisiert ist.
Hör auf zu künsteln und fang von vorne an:
ADC Wert ausgeben ohne irgendwelchen Schnickschnack.
Und bevor du das tust, stell sicher, dass dein LCD funktioniert. Schreib 
von mir aus "ADC-Test" irgendwo hin. Und wenn du diesen Text nicht 
siehst, dann ist deine LCD Ansteuerung im A... und nicht der ADC.

Autor: CarstenM (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hier der komplette Quellcode.

Ich wollte mich nur auf den A/D Wandler mit meiner Fragen beziehen.
Der Rest läuft ohne Probleme.

>ftoa(test_1,adcvalue_2,2,1,0);      //Umwandlun double in char
>was ist das für eine Funktion?

Siehe in meinem Quellcode(nunmtostr.c). So kann ich einen array 
erstellen, das beliebige Vor und Nachkommastellen hat. (Stammt auch von 
hier)

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

Bewertung
0 lesenswert
nicht lesenswert
Immer noch:
  char test_1 ="TEST123";


Das geht so nicht!
Du kannst nicht einen kompletten String in einem einzelnen char 
unterbringen!


   char test_l[] = "Test123";

und stell besser sicher, dass der String, der bei ftoa enstehen wird 
auch tatsächlich in das ARray passt. Also besser klotzen und nicht 
kleckern

   char test_l[15];


(Warum verwendest du eigentlich nicht die Standardfunktionen zur ASCII 
Umwandlung?)

Autor: CarstenM (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke erstmal das du dir die Zeit nimmst, alles durchzuschauen.
Ich hab nochmal den Link zum Thread rausgesucht, aus dem ich ftoa habe.

Beitrag "C-Umwandlungsfunktionen für double/int/long nach String"
Ich kenne zwar atoi aber den passenden gegenpart.

Um das ganze einfacher zu machen gehe ich wohl besser auf Anfang und 
werde nur den ADC nutzen und dann alles auf einem PORt ausgeben. 
Vielleicht klappt es dann ja.

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

Bewertung
0 lesenswert
nicht lesenswert
CarstenM schrieb:
> Danke erstmal das du dir die Zeit nimmst, alles durchzuschauen.
> Ich hab nochmal den Link zum Thread rausgesucht, aus dem ich ftoa habe.
>
> Beitrag "C-Umwandlungsfunktionen für double/int/long nach String"
> Ich kenne zwar atoi aber den passenden gegenpart.

itoa :-)
http://www.mikrocontroller.net/articles/FAQ#Wie_ka...

Autor: Naja (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Karl heinz Buchegger

>Naja schrieb:
>> Welches Tutorial soll denn das gewesen sein? Kann man gleich mal
>> sperren.

>Nö, wieso?
>Es wäre besser erst mal C zu lernen, ehe man das Tutorial angreift :-)

CarstenM schrieb:
>Ansonsten ist es identisch.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

>dort stand mal:
>result /= 4;

>adcvalue_2 = adcvalue_1*0,0025;
>char test_1 ="TEST123";

Es wäre besser gewesen erst mal lesen zu lernen, ehe man anderer Leute 
Beiträge angreift :-)

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

Bewertung
0 lesenswert
nicht lesenswert
Naja schrieb:

> Es wäre besser gewesen erst mal lesen zu lernen, ehe man anderer Leute
> Beiträge angreift :-)

Ich vermisse deine konstuktiven Beiträge die mithelfen das Problem des 
TO zu lösen.

Und nein: das er die Mittelwertbildung aus 4 Werten lahmgelegt hat, ist 
nicht das Problem.
Und ja: Die Änderung, die er an der Funktion aus dem Tutorial gemacht 
hat, ist zulässig (wenn er sonst nichts an der Registereinstellung 
verändert hat - habs nicht kontrolliert).
Und ja: Die Funktion aus dem Tutorial funktioniert.

>>dort stand mal:
>>result /= 4;
>
>>adcvalue_2 = adcvalue_1*0,0025;
>>char test_1 ="TEST123";
>

Die erste Modifikation (4->1) ist also kein Problem. Die anderen beiden 
sind echte Fehler, haben allerdings nichts mit dem Tutorial zu tun. 
Warum soll man daher das Tutorial sperren?

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.