Forum: Mikrocontroller und Digitale Elektronik UART + AT89C51 = sinnlose Zeichenketten


von Bernhard (Gast)


Lesenswert?

Hi,

ich hab hier einen AT89C51RB2,den ich zu Testzwecken so programmieren 
möchte,dass dieser mir ein Zeichen an ein Terminalprogramm schickt.
Dazu hab ich folgendes C - Programm geschrieben:
1
 #include<C51RB2.h>
2
 #include<stdio.h>
3
4
 void uart_init(void)
5
 {
6
 // Baudrate = 19200
7
 SCON = 0x50;  // 8 Bit UART 
8
 TH1=0xFD;       
9
 PCON |=0x80;
10
 TMOD |=0x20;  // Timer 1 als Baudratengenerator
11
 TCON=0x40;    
12
 }
13
14
 void main()
15
 {
16
 uart_init();
17
 TI = 0; // Flag loeschen
18
 SBUF = 0x65; //Ausgabe eines Zeichens
19
 }


Ich bekomme aber statt eines Zeichens einen Haufen von Zeichen,die total 
unterschiedlich sind.

edit: Ich hab einen 11.059MHz Quarz.

Hat jemand eine Idee was ich falsch gemacht habe?

von kamil (Gast)


Lesenswert?

Was passiert denn wenn dein Programm am Ende der main-Funktion ankommt?
Mach mal am Ende von main eine Endlosschleife oder sowas...

von Bernhard (Gast)


Lesenswert?

Hi kamil,

vielen Dank - jetzt funktioniert es!

Er sendet das richtige Zeichen.

Was ich aber nicht kapiere ist: Warum hat der ohne dieser Endlosschleife 
einen Schwachsinn gemacht?

Bernhard

von Kamil P. (kamil)


Lesenswert?

Naja, im RAM befindet sich zufälliger Code und da wird der eine oder 
andere Befehl dabei, der irgendwas über UART sendet. Die Endlosschleife 
verhindert, dass das dieser Zufallscode ausgeführt wird - das Programm 
bleibt in der Endlosschleife hängen.

von Bernhard (Gast)


Lesenswert?

Alles klar,ist wenn man ein bisschen nachdenkt logisch.

Nochmals danke!

Bernhard

von Bernhard (Gast)


Lesenswert?

Hi,

ich will hierfür keinen neuen Thread aufmachen,doch ich habe ein 
weiteres Problem. Diesmal handelt es sich dabei um die Ausgabe eines 
Strings.
Mein C - Programm sieht folgendermaßen aus:
1
 #include<C51RB2.h>
2
 #include<stdio.h>
3
 #include<string.h>
4
 const char* string = "-[WELCOME]-";
5
 char x[2];
6
 int laenge;
7
8
 void uart_init(void)
9
 {
10
 // Baudrate = 19200
11
 SCON = 0x50;  // 8 Bit UART 
12
 REN = 1; //Recieve Interrupt Enable
13
 IEN0 =0x10; //enable Uart interrupt
14
 TH1=0xFD;       
15
 PCON |=0x80;
16
 TMOD |=0x20;  // use timer 1 as baudrate generator
17
 TCON=0x40;    
18
 ES=0;    // Enable Serial IRQ (if required)
19
 EA= 1;    // Enable general IRQs (if required)
20
 TI = 0;
21
 }
22
23
void main()
24
 {
25
 x[1] = '\0';
26
 uart_init(); //Initialisierung vom Uart
27
 
28
laenge = strlen(string); //Laenge des Strings
29
 for(i=0;i<=laenge;i++)
30
 {
31
   TI = 0;
32
   x[0] = string[i];
33
   SBUF = x;
34
   do
35
   {
36
   }while(TI = 0);
37
   TI = 0;
38
 }
39
40
  do
41
 {
42
 
43
 }while ( a = 1);
44
 
45
 }

Wenn ich das Programm auf den µC spiele und ausführe dann bekomme ich im 
Terminal folgendes Zeichen: â

Über Hilfe bin ich dankbar.

Bernhard

von MC (Gast)


Lesenswert?

Wenn ich das richtig sehe, möchtest du auf deinem Terminal "Welcome" 
stehen haben.
Dazu hast du einen String mit dem Text und ein Array mit zwei Stellen, 
wobei du nacheinander in die erste Stelle das jeweilige Zeichen des 
Wortes einlädst. In der zweiten Stelle hast du immer '\0'.
Dann gibst du über deine for-Schleife nur 'x' aus.

