Forum: Mikrocontroller und Digitale Elektronik uController-USART-String


von daselmo (Gast)


Lesenswert?

Hallo,

wir haben bei unserem kleinen Tester folgendes Problem:
Der Funktion WriteUARTStringPC ()kann kein String übergeben werden.
Bitte um Hilfe.

Es wird auf einem ATMEGA128 mit einem 7372000 Quarz programmiert.
Quellcode
1
 
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
//#include <util/delay.h>
5
#include <inttypes.h>
6
#include <string.h>
7
8
#define FOSC 7372000      //clock speed
9
#define BAUD 9600
10
#define MYUBRR FOSC/16/BAUD-1
11
12
//typeset unsigned char uchar;
13
  //set baud rate 
14
15
16
17
void USART0Init(unsigned int ubrr0)
18
{  //set Bausdrate
19
  UBRR0H = (ubrr0>>8);
20
  UBRR0L = (ubrr0);
21
22
  //transmit enable / 1 stopbit, 8 databits
23
  UCSR0B = 0x18;   //?!?!?!?!?!?!?!?!?
24
  UCSR0C = 0x06;
25
}
26
27
28
char ReadPcUART()
29
{
30
  while (!(UCSR0A & (1<<RXC0)))   // warten bis Zeichen verfuegbar
31
        ;
32
  return UDR0;                  
33
}
34
35
void ReadStringPCUART( char* Buffer, uint8_t MaxLen )
36
{
37
  uint8_t NextChar;
38
  uint8_t StringLen = 0;
39
 
40
  NextChar = ReadPcUART();         // Warte auf und empfange das n‰chste Zeichen
41
 
42
                                  // Sammle solange Zeichen, bis:
43
                                  // * entweder das String Ende Zeichen kam
44
                                  // * oder das aufnehmende Array voll ist
45
  while( NextChar != '\n' && StringLen < MaxLen + 1 ) {
46
    *Buffer++ = NextChar;
47
    StringLen++;
48
    NextChar = ReadPcUART();
49
  }
50
 
51
                                  // Noch ein '\0' anh‰ngen um einen Standard
52
                                  // C-String daraus zu machen
53
  //*Buffer = '\0';
54
}
55
56
57
void WriteCharPC (unsigned char cData)
58
{
59
  while (!(UCSR0A & (1<<UDRE0)))  /* warten bis Senden moeglich */
60
    {
61
    }                             
62
 
63
    UDR0 = cData;                      /* sende Zeichen */
64
    return 0;
65
}
66
67
void WriteUARTStringPC (char* sText)
68
{
69
  unsigned char cByte;
70
   unsigned char cOffset;
71
72
   for (cOffset=0;sText[cOffset]!='\0';cOffset++)
73
    {
74
       // byte aus flash lesen
75
       cByte=sText[cOffset];  
76
77
       // fertig
78
       if (cByte=='\0') break;
79
80
       // und zum PC schicken
81
       WriteCharPC (cByte);
82
    }
83
}
84
85
int main ()
86
{
87
  
88
  char Line[20];      // String mit maximal 20 zeichen
89
90
  Line[0] = 101;
91
  Line[1] = 54;
92
  Line[2] = 72;  
93
94
  USART0Init(MYUBRR);
95
  
96
  for(;;)
97
  {  
98
    //ReadStringPCUART(Line);
99
    //WriteUARTStringPC('1');
100
        /*
101
        WriteCharPC ('A');
102
    WriteCharPC ('0');
103
    WriteCharPC ('0');
104
    WriteCharPC ('0');
105
    WriteCharPC ('1');
106
    WriteCharPC ('\n');
107
         */
108
    WriteUARTStringPC(Line[0]);          //<-- 
109
    //WriteUARTStringPC("\n\r");
110
    //uart_gets( Line,40);
111
    //data=ReadPcUSART();
112
    //WritePCUSART(data);
113
  }
114
  
115
  return 0;  
116
}

Bitte um Hilfe.

von Noname (Gast)


Lesenswert?

>Der Funktion WriteUARTStringPC ()kann kein String übergeben werden.
Was heisst das genau? Fängt der uC an zu quitschen oder was? :-)

von Noname (Gast)


Lesenswert?

Das hier:
1
    WriteUARTStringPC(Line[0]);          //<--

wird jedenfalls eine Fehlermeldung geben.
Dir ist doch klar, das Du das ein Zeichen (char) übergibst anstelle des 
von der Funktion geforderten char *, oder vielleicht doch nicht?

von Stefan E. (sternst)


Lesenswert?

daselmo schrieb:
> Der Funktion WriteUARTStringPC ()kann kein String übergeben werden.

Kann schon, du tust es nur nicht.

1
    WriteUARTStringPC(Line[0]);          //<--
