mikrocontroller.net

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


Autor: Bernhard (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
 #include<C51RB2.h>
 #include<stdio.h>

 void uart_init(void)
 {
 // Baudrate = 19200
 SCON = 0x50;  // 8 Bit UART 
 TH1=0xFD;       
 PCON |=0x80;
 TMOD |=0x20;  // Timer 1 als Baudratengenerator
 TCON=0x40;    
 }

 void main()
 {
 uart_init();
 TI = 0; // Flag loeschen
 SBUF = 0x65; //Ausgabe eines Zeichens
 }


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?

Autor: kamil (Gast)
Datum:

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

Autor: Bernhard (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Kamil P. (kamil)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Bernhard (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alles klar,ist wenn man ein bisschen nachdenkt logisch.

Nochmals danke!

Bernhard

Autor: Bernhard (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
 #include<C51RB2.h>
 #include<stdio.h>
 #include<string.h>
 const char* string = "-[WELCOME]-";
 char x[2];
 int laenge;

 void uart_init(void)
 {
 // Baudrate = 19200
 SCON = 0x50;  // 8 Bit UART 
 REN = 1; //Recieve Interrupt Enable
 IEN0 =0x10; //enable Uart interrupt
 TH1=0xFD;       
 PCON |=0x80;
 TMOD |=0x20;  // use timer 1 as baudrate generator
 TCON=0x40;    
 ES=0;    // Enable Serial IRQ (if required)
 EA= 1;    // Enable general IRQs (if required)
 TI = 0;
 }

void main()
 {
 x[1] = '\0';
 uart_init(); //Initialisierung vom Uart
 
laenge = strlen(string); //Laenge des Strings
 for(i=0;i<=laenge;i++)
 {
   TI = 0;
   x[0] = string[i];
   SBUF = x;
   do
   {
   }while(TI = 0);
   TI = 0;
 }

  do
 {
 
 }while ( a = 1);
 
 }
 

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

Über Hilfe bin ich dankbar.

Bernhard

Autor: MC (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
sbuf=x[0];
Oder du lädst direkt das Zeichen in den Buffer:
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.
const char* string[11] = "-[WELCOME]-";

Autor: Bernhard (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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-...


Ich hab jetzt die Änderungen,die MC vorgeschlagen hat,übernommen.
Mein C - Programm sieht jetzt folgendermaßen aus:
#include<C51RB2.h>
 #include<stdio.h>
 #include<string.h>
 char string[11] = "-[WELCOME]-";
 char x[2];
 int laenge;

 void uart_init(void)
 {
 // Baudrate = 19200
 SCON = 0x50;  // 8 Bit UART 
 REN = 1; //Recieve Interrupt Enable
 IEN0 =0x10; //enable Uart interrupt
 TH1=0xFD;       
 PCON |=0x80;
 TMOD |=0x20;  // use timer 1 as baudrate generator
 TCON=0x40;    
 ES=0;    // Enable Serial IRQ (if required)
 EA= 1;    // Enable general IRQs (if required)
 TI = 0;
 }

void main()
 {
 x[1] = '\0';
 uart_init(); //Initialisierung vom Uart
 
laenge = strlen(string); //Laenge des Strings
 for(i=0;i<=laenge;i++)
 {
   TI = 0;
   SBUF = string[i];
   do
   {
   }while(TI = 0);
   TI = 0;
 }

  do
 {
 
 }while ( a = 1);
 
 }

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

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

Bernhard

Autor: R. W. (quakeman)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Bernhard (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

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.