Forum: Mikrocontroller und Digitale Elektronik ATmega8 ADC problem


von Rob E. (newgenera2589)


Lesenswert?

Hi

Das Problem was ich habe ist folgendes:

Ich will mit einem Atmega8 einen Widerstand ermitteln können und auf 
einem Display angezeigt bekommen.
Die Schaltung ist aufgebaut und "funktioniert" in dem Sinne, dass das 
Display angesteuert und programmiert werden kann.. doch kriege ich 
keinen ADCH Wert auf ein LCD Display ausgegeben.

Hier ist einmal der Quellcode... ich hoffe einer kann mir erklären wo 
der Fehler oder mein Verständnisproblem liegt.
1
#include <avr/io.h>
2
#include "lcd-routines.h"
3
#include <util/delay.h>
4
5
6
void ADC_Init()
7
{
8
  
9
  uint16_t result;
10
  ADMUX = (0<<REFS0)|(0<<REFS1);                  //Referezspannung auf Extern (bei uns Vcc=5V)
11
  //free runnung nochmal gucken
12
  ADCSRA = (1<<ADPS1);          // Frequenzvorteiler auf 50MHz Teiler durch8 !!!!!!!!!!ungefähr 120mhz!!!!!!!!!
13
  ADCSRA |= (1<<ADEN) | (1<<ADLAR);                // ADC aktivieren
14
  
15
  // ADC wandler Warlaufen lasse
16
  ADCSRA |= (1<<ADSC) | (1<<ADFR);                // eine ADC-Wandlung
17
  while (ADCSRA & (1<<ADSC) )
18
  {                          // auf Abschluss der Konvertierung warten
19
  }
20
  result =ADCL;
21
  result |=(ADCH<<8);                    //ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten Wandlung nicht übernommen.
22
}
23
//-----------------------------------------------ADC Einzelmessung------------------------------------------------------
24
uint8_t ADC_Read( uint8_t channel )        //
25
{
26
  uint16_t result;
27
  
28
  // Kanal waehlen, ohne andere Bits zu beeinflußen
29
  ADMUX = (ADMUX & (~(0x1F))) | (channel & 0x1F);      //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
30
  ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
31
  while (ADCSRA & (1<<ADSC) )
32
  {        // auf Abschluss der Konvertierung warten
33
  }
34
  //result =ADCL;                // ADC auslesen und zurückgeben
35
  //result |=(ADCH<<8);
36
  
37
  return ADCH;
38
}
39
40
int main(void)
41
{
42
  int zahler=0;
43
  uint8_t mess=0;
44
  uint8_t mess2=0;
45
  uint16_t test;
46
  lcd_init();
47
  lcd_string("Bauteilmessgerat");
48
  lcd_setcursor( 0, 2 );
49
  lcd_string("Version 0.1");
50
  _delay_ms(150);
51
  
52
  while(1)
53
  {
54
    lcd_clear();                    //Display Löschen
55
    lcd_setcursor( 0, 1 );                //Springe mit dem Curser in die erste Zeile
56
    lcd_string("Widerstands-");              //Schreibe auf Display
57
    lcd_setcursor( 0, 2 );                //Springe mit dem Curser in die zweite Zeile
58
    lcd_string("messung");  
59
    _delay_ms(100);
60
61
62
while(1)
63
{
64
char messstring[20];
65
char Buffer[20];
66
      zahler++;
67
      lcd_clear();
68
      lcd_setcursor(0,1);
69
70
      itoa( zahler, Buffer, 10 );
71
      lcd_string( Buffer );
72
      lcd_setcursor(0,2);
73
    //  mess= ADC_Read(4);
74
      mess = ADCH;
75
    //  mess2 = 4.8876 * mess;
76
   
77
   itoa( mess, messstring, 10 );
78
   lcd_string( messstring );   
79
  _delay_ms(500);
80
}
81
82
83
  }
84
  return 0;
85
}

: Bearbeitet durch User
von spess53 (Gast)


Lesenswert?

Hi

>ADCSRA |= (1<<ADSC) | (1<<ADFR);

Du willst Free Running?

MfG Spess

von chris (Gast)


Lesenswert?

Rob El schrieb:
> // Frequenzvorteiler auf 50MHz Teiler
> durch8 !!!!!!!!!!ungefähr 120mhz!!!!!!!!!

dieser Kommentar kann mit der Realität irgendwie garnix zu tun haben...

von Detlef K. (adenin)


Lesenswert?

Vielleicht müsste ja mal irgendwo ADC_Init() aufgerufen werden?

Und das hier geht so nicht:
1
  ADCSRA |= (1<<ADSC) | (1<<ADFR);                // eine ADC-Wandlung
2
  while (ADCSRA & (1<<ADSC) )
3
  {                          // auf Abschluss der Konvertierung warten
4
  }