Line[0] ist kein String, sondern nur das erste Zeichen in einem Array. 
Aber auch wenn du das korrigierst, wirst du vielleicht unerwartete 
Ergebnisse bekommen, denn in dem Array steht gar kein String, sondern 
eine unterminierte Abfolge von Zeichen.

von Typ (Gast)


Lesenswert?

1
char Line[20] ="WTF?";
2
WriteUARTStringPC(Line); //entspricht -> WriteUARTStringPC(&Line[0]);

von daselmo (Gast)


Lesenswert?

Gut nun bessere ich folgende Zeilen aus:
1
char Line[20] ="WTF?";
2
WriteUARTStringPC(Line); //entspricht -> WriteUARTStringPC(&Line[0]);
und debugge es mit dem JTAG mkII und AVR Studio.
Jetzt gibt der uController eine unendliche Folge von 'hochgestellten 3' 
aus.

Es funktioniert aber wenn man es direkt hineinschreibt.
1
 WriteUARTStringPC("WTF?");

Hat jemand eine Idee was es sein könnte?

von Peter II (Gast)


Lesenswert?

Ich würde es dem µC und compiler nicht so schwer machen.

So sollte das ganze ein wenig optimierter sein:

[c]
void WriteUARTStringPC (char* sText)
{
   // oder die langform  while( *sText != 0 ) {
   while( *sText ) {
       WriteCharPC ( *sText );
       sText++;
   }
}
[\c]

du hattest 2 hilfsvariablen und jedes mal in der schleife hast du den 
index zugriff verwendet.

von daselmo (Gast)


Lesenswert?

1
void WriteUARTStringPC (char* sText)
2
{
3
   // oder die langform  while( *sText != 0 ) {
4
   while( *sText ) {
5
       WriteCharPC ( *sText );
6
       sText++;
7
   }
8
}

Ist ja eine super Idee, haben wir auch hier im µC Forum des Öfteren 
gesehen und ausprobiert, behebt aber leider unser Problem nicht.

Das Problem ist die Übergabe des Strings an die Funktion. Wo liegt da 
unser Fehler?

von Karl H. (kbuchegg)


Lesenswert?

daselmo schrieb:
> Gut nun bessere ich folgende Zeilen aus:
>
char Line[20] ="WTF?";
> WriteUARTStringPC(Line); //entspricht -> WriteUARTStringPC(&Line[0]);
>
> und debugge es mit dem JTAG mkII und AVR Studio.
> Jetzt gibt der uController eine unendliche Folge von 'hochgestellten 3'
> aus.

und was war sonst noch so im Programm?
Gab es Code zwischen den beiden Programmzeilen, die Line manipuliert
haben? Immer wenn ich sowas in einem Programm sehe
1
 Line[0] = 101;
läuft es mir kalt den Rücken runter und ich traue dem Programmierer
nicht weiter, als ich einen Kernighan&Ritchie werfen kann. Und der 
fliegt nicht besonders gut.

von daselmo (Gast)


Lesenswert?

Aktueller Code, erfolgreich einen weiteren Weg gefunden der nicht 
funktioniert.

1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <inttypes.h>
4
#include <string.h>
5
6
#define FOSC 7372000      //clock speed
7
#define BAUD 9600
8
#define MYUBRR FOSC/16/BAUD-1
9
10
11
//typeset unsigned char uchar;
12
//set baud rate 
13
14
15
16
void USART0Init(unsigned int ubrr0)
17
{  //set baud
18
  UBRR0H = (ubrr0>>8);
19
  UBRR0L = (ubrr0);
20
21
  //transmit enable / 1 stopbit, 8 databits
22
  UCSR0B = 0x18;   
23
  UCSR0C = 0x06;
24
}
25
26
void WriteCharPC (unsigned char cData)
27
{
28
  while (!(UCSR0A & (1<<UDRE0)))  /* warten bis Senden moeglich */
29
  {
30
  }                             
31
 
32
  UDR0 = cData;                      /* sende Zeichen */
33
  return 0;
34
}
35
36
void WriteUARTStringPC (char* sText)
37
{
38
  while( *sText ) 
39
  {
40
     WriteCharPC ( *sText );
41
     sText++;
42
  }
43
}
44
45
int main ()
46
{
47
  char Line[20] = "WTF";      // String mit maximal 20 zeichen
48
49
  USART0Init(MYUBRR);
50
  
51
  for(;;)
52
  {  
53
54
    WriteUARTStringPC(Line);          //<-- 
55
56
  }
57
  
58
  return 0;  
59
}

Also wenn jemand weiter weiss bitte um Hilfe!

von Peter II (Gast)


Lesenswert?

kannst du denn einzele zeichen senden?

WriteCharPC('#');

stimmt wirklich der Takt vom µC? Bitte mit ein LED die im sekunden Takt 
blinkt prüfen!

