www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik eingelesenen Analogwert über UART ausgeben


Autor: Thomas K. (teakay)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich möchte einen eingelesenen Analogwert über die serielle Schnittstelle 
wieder ausgeben. Allerdings bekomme ich beim Compilieren meines 
Programmes mit AVR-Studio immer wieder Fehlermeldungen. Diese werden von 
dem Befehl "puts ( string );" ausgelöst. Hier wäre noch mein 
Programmcode:
#include <avr/io.h>
#include <stdint.h>

#ifndef F_CPU
/* In neueren Version der WinAVR/Mfile Makefile-Vorlage kann
   F_CPU im Makefile definiert werden, eine nochmalige Definition
   hier wuerde zu einer Compilerwarnung fuehren. Daher "Schutz" durch
   #ifndef/#endif 
 
   Dieser "Schutz" kann zu Debugsessions führen, wenn AVRStudio 
   verwendet wird und dort eine andere, nicht zur Hardware passende 
   Taktrate eingestellt ist: Dann wird die folgende Definition 
   nicht verwendet, sondern stattdessen der Defaultwert (8 MHz?) 
   von AVRStudio - daher Ausgabe einer Warnung falls F_CPU
   noch nicht definiert: */
#warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 4000000"
#define F_CPU 4000000L    // Systemtakt in Hz, das L am Ende ist wichtig, NICHT UL verwenden! 
#endif
 
#define BAUD 9600L          // Baudrate, das L am Ende ist wichtig, NICHT UL verwenden!
 
// Berechnungen
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000) // Fehler in Promille 
 
#if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
#endif

uint16_t ReadChannel(uint8_t mux)
{
  uint8_t i;
  uint16_t result;

ADMUX = mux;                      // Kanal waehlen
  ADMUX |= (1<<REFS1) | (1<<REFS0); // interne Referenzspannung nutzen
 
  ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0);    // Frequenzvorteiler 
                               // setzen auf 8 (1) und ADC aktivieren (1)
 
  /* 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
 
  return result;
}
 

 
/* Beispielaufrufe: */
 
void foo(void)
{
  uint16_t adcval;
  char string[7];
  adcval = ReadChannel(0); /* MUX-Bits auf 0b0000 -> Channel 0 */
  itoa(adcval,string,10); 
//  adcval = ReadChannel(1); /* MUX-Bits auf 0b0010 -> Channel 2 */
//  itoa(adcval,string,10);

}

void putc(char c)
{
  while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich
*/
  {
  }

  UDR = c;                    /* schreibt das Zeichen x auf die Schnittstelle
Schnittstelle */
}

void puts (char *s)
{
    while (*s)
    {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */
        putc(*s);
        s++;
    }
}

int main(void)
{

 
  UCSRB |= (1<<TXEN)|(1<<RXEN);      // UART TX einschalten
  UCSRC |= (1<<URSEL)|(3<<UCSZ0);    // Asynchron 8N1

  UBRRH = UBRR_VAL >> 8;
  UBRRL = UBRR_VAL & 0xFF;

 
    puts ( string );
 
    
  return 0;

}

Wäre froh, wenn mir jemand helfen könnte.

Gruß
Thomas

Autor: Unbekannter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, von ist Dein "string" in main() definiert?

Du hast weder eine globale noch lokale Veriable mit dem Namen 
"string"...

Autor: Thomas K. (teakay)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Unbekannter wrote:
> Ja, von ist Dein "string" in main() definiert?
>
> Du hast weder eine globale noch lokale Veriable mit dem Namen
> "string"...
Warum ist diese nicht definiert. Was mache ich dann über diese 
Anweisung???
void foo(void)
{
  uint16_t adcval;
  char string[7];
  adcval = ReadChannel(0); /* MUX-Bits auf 0b0000 -> Channel 0 */
  itoa(adcval,string,10); 
//  adcval = ReadChannel(1); /* MUX-Bits auf 0b0010 -> Channel 2 */
//  itoa(adcval,string,10);

}
Definiere ich den String da nicht??? Oder muss ich ihn nochmals in 
main() definieren???

Gruß
Thomas

Autor: Severino R. (severino)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thomas Kratz wrote:

> Definiere ich den String da nicht??? Oder muss ich ihn nochmals in
> main() definieren???

Main kennt den string nicht, den Du in foo() lokal definierst. Schlimmer 
noch: sobald foo() beendet wird, ist string verloren.
Zudem: foo() wird nirgends aufgerufen!

Autor: Thomas K. (teakay)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Severino R. wrote:
>
> Main kennt den string nicht, den Du in foo() lokal definierst. Schlimmer
> noch: sobald foo() beendet wird, ist string verloren.
> Zudem: foo() wird nirgends aufgerufen!
Wenn ich meinen Code nun wie folgt in main() ändere funktioniert es 
trotzdem nicht warum?? Ist mein Code noch falsch???
int main(void)
{
  foo();  
  char string;
  UCSRB |= (1<<TXEN)|(1<<RXEN);      // UART TX einschalten
  UCSRC |= (1<<URSEL)|(3<<UCSZ0);    // Asynchron 8N1

  UBRRH = UBRR_VAL >> 8;
  UBRRL = UBRR_VAL & 0xFF;
  
  
    puts ( string );
 
    
  return 0;

}

Autor: Walter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
lies doch erst Mal ein C Buch ...
oder wenigstens ein Tutorial

Autor: Thomas K. (teakay)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die Hilfe werde ich tun!!!

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

Bewertung
0 lesenswert
nicht lesenswert
Thomas Kratz wrote:
> Severino R. wrote:
> Wenn ich meinen Code nun wie folgt in main() ändere funktioniert es
> trotzdem nicht warum?? Ist mein Code noch falsch???

Weil ein einzelnder character, so wie in

   char string;

nun mal kein string ist, sondern ein einzelner Character!

Für eine kleine Einführung, siehe hier
http://www.mikrocontroller.net/articles/FAQ#Wie_fu...

Aber das Studium eines ausführlichen Buches ist durch nichts
zu ersetzen.

Autor: Walter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ein weiterer Fehler ist dass in string erst etwas reingeschrieben werden 
muss,
und mach dich Mal mit der Sichtbarkeit von Variablen kundig

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.