Wenn Du ADFR setzt, dann wird automatisch immer wieder eine neue 
Wandlung gestartet.
ADSC wird in dem Fall nie zurückgesetzt.
Du könntest aber hier auf ADIF=1 warten, musst es aber von Hand 
zurücksetzten. ACHTUNG! Zurückgesetzt wird ADIF, indem man eine 1 
hineinschreibt!

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Detlef Kunz schrieb:
> Vielleicht müsste ja mal irgendwo ADC_Init() aufgerufen werden?
>
> Und das hier geht so nicht:
>
1
>   ADCSRA |= (1<<ADSC) | (1<<ADFR);                // eine ADC-Wandlung
2
>   while (ADCSRA & (1<<ADSC) )
3
>   {                          // auf Abschluss der Konvertierung warten
4
>   }
5
>
> Wenn Du ADFR setzt, dann wird automatisch immer wieder eine neue
> Wandlung gestartet.
> ADSC wird in dem Fall nie zurückgesetzt.
> Du könntest aber hier auf ADIF=1 warten, musst es aber von Hand
> zurücksetzten. ACHTUNG! Zurückgesetzt wird ADIF, indem man eine *1*
> hineinschreibt!

Er könnte aber auch ganz einfach auf die Beendingung der Messung pfeifen 
und überhaupt nicht warten. In der Zeit, in der die obligatorische 
Copyright-Meldung zur Belustigung aller ausgegeben wird, macht der ADC 
eigenständig ein paar Hundert Messungen, so dass es völlig wurscht ist, 
ob der erste Wert nicht ganz so genau ist, er wird sowieso nicht 
verwendet.


Allerdings erhebt sich die Frage: Wozu eigentlich der Free-Running?

: Bearbeitet durch User
von Rob E. (newgenera2589)


Lesenswert?

hi vielen dank schonmal für eure hilfe :)


Rob El schrieb:
> // Frequenzvorteiler auf 50MHz Teiler
> durch8 !!!!!!!!!!ungefähr 120mhz!!!!!!!!!

dieser Kommentar kann mit der Realität irgendwie garnix zu tun haben...

chris, ich habe den frequenzteilre auf 50mhz gehabt und mir wurde 120mhz 
empfohlen.... deswegen der kommentar

danke detlef das war mir nicht klar...

karl ich hatte zuerst die einzelmessung aber es hatte nicht 
funkioniert... dementsprechend habe ich gedacht versuch es doch einfach 
mal nur zum test im free-running modus...

von Karl H. (kbuchegg)


Lesenswert?

Rob El schrieb:
> hi vielen dank schonmal für eure hilfe :)
>
>
> Rob El schrieb:
>> // Frequenzvorteiler auf 50MHz Teiler
>> durch8 !!!!!!!!!!ungefähr 120mhz!!!!!!!!!
>
> dieser Kommentar kann mit der Realität irgendwie garnix zu tun haben...
>
> chris, ich habe den frequenzteilre auf 50mhz gehabt und mir wurde 120mhz
> empfohlen.... deswegen der kommentar

Aber auch du musst zugeben, dass 50 durch 8 nicht 120 ergibt.

Der Kommentar ist im besten Fall einfach nur missverständlich.

Und da ist noch gar nicht drinnen, dass der Vorsatz 'm' milli (also 1 
Tausendstel) bedeutet, der Vorsatz 'M' aber Mega (also 1 Million).

> karl ich hatte zuerst die einzelmessung aber es hatte nicht
> funkioniert...

dann hättest du dem nachgehen sollen.
Die Routinen sehen in etwa so aus wie die aus dem Tutorial. Und die 
funktionieren. D.h. du musst bei deinen 'Anpassungen' irgendetwas 
zerstört haben.

> dementsprechend habe ich gedacht versuch es doch einfach
> mal nur zum test im free-running modus...

Free Running macht eigentlich nur dann wirklich Sinn, wenn man sich das 
Ergebnis mit einem Interrupt abholt und gleich wegspeichert.
Free Running macht hingegen Probleme, wenn man mal mehr als nur einen 
ADC Kanal benötigt. In deiner Anwendung gibt es keinen wirklichen Grund, 
warum man Free Running benutzen sollte. Wichtiger wäre es, wenn dein 
generelles Setup für gezielte ADC Einzelmessungen sauber funktioniert. 
Denn das brauchst du viel häufiger als einen Free Running Modus zur 
schnellstmöglichen Massenwandlung von Werten.

Zumal auch der mutwillige Verzicht auf 10 Bit und statt dessen 8 Bit zu 
benutzen in einem Messgerät eher etwas seltsam anmutet. Das letzte Bit 
in einem ADC wird zwar ein wenig klappern, aber auch das kann man durch 
Mittelung wieder in den Griff kriegen. Ob du in einem Schleifendurchlauf 
500ms wartest, oder ob du 32 mal misst und dann mit dem Durchschnitt der 
Messwerte das 'rauschen' des Eingangs ausgleichst, ist für den µC 
gehupft wie gesprungen.

: Bearbeitet durch User
von Uwe (Gast)


Lesenswert?

> // Frequenzvorteiler auf 50MHz Teiler
> durch8 !!!!!!!!!!ungefähr 120mhz!!!!!!!!!
AArgh!
Schon mal das Datenblatt gelesen ... nein ... sieht man!

von Эраст Петрович Фандорин (Gast)


Lesenswert?

Uwe nölte:AArgh!
>Schon mal das Datenblatt gelesen ... nein ... sieht man!

Leg Dich wieder hin. Das Alles war gestern Abend um 22:30 Uhr schon 
bekannt.

von Uwe (Gast)


Lesenswert?

Ja und heute um 16:49 kam:
> chris, ich habe den frequenzteilre auf 50mhz gehabt und mir wurde 120mhz
> empfohlen.... deswegen der kommentar
wiederhinleg

von Uwe (Gast)


Lesenswert?

Ich empfehle ihm deshalb 870MHz ...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.