Richtige Baudrate am PC angestellt? Stimmt der verkabelung?

von daselmo (Gast)


Lesenswert?

>kannst du denn einzele zeichen senden?

über die WriteCharPC() sind einzelne Zeichen möglich.

Es funktioniert auch, wenn wir z.b. "Hello World" in die 
WriteUSARTStringPC() schreiben, also:
1
 WriteUSARTStringPC("Hello World");

>stimmt wirklich der Takt vom µC? Bitte mit ein LED die im sekunden Takt
>blinkt prüfen!

Takt stimmt, hatten am Anfang das Problem mit den Fuses und dem externen 
Takt. Diesen Fehler haben wir aber schon behoben.

>Richtige Baudrate am PC angestellt? Stimmt der verkabelung?

Die Baudrate am Terminal stimmt auch und die Verkabelung wurde schon 
mehrmals kontrolliert.

von Karl H. (kbuchegg)


Lesenswert?

Welche Compilerversion?
Dein letzter Code sieht soweit in Ordnung aus. Müsste eigentlich 
funktionieren.

von daselmo (Gast)


Lesenswert?

>Welche Compilerversion?

Verwenden AVR Studio 4 Version 4.18 mit original ATMEL JTAG mkII.

von Peter II (Gast)


Lesenswert?

kommt denn beim compilieren keine Warnung oder ein Fehler?

> void WriteCharPC (unsigned char cData)
> ...
> return 0

sollte eigenlich nicht zulässig sein.

von daselmo (Gast)


Lesenswert?

>kommt denn beim compilieren keine Warnung oder ein Fehler?

>> void WriteCharPC (unsigned char cData)
>> ...
>> return 0

>sollte eigenlich nicht zulässig sein.

Warning schon. Wurde behoben. Problem bleibt.

von Peter II (Gast)


Lesenswert?

dann nutzt doch mal den debuger wenn du schon einen hast, werden denn 
die buchstaben einzeln in WriteCharPC übergeben?

von daselmo (Gast)


Lesenswert?

Wird das Line folgendermaßen deklariert:
1
 char Line[20] = "WTF";

steht im Line beim Debuggen nichts drinnen.

Also liegt das Problem schon bei der Deklaration?!

von Peter II (Gast)


Lesenswert?

daselmo schrieb:
> Also liegt das Problem schon bei der Deklaration?!

nein, kann durch den optimierer anderes gemacht werden. Gehe direkt in 
die funktion WriteUARTStringPC dort sollte dann der string schon zu 
sehen sein.

von daselmo (Gast)


Lesenswert?

Das Problem ist, dass das sText in der Watchliste "Location not valid" 
meldet.
Was tun?

von Peter II (Gast)


Lesenswert?

daselmo schrieb:
> Was tun?

optimierung mal ausschalten

von daselmo (Gast)


Lesenswert?

>optimierung mal ausschalten

wenn wir die Optimierung ausschalten, hängt sich das Programm nach der 
Init auf.
Langsam sind wir verzweifelt.

von Peter II (Gast)


Lesenswert?

daselmo schrieb:
> wenn wir die Optimierung ausschalten, hängt sich das Programm nach der
> Init auf.
> Langsam sind wir verzweifelt.

hat du auch den richtigen controller type ausgewählt?

von Karl H. (kbuchegg)


Lesenswert?

Hast du den richtigen Prozessor in den Optionen eingestellt?
Such mal deine Projekt-Optionen durch.

Wenn du nichts findest, würd ich auch mal Folgendes probieren:

Neues Projekt anfangen.
Wichtig: Sehr genau darauf auchten, was da eingestellt wird.

Den Code mittels Cut&Paste in das vom Wizard erzeugte Source File 
einsetzen.

Build machen.

von Karl H. (kbuchegg)


Lesenswert?

Mega128 bringt mich auf noch eine Idee:
Die M103 Fuse ist abgeschaltet?

Dieses Symptom
> wenn wir die Optimierung ausschalten, hängt sich das Programm
> nach der Init auf.
würde da ganz stark dafür sprechen, dass die M103 aktiv ist.

von daselmo (Gast)


Lesenswert?

>Mega128 bringt mich auf noch eine Idee:
>Die M103 Fuse ist abgeschaltet?

ES FUNKTIONIERT!!!!!!!

Code wie vom Post: Datum: 25.04.2012 08:43. M103 in den Fuses 
deaktiviert.

Vielen Dank!

Schulden dir ein Bier/Kaffee o.Ä ;)

von Stefan P. (form)


Lesenswert?

daselmo schrieb:
>
1
> #define FOSC 7372000      //clock speed
2
>

Nicht wirklich dramatisch, aber es wird sich vermutlich um einen 7,3728 
MHz Quarz handeln. Also lieber auch die "8" noch hinschreiben.

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.