mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATMega32 - ADC&UART


Autor: Beginner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nabend!

Ich bin ein interessierter Anfänger was die Microcontroller angeht.
Für heute hatte ich mir vorgenommen mit dem integrierten AD-Wandler des 
ATMega32 zu arbeiten und die Daten dann über UART zum PC zu senden.

Orientiert habe ich mich dabei an den Artikeln hier aus dem Forum. 
Kurzum ich habe den Schleifer eines Potis an den ADC0 Eingang des 
Controllers gelegt und die anderen beiden Anschlüsse an VCC sowie GND.
AREF beträgt ebenfalls 5V.

Nun habe ich das Problem das ich mit dem Terminalprogramm immer nur "FF" 
empfange, egal wie ich das Poti verändere.
Könnt ihr mir sagen was ich falsch mache?


Anbei der Code:
#include <avr/io.h>
#include <inttypes.h>
#include <stdio.h>

#define BAUD        19200UL
#define UBRR_BAUD   ((F_CPU/(16UL*BAUD))-1)




void uart_init(void)       // USART initialisieren
{
    UBRRH = (uint8_t) (UBRR_BAUD>>8);
    UBRRL = (uint8_t) (UBRR_BAUD & 0x0ff);
    UCSRB = (1<<RXEN)|(1<<TXEN);
    UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
}


int main(void)
{
  int buffer;
  int i;


  ADCSRA = (1<<ADEN)|(1<<ADSC);

  while ( ADCSRA & (1<<ADSC) )
    {
    ;
    }

  buffer=ADCW;

//------------------------------------------------------------------

  uart_init();            // UART initialisieren

  while ( !( UCSRA & (1<<UDRE)) )
    {
    ;
    }

        UDR = buffer;
}

Ich hoffe ich habe Euch keine essentiellen Informationen unterschlagen 
;)
Gruß

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was hältst Du davon, die Wandlung und das Senden mal in eine 
Endlosschleife zu packen? So wie es da steht, wird nur ein einziges Mal 
gewandelt und gesendet.

Außerdem: Wie groß ist Dein F_CPU, wo ist es angegeben und womit 
erzeugst Du den Takt?

Und noch was: AVCC ist intern als Referenz auswählbar (in ADMUX mit 
REFS0/1) und sollte nicht extern an den AREF-Pin angeschlossen werden! 
Der AREF-Pin sollte nur dann mit einer externen Spannung verbunden 
werden, wenn eine Referenzspannung benötigt wird, die der µC intern 
nicht zur Verfügung stellen kann.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach ja, die erste Wandlung nach dem Aktivieren des ADC ergibt i.d.R. 
kein sinnvolles Ergebnis und sollte verworfen werden.

Autor: Beginner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das nur einmal gewandelt und gesendet wird sollte eigentlich so sein, 
hab jetzt aber eine Endlosschleife drumherum gemacht.
F_CPU ist 16000000
Erzeugt wird der Takt mit einem 16MHz Quarz. Fusebits sind korrekt.

Mit der Endlossschleife empfange ich jetzt:
CE 67 99 CE 67 99 EE E3 67 99

was sich dann immer wiederholt. Irgendwie bin ich jetzt doch etwas 
verwirrt...

Autor: Beginner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ahh ok Danke. Das mit dem AREF Pin werde ich dann nochmal ändern und auf 
den internen zurückgreifen.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Beginner wrote:
> Ahh ok Danke. Das mit dem AREF Pin werde ich dann nochmal ändern und auf
> den internen zurückgreifen.
Und dann auch gleich an AREF einen kleinen Kondensator (100 nF) gegen 
GND.

Dürfte aber mit Deinem Problem nichts zu tun haben...

Autor: Beginner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe jetzt

ADMUX = (1<<REFS0);

in den Code eingefügt und auch den Kondensator zwischengeschaltet.
Mit dem terminalprogramm empfange ich jetzt das folgende:
CE 67 99 CE 67 99 CE 67 CE 67 99 CE 67 99 CE 77 CE 67 99

