Baudrate für 8051 Microcontroller

Ich würde gerne wissen, ob eine Baudrate von 9600 für eine 8051-MCU mit einem 11,0952-MHz-Quarz so schnell ist. Warum? Ich habe eine gewisse Inkonsistenz im Verhalten meiner MCU festgestellt, da ich feststelle, dass meine MCU die erforderliche Operation nicht ausführt, wenn ich eine Reihe von Zeichen sende, die nach einem bestimmten Zeichen suchen, um bestimmte Operationen auszuführen. Dies bedeutet, dass beim Empfang eine Fehlplatzierung entlang der Leitung aufgetreten ist. Dann habe ich eine Serienroutine gemacht. Ich habe ein "ABC" vom Terminal an die MCU gesendet, die ein Inkrement jedes gesendeten Zeichens an das Terminal zurücksenden sollte, daher sollte es "BCD" geben. Aber das habe ich immer wieder bekommen - "BD" fehlt "C". Das bedeutet, dass die MCU "B" verpasst hat. Ich habe auch andere Zeichensätze gesendet und festgestellt, dass einige Zeichen von der MCU übersehen werden. Was könnte die Ursache dafür sein. Könnte es an der Baudrate liegen oder an meinem Code. Wie kann ich das eventuell beheben.

Hier ist der Code.

void initUART()
{
  SCON = 0x50;
  TMOD = 0x20;
  TH1 = TL1 =-3;
  TR1 = 1;
}

void sendCHAR()
{
  SBUF = uartBUFF[s];
  while(!TI);
  TI=0;
}

void serial_isr(void) interrupt 4  
{
  if (RI)
  {
    RI = 0;
    tmpBUFF = SBUF;
    charFLAG=1;
  }
}

main()
{
  IE= 0x91;
  initUART();
  while (1)
  {
    if(charFLAG)
    {
      SBUF = (tmpBUFF+1);
      while(!TI);
      TI=0;
      charFLAG = 0;
    }
  }
}

Danke!

