mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Atmega8 Uart & ADC


Autor: Max K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

ich versuche gerade über den den PC0 Per internen ADC die spannung 
einzulesen die an diesem liegt und das ganze über Uart an den PC zu 
senden:


Mein Code sieht wie folgt aus
#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 4000000
#include <util/delay.h>
#define BAUD 9600
#define UBRR_VAL F_CPU/16/BAUD-1


volatile uint16_t result;
volatile uint16_t wert;
uint8_t i;




void delay_ms(int delay) {
        int i;
        for (i=0;i<=delay;i++) {
                _delay_ms(1);
        }
}

void init_uart(unsigned int ubrr) {
        UBRRH = (unsigned char)(ubrr>>8);
        UBRRL = (unsigned char)(ubrr);
        UCSRB |= (1<<RXEN);
        UCSRB |= (1<<TXEN);
        UCSRB |= (1<<RXCIE);
        UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
}

void send_char(unsigned char data) {
        while (!(UCSRA & (1<<UDRE)));
        UDR = data;
}

void send_string(char *data) {
        while (*data) {
                send_char(*data);
                data++;
        }
}

volatile uint16_t adc(uint8_t mux)
{
  
  ADMUX = mux;
  ADMUX |= (0<<REFS1) | (1<<REFS0);     // AVcc nutzen
    ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0);   // Frequenzvorteiler setzen auf 8 und ADC aktivieren
 
    /* 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 
    while ( ADCSRA & (1<<ADSC) );       // auf Abschluss der Konvertierung warten 
    result = ADCW;        // ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten Wandlung nicht übernommen.
 
    /* Eigentliche Messung - Mittelwert aus 4 aufeinanderfolgenden Wandlungen */
    result = 0; 
     for( i=0; i<4; i++ )
    {
    ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
      while ( ADCSRA & (1<<ADSC) );     // auf Abschluss der Konvertierung warten
      result += ADCW;            // Wandlungsergebnisse aufaddieren
    }
    ADCSRA &= ~(1<<ADEN);               // ADC deaktivieren (2)
 
    result /= 4;                       // Summe durch vier teilen = arithm. Mittelwert
 
}



int main(void) {
  init_uart(UBRR_VAL);


  wert = adc(0);  

  send_string("Wert: ");
  send_string(wert);


}


Das Problem ist nun das ich im Terminal keinen Zahlenwert angzeigt 
bekomme sondern "Wert: " und daruaf folgen dann irgendwelche kryptische 
zeichen. An der Baudrate kann es ja schonmal nicht liegen.

Hat jemand eine Ahnung woran es liegen könnte?

Vielen Dank,
Max

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Oliver Ju. (skriptkiddy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du musst den Wert noch in einen "String" umwandeln.

utoa müsste dir helfen
send_string(utoa(wert));


Gruß Skriptkiddy

Autor: Max K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke habe den Code jetzt etwas angepasst aber leider bekomm ich immer 
Werte wie
333332
 raus das kann doch nicht ganz stimmen oder??

Hier nocheinmal der neue Code.
#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 4000000
#include <util/delay.h>
#define BAUD 9600
#define UBRR_VAL F_CPU/16/BAUD-1

volatile uint16_t result;
volatile uint16_t wert;
uint8_t i;



void delay_ms(int delay) {
        int i;
        for (i=0;i<=delay;i++) {
                _delay_ms(1);
        }
}

void init_uart(unsigned int ubrr) {
        UBRRH = (unsigned char)(ubrr>>8);
        UBRRL = (unsigned char)(ubrr);
        UCSRB |= (1<<RXEN);
        UCSRB |= (1<<TXEN);
        UCSRB |= (1<<RXCIE);
        UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
}

void send_char(unsigned char data) {
        while (!(UCSRA & (1<<UDRE)));
        UDR = data;
}

void send_string(char *data) {
        while (*data) {
                send_char(*data);
                data++;
        }
}

volatile uint16_t adc(uint8_t mux)
{
  
  ADMUX = mux;
  ADMUX |= (1<<REFS0);         // AVcc nutzen
    ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);   // Frequenzvorteiler setzen auf 64 und ADC aktivieren
 
    /* 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 
    while ( ADCSRA & (1<<ADSC) );             // auf Abschluss der Konvertierung warten 
    result = ADCW;  // ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten Wandlung nicht übernommen.
 
    /* Eigentliche Messung - Mittelwert aus 4 aufeinanderfolgenden Wandlungen */
    result = 0; 
     for( i=0; i<4; i++ )
    {
    ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
      while ( ADCSRA & (1<<ADSC) );     // auf Abschluss der Konvertierung warten
      result += ADCW;            // Wandlungsergebnisse aufaddieren
    }
    ADCSRA &= ~(1<<ADEN);               // ADC deaktivieren
 
    result /= 4;                       // Summe durch vier teilen = arithm. Mittelwert
 
  return result;
}



int main(void) {
  init_uart(UBRR_VAL);

  wert = adc(0);  

  send_string("wert: ");
  send_string(utoa(wert));



}

Autor: Huch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ganz sicher das, dass
send_string("wert: ");
ohne Fehler und Warnings compiliert? So à la: "... redefinition of 
utoa..."?

Eigentlich:

char utoa (unsigned int __val, char __s, int __radix)

Welchen Compiler verwendest Du?. Welche lib?

Autor: Huch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, falsche Zeile:
send_string(utoa(wert));

ist die fragliche Zeile.

Autor: Max K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich bekomme folgende Warnings angezeigt.
../main.c:83: warning: implicit declaration of function 'utoa'
../main.c:83: warning: passing argument 1 of 'send_string' makes pointer from integer without a cast

Autor: Huch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ich bekomme folgende Warnings angezeigt.

OK. Sehe gerade das Du stdlib nicht uncludet hattest. Deswegen wohl kein 
redefinition. Aber die Warnung hätte Dir eine Warnung sein sollen. Eine 
"implizite" Deklaration heisst, es gibt keine explizite, was bei library 
Funktionen immer der Fall sein sollte.

Also es fehlt:
#include <stdlib.h>
...
char buffer[10];            // oder ein anderer passender Wert
...
send_string(utoa(wert, buffer, 10));
...

Lies Dir mal die Beschreibung der avr-libc durch.

Autor: Lukas K. (carrotindustries)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Max K. schrieb:
> Ich bekomme folgende Warnings angezeigt.
>
>
../main.c:83: warning: implicit declaration of function 'utoa'
> ../main.c:83: warning: passing argument 1 of 'send_string' makes pointer
> from integer without a cast
> 
http://www.mikrocontroller.net/articles/FAQ#Wie_ka...
insb. das itoa Beispiel. utoa gibt keinen Pointer/String zurück, sondern 
erwartet einen Puffer, in welchem der String gespeichert wird.

Autor: Huch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>utoa gibt keinen Pointer/String zurück
Das ist so nicht richtig. Es gibt einen Zeiger auf den übergebenen 
Buffer zurück.
Aber Du meintest wohl auch eher die Tatsache, dass utoa selbst keinen 
Buffer alloziiert.

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.