4
\$\begingroup\$

I will like to know if a baud-rate of 9600 is so fast for an 8051 MCU using an 11.0952Mhz crystal. Why? I have observed some inconsistency in the behavior of my MCU, in that when I send a set of characters looking for a particular character to perform certain operations, I discover that my MCU does not perform the required operation. Meaning that there was a misplacement along the line during receiving. Then I did some serial routine. I sent a "ABC" from terminal to the MCU, which should transmit back to the terminal an increment of each character sent, hence it should give "BCD". But this is what i got consistently - "BD" missing "C". Meaning that the MCU missed "B". I also send other set of characters and discovered that some characters get missed by the MCU. What could be the cause of this. Could it be the Baud-rate or in my code. How can I possibly rectify this.

Here is the 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;
    }
  }
}

Thanks!

\$\endgroup\$
4
  • 1
    \$\begingroup\$ Can you post your source code/assembly? \$\endgroup\$ Commented May 9, 2011 at 19:54
  • \$\begingroup\$ Please view the source file below \$\endgroup\$
    – Paul A.
    Commented May 10, 2011 at 8:26
  • \$\begingroup\$ I can't see any source? You could edit it into your question \$\endgroup\$ Commented May 10, 2011 at 8:27
  • \$\begingroup\$ 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; } } } \$\endgroup\$
    – Paul A.
    Commented May 10, 2011 at 8:36

2 Answers 2

3
\$\begingroup\$

How do you get the characters from the serial port buffer register? If you simply read them in a loop like

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

Then you will miss characters once the execution time of do_something() gets longer. Note that this includes time spend in intterrupts. The 8051 serial port has no hardware fifos, a character will be overwritten by the next one if it was not read in time.

Our solution was to read the characters into a Ringbuffer during the serial Intterupt, and to use the FIFO in the main loop. Works (with high priority interrupt) for 460800 Baud with 7,3728 MHz crystal on a Silabs 80C51FXXX.

Update

As we now see the source coude, the bug is now clear: You wait in the main loop for your character to be sent. But that means you wait a whole "character time" without being able to read your interrupt character buffer, and another few cyles to detect and read the next. This is too long if the sender sends characters fast, as a PC does.

\$\endgroup\$
6
  • \$\begingroup\$ 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; } } } \$\endgroup\$
    – Paul A.
    Commented May 10, 2011 at 8:34
  • \$\begingroup\$ Looking at the original poster's code, you're right, he needs a ring buffer. Here's one google threw up 8052.com/codelib/files/efdUartDriver.zip \$\endgroup\$ Commented May 10, 2011 at 9:37
  • \$\begingroup\$ Updated my answer as question now contains code. \$\endgroup\$
    – Turbo J
    Commented May 10, 2011 at 13:54
  • \$\begingroup\$ I got it figured out. I simple applied "tubor J" sugggestions ( who contributed above) and it worked good. Just ensure that you save all information when serial communication is going on, in a buffer. Then after, make use of the variables in the buffer. This prevents characters from been lost. Thank to all! \$\endgroup\$
    – Paul A.
    Commented May 11, 2011 at 14:31
  • \$\begingroup\$ It's worth noting that with many microcontroller UARTs, it might not be possible to send a byte for every byte that arrives in a continuous stream. If the original sender sends out an absolutely-continuous stream of data with exactly one stop bit per byte, but the controller's baud rate clock is 0.01% slow, then it will eventually lose data unless it has a means of sending out data with only 0.999 stop bits rather than a full stop bit. The difference between 1 stop bit and 0.999 may seem trivial, but it can add up. If a controller had more precise baud-rate control... \$\endgroup\$
    – supercat
    Commented Mar 25, 2014 at 15:15
3
\$\begingroup\$

With a 11.0952 MHz crystal the maximum bitrate for the 8051 is 57600 bps, so that should not be the problem. Besides, you do seem to receive some characters OK. You may want to check the answers to your other question again if you're not sure about the bitrate.

\$\endgroup\$
3
  • \$\begingroup\$ You may have missed that Paul A. posted the question you linked... \$\endgroup\$ Commented May 9, 2011 at 17:56
  • \$\begingroup\$ Yes! I am using a baudrate 9600. And I am sure of the settings. And also I am recieving some characters but it appears that some characters get missing. Appearing like the transfer rate of the character is faster for the micro controller to recieve while it is still processing an earlier received character. \$\endgroup\$
    – Paul A.
    Commented May 9, 2011 at 17:58
  • \$\begingroup\$ @reemrevnivek - Yes, I missed that :-) \$\endgroup\$
    – stevenvh
    Commented May 10, 2011 at 9:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.