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


von Thomas K. (teakay)


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:
1
#include <avr/io.h>
2
#include <stdint.h>
3
4
#ifndef F_CPU
5
/* In neueren Version der WinAVR/Mfile Makefile-Vorlage kann
6
   F_CPU im Makefile definiert werden, eine nochmalige Definition
7
   hier wuerde zu einer Compilerwarnung fuehren. Daher "Schutz" durch
8
   #ifndef/#endif 
9
 
10
   Dieser "Schutz" kann zu Debugsessions führen, wenn AVRStudio 
11
   verwendet wird und dort eine andere, nicht zur Hardware passende 
12
   Taktrate eingestellt ist: Dann wird die folgende Definition 
13
   nicht verwendet, sondern stattdessen der Defaultwert (8 MHz?) 
14
   von AVRStudio - daher Ausgabe einer Warnung falls F_CPU
15
   noch nicht definiert: */
16
#warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 4000000"
17
#define F_CPU 4000000L    // Systemtakt in Hz, das L am Ende ist wichtig, NICHT UL verwenden! 
18
#endif
19
 
20
#define BAUD 9600L          // Baudrate, das L am Ende ist wichtig, NICHT UL verwenden!
21
 
22
// Berechnungen
23
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
24
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
25
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000) // Fehler in Promille 
26
 
27
#if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))
28
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
29
#endif
30
31
uint16_t ReadChannel(uint8_t mux)
32
{
33
  uint8_t i;
34
  uint16_t result;
35
36
ADMUX = mux;                      // Kanal waehlen
37
  ADMUX |= (1<<REFS1) | (1<<REFS0); // interne Referenzspannung nutzen
38
 
39
  ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0);    // Frequenzvorteiler 
40
                               // setzen auf 8 (1) und ADC aktivieren (1)
41
 
42
  /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
43
     also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
44
  ADCSRA |= (1<<ADSC);              // eine ADC-Wandlung 
45
  while ( ADCSRA & (1<<ADSC) ) {
46
     ;     // auf Abschluss der Konvertierung warten 
47
  }
48
  result = ADCW;  // ADCW muss einmal gelesen werden,
49
                  // sonst wird Ergebnis der nächsten Wandlung
50
                  // nicht übernommen.
51
 
52
  /* Eigentliche Messung - Mittelwert aus 4 aufeinanderfolgenden Wandlungen */
53
  result = 0; 
54
  for( i=0; i<4; i++ )
55
  {
56
    ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
57
    while ( ADCSRA & (1<<ADSC) ) {
58
      ;   // auf Abschluss der Konvertierung warten
59
    }
60
    result += ADCW;        // Wandlungsergebnisse aufaddieren
61
  }
62
  ADCSRA &= ~(1<<ADEN);             // ADC deaktivieren (2)
63
 
64
  result /= 4;                     // Summe durch vier teilen = arithm. Mittelwert
65
 
66
  return result;
67
}
68
 
69
70
 
71
/* Beispielaufrufe: */
72
 
73
void foo(void)
74
{
75
  uint16_t adcval;
76
  char string[7];
77
  adcval = ReadChannel(0); /* MUX-Bits auf 0b0000 -> Channel 0 */
78
  itoa(adcval,string,10); 
79
//  adcval = ReadChannel(1); /* MUX-Bits auf 0b0010 -> Channel 2 */
80
//  itoa(adcval,string,10);
81
82
}
83
84
void putc(char c)
85
{
86
  while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich
87
*/
88
  {
89
  }
90
91
  UDR = c;                    /* schreibt das Zeichen x auf die Schnittstelle
92
Schnittstelle */
93
}
94
95
void puts (char *s)
96
{
97
    while (*s)
98
    {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */
99
        putc(*s);
100
        s++;
101
    }
102
}
103
104
int main(void)
105
{
106
107
 
108
  UCSRB |= (1<<TXEN)|(1<<RXEN);      // UART TX einschalten
109
  UCSRC |= (1<<URSEL)|(3<<UCSZ0);    // Asynchron 8N1
110
111
  UBRRH = UBRR_VAL >> 8;
112
  UBRRL = UBRR_VAL & 0xFF;
113
114
 
115
    puts ( string );
116
 
117
    
118
  return 0;
119
120
}

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

Gruß
Thomas

von Unbekannter (Gast)


Lesenswert?

Ja, von ist Dein "string" in main() definiert?

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

von Thomas K. (teakay)


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???
1
void foo(void)
2
{
3
  uint16_t adcval;
4
  char string[7];
5
  adcval = ReadChannel(0); /* MUX-Bits auf 0b0000 -> Channel 0 */
6
  itoa(adcval,string,10); 
7
//  adcval = ReadChannel(1); /* MUX-Bits auf 0b0010 -> Channel 2 */
8
//  itoa(adcval,string,10);
9
10
}
Definiere ich den String da nicht??? Oder muss ich ihn nochmals in 
main() definieren???

Gruß
Thomas

von Severino R. (severino)


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!

von Thomas K. (teakay)


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???
1
int main(void)
2
{
3
  foo();  
4
  char string;
5
  UCSRB |= (1<<TXEN)|(1<<RXEN);      // UART TX einschalten
6
  UCSRC |= (1<<URSEL)|(3<<UCSZ0);    // Asynchron 8N1
7
8
  UBRRH = UBRR_VAL >> 8;
9
  UBRRL = UBRR_VAL & 0xFF;
10
  
11
  
12
    puts ( string );
13
 
14
    
15
  return 0;
16
17
}

von Walter (Gast)


Lesenswert?

lies doch erst Mal ein C Buch ...
oder wenigstens ein Tutorial

von Thomas K. (teakay)


Lesenswert?

Danke für die Hilfe werde ich tun!!!

von Karl H. (kbuchegg)


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_funktioniert_String-Verarbeitung_in_C.3F

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

von Walter (Gast)


Lesenswert?

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

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.