Das kann so nicht funktionieren, da 'x' keine einfache Variable sondern 
ein Array mit zwei Speicherstellen ist. Was du machen könntest, wäre:
1
sbuf=x[0];
Oder du lädst direkt das Zeichen in den Buffer:
1
sbuf=string[i];
Was noch ein Problem sein könnte (da bin ich mir nicht ganz sicher), ist 
die fehlende Anzahl an Speicherstellen bei deinem string-Array.
1
const char* string[11] = "-[WELCOME]-";

von Bernhard (Gast)


Lesenswert?

Genau,ich möchte den String mit dem Inhalt Welcome auf die serielle 
Schnittstelle ausgeben.

sbuf=string[i];

Das hab' ich vorher schon probiert,das hat jedoch auch nicht 
funktioniert.
Über Google bin ich dann über einen Beitrag in einem anderen Forum 
gestoßen,wo jemand ein ziemlich ähnliches Problem hatte.
http://www.tutorials.de/forum/c-c/306688-8051-lcd-displayansteuerung.html


Ich hab jetzt die Änderungen,die MC vorgeschlagen hat,übernommen.
Mein C - Programm sieht jetzt folgendermaßen aus:
1
#include<C51RB2.h>
2
 #include<stdio.h>
3
 #include<string.h>
4
 char string[11] = "-[WELCOME]-";
5
 char x[2];
6
 int laenge;
7
8
 void uart_init(void)
9
 {
10
 // Baudrate = 19200
11
 SCON = 0x50;  // 8 Bit UART 
12
 REN = 1; //Recieve Interrupt Enable
13
 IEN0 =0x10; //enable Uart interrupt
14
 TH1=0xFD;       
15
 PCON |=0x80;
16
 TMOD |=0x20;  // use timer 1 as baudrate generator
17
 TCON=0x40;    
18
 ES=0;    // Enable Serial IRQ (if required)
19
 EA= 1;    // Enable general IRQs (if required)
20
 TI = 0;
21
 }
22
23
void main()
24
 {
25
 x[1] = '\0';
26
 uart_init(); //Initialisierung vom Uart
27
 
28
laenge = strlen(string); //Laenge des Strings
29
 for(i=0;i<=laenge;i++)
30
 {
31
   TI = 0;
32
   SBUF = string[i];
33
   do
34
   {
35
   }while(TI = 0);
36
   TI = 0;
37
 }
38
39
  do
40
 {
41
 
42
 }while ( a = 1);
43
 
44
 }

Als Ausgabe kommt wieder ein einzelnes Zeichen,jedoch diesmal ein 
Smilie.

Ich hab keine Ahnung wo das Problem liegen könnte..

Bernhard

von R. W. (quakeman)


Lesenswert?

Also ich habe das Programm mal im Simulator laufen lassen und es 
funktioniert einwandfrei nach ein paar kleinen Anpassungen.

Mir ist aufgefallen, daß du die for Schleife bis "<=laenge" laufen 
lässt, was falsch ist. Richtig wäre bis "<laenge", da der Zähler ja bei 
0 anfängt und ansonsten ein Zeichen zu viel ausgelesen wird.

Ebenso macht "ea=1" keinen Sinn, da kein Interrupt verwendet werden 
soll.

Welchen Sinn deine Variable x[] haben soll ist mir auch noch unklar, da 
du dieser einen Wert zuweist, diese dann aber nie mehr benutzt.

Ebenso verwendest du die Variablen "a" und "i", welche du vorher nicht 
deklariert hast. Vielleicht geht das bei deinem Compiler, beim dem Keil 
C51 jedenfalls musste ich "a" und "i" vorher erst deklarieren.

Deine endlos while Schleife am Ende kannst du auch mit "while(1);" 
einfacher schreiben. Ebenso die TI Schleifen mit "while(TI==0);" :)

Der gravierendste Fehler, und eventuell die Ursache des Problems, könnte 
der falsche Operator in deiner while Schleife sein. Du prüfst auf "TI = 
0", wobei ein einfaches "=" eine Zuweisung und kein Vergleich ist. Du 
mußt dort auf "TI == 0" prüfen, damit es ein Vergleich ist.
Bedingt durch die Zuweisung wird nämlich sofort das nächste Zeichen in 
SBUF geschrieben, ohne auf das fertige Senden des vorherigen Zeichens zu 
warten.

Ciao,
     Rainer

von Bernhard (Gast)


Lesenswert?

Hi Rainer,

besten Dank für die Mühe die du dir gemacht hast.
Der Fehler lag,wie du richtig vermutet hast, in der fehlerhaften while 
Schleife.
Ein ziemlich peinlicher Fehler meinerseits...

Den Programmteil habe ich aus einem etwas größeren Testprogramm 
herauskopiert,deshalb fehlten einige Definitionen(a & i).

Den Fehler in der for - Schleife hab ich ebenfalls ausgebessert.

Danke!

Bernhard

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.