Können Sie Ihren Quellcode/Assembly posten?
Bitte sehen Sie sich die Quelldatei unten an
Ich kann keine Quelle sehen? Sie könnten es in Ihre Frage bearbeiten
Void initUART () { SCON = 0x50; TMOD = 0x20; TH1 = TL1 = –3; TR1 = 1; } Void sendCHAR () { SBUF = uartBUFF [s]; während(!TI); TI=0; aufrechtzuerhalten. void serial_isr (void) unterbrechen 4 {wenn (RI) {RI = 0; tmpBUFF = SBUF; charFLAG=1;}} main() { IE= 0x91; initUART(); while (1) {if(charFLAG) {SBUF = (tmpBUFF+1); während(!TI); TI=0; charFLAG = 0; } } }

Antworten (2)

Wie erhalten Sie die Zeichen aus dem Pufferregister der seriellen Schnittstelle? Liest man sie einfach in einer Schleife wie

void main() {       
  char c;
  while (1) {
    c=SBUF;
    do_something(c);
  }
}

Dann werden Ihnen Zeichen fehlen, sobald die Ausführungszeit von do_something() länger wird. Beachten Sie, dass dies die Zeit beinhaltet, die in Interrupts verbracht wird. Der serielle Port 8051 hat keine Hardware-Fifos, ein Zeichen wird vom nächsten überschrieben, wenn es nicht rechtzeitig gelesen wurde.

Unsere Lösung bestand darin, die Zeichen während des seriellen Interrupts in einen Ringbuffer einzulesen und den FIFO in der Hauptschleife zu verwenden. Funktioniert (mit High Priority Interrupt) für 460800 Baud mit 7,3728 MHz Quarz auf einem Silabs 80C51FXXX.

Aktualisieren

Da wir jetzt den Quellcode sehen, ist der Fehler nun klar: Sie warten in der Hauptschleife darauf, dass Ihr Zeichen gesendet wird. Aber das bedeutet, dass Sie eine ganze "Zeichenzeit" warten, ohne Ihren Interrupt-Zeichenpuffer lesen zu können, und noch ein paar Zyklen, um den nächsten zu erkennen und zu lesen. Dies ist zu lang, wenn der Sender Zeichen schnell sendet, wie es ein PC tut.

Void initUART () { SCON = 0x50; TMOD = 0x20; TH1 = TL1 = –3; TR1 = 1; } Void sendCHAR () { SBUF = uartBUFF [s]; während(!TI); TI=0; aufrechtzuerhalten. void serial_isr (void) unterbrechen 4 {wenn (RI) {RI = 0; tmpBUFF = SBUF; charFLAG=1;}} main() { IE= 0x91; initUART(); while (1) {if(charFLAG) {SBUF = (tmpBUFF+1); während(!TI); TI=0; charFLAG = 0; } } }
Wenn Sie sich den Code des ursprünglichen Posters ansehen, haben Sie Recht, er benötigt einen Ringpuffer. Hier ist eine von Google ausgegebene Datei 8052.com/codelib/files/efdUartDriver.zip
Meine Antwort wurde aktualisiert, da die Frage jetzt Code enthält.
Ich habe es herausgefunden. Ich habe einfach die Vorschläge von "tubor J" (die oben beigetragen haben) angewendet und es hat gut funktioniert. Stellen Sie einfach sicher, dass Sie alle Informationen in einem Puffer speichern, wenn die serielle Kommunikation läuft. Verwenden Sie danach die Variablen im Puffer. Dadurch wird verhindert, dass Zeichen verloren gehen. Vielen Dank an alle!
Es ist erwähnenswert, dass es bei vielen Mikrocontroller-UARTs möglicherweise nicht möglich ist, ein Byte für jedes Byte zu senden, das in einem kontinuierlichen Strom ankommt. Wenn der ursprüngliche Sender einen absolut kontinuierlichen Datenstrom mit genau einem Stoppbit pro Byte aussendet, die Baudratenuhr des Controllers jedoch um 0,01 % langsam ist, verliert er schließlich Daten, es sei denn, er hat die Möglichkeit, Daten mit nur 0,999 zu senden Stoppbits anstelle eines vollständigen Stoppbits. Der Unterschied zwischen 1 Stoppbit und 0,999 mag trivial erscheinen, kann sich aber summieren. Wenn ein Controller eine präzisere Baudratensteuerung hätte ...
...man könnte einfach sicherstellen, dass der Baudtakt des Controllers ein kleines bisschen (zB 0,1%) schneller ist als der des sendenden Geräts; Eine solche Technik wird von 1200-Baud-Modems verwendet (die, wenn ich mich recht erinnere, tatsächlich Daten mit ungefähr 1202 Bit/Sekunde austauschen), aber der 8051 ist nicht in der Lage, das gut zu machen. Man könnte ein solches Verhalten simulieren, wenn man gelegentlich Interrupts deaktiviert, die UART-Baudrate kurz etwas schneller und langsamer zurücksetzt und Interrupts wieder aktiviert (so dass jede solche Operation die Bitblöcke des UART um einen Bruchteil eines Bits vorrücken würde ).

Mit einem 11,0952-MHz-Quarz beträgt die maximale Bitrate für den 8051 57600 bps, das sollte also kein Problem sein. Außerdem scheinen Sie einige Zeichen OK zu erhalten. Vielleicht möchten Sie die Antworten auf Ihre andere Frage noch einmal überprüfen, wenn Sie sich bezüglich der Bitrate nicht sicher sind.

Sie haben vielleicht übersehen, dass Paul A. die von Ihnen verlinkte Frage gepostet hat ...
Ja! Ich verwende eine Baudrate von 9600. Und ich bin mir der Einstellungen sicher. Und ich erhalte auch einige Zeichen, aber es scheint, dass einige Zeichen fehlen. Es scheint, als ob die Übertragungsrate des Zeichens für den Mikrocontroller schneller zu empfangen ist, während er noch ein früher empfangenes Zeichen verarbeitet.
@reemrevnivek - Ja, das habe ich übersehen :-)