usw.
Drehen am Poti hat nachwievor keinen Einfluß auf die Werte

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dein ADC-Buffer ist 16 Bit breit und das UDR nur 8...

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nun ja, die Werte an sich kann ich mir momentan auch nicht erklären. Was 
mir aber noch aufgefallen ist: In UDR passen ja nunmal nur 8 Bit rein, 
das Wandlungsergebnis hat aber 10 Bit. D.h., Du schneidest bei der 
Zuweisung "UDR = buffer;" die beiden höchsten Bits ab und überträgst nur 
die letzten 8. Dass da keine sinnvollen Werte am PC ankommen, sollte 
klar sein...

Autor: Beginner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja da habt ihr natürlich recht, aber wenn ich das Poti von min. nach 
max. und umgekehrt drehe, dann müssten sich die Werte doch auf jedenfall 
ändern.
Habs nochmal nachgemessen die Spannung am ADC0 Pin ändert sich durch 
verändern der Schleiferstellung...

Könnte man das Problem mit dem Cast Operator lösen?
Also im Prinzip: UDR = (char) buffer;

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Beginner wrote:
> Könnte man das Problem mit dem Cast Operator lösen?
> Also im Prinzip: UDR = (char) buffer;
Nö. Auf die Weise schneidest Du genauso das High-Byte ab wie in dem 
anderen Fall, nur dass Du jetzt noch dem Compiler mitteilst, dass das 
auch beabsichtigt ist... Was Du machen könntest ist, das Bit ADLAR im 
ADMUX setzen und nur ADCH auslesen (anstelle von ADC(W)). Dann bekommst 
Du die 8 höherwertigen Bits und die beiden letzten werden weggeworfen. 
Oder Du schiebst buffer bei der Zuweisung um zwei Stellen nach 
rechts...

Autor: Beginner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also wenn ich das richtig verstanden und umgesetzt habe sieht der ADC 
Teil jetzt folgendermaßen aus:

ADCSRA = (1<<ADEN)|(1<<ADSC);
  ADMUX = (1<<REFS0);
  ADMUX = (1<<ADLAR);


  while ( ADCSRA & (1<<ADSC) )
    {
    ;                     // auf Abschluss der Konvertierung warten
    }


  buffer=ADCH;        // ADC Wert in Buffer schreiben

Ja jetzt passiert folgendes:
Ist die Spannung am ADC0 Pin größer als ~4,2V so sendet er "FF" ist die 
Spannung kleiner dann garnichts.
Ich bin etwas ratlos ....

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>  ADMUX = (1<<REFS0);
>  ADMUX = (1<<ADLAR);

Jetzt ist nur noch das ADLAR-Bit gesetzt.

So muß das heissen:

  ADMUX = (1<<REFS0) | (1<<ADLAR);

Autor: Beginner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oh ja klar da hab ich gepennt ... im ADCSRA Register hatte ich es ja 
auch schon so gemacht.
Am Ergebnis hat sich leider nichts geändert. Bzw. durch das Verändern 
der Schleiferstellung ändern sich die empfangenen Werte im 
Terminalprogramm nicht

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Poste mal dein aktuelles Programm (im Angang!).

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

Bewertung
0 lesenswert
nicht lesenswert
Ok ist als Anlage beigefügt

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Initialisierungen sollten beide vor die for(;;)-Schleife - 
schließlich braucht man die Schnittstelle und den ADC nur ein Mal 
initialisieren.
Vermutlich hast du deswegen auch nur unsinnige Werte.

Autor: Beginner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mhh ja das war schonmal ein guter Schritt in die richtige Richtung!
Irgendwo ist aber noch eine Kleinigkeit würde ich sagen.
Das Terminalprogramm zeigt mir jetzt nur noch einen hexadezimalen Wert 
an, welcher sich allerdings auch nicht ändert, wenn man die 
Schleiferstellung verändert. Die Endlosschleife ist nachwievor im 
Programm.
Ich hab mir grad mal die Spannung am ADC0 Pin gemessen und die 
dazugehörigen HEX Werte aus dem terminalprogramm notiert:
5V  ->8C
3V  ->42
1,1V->C6

Das kann doch irgendwie nicht stimmen ...

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.