Monday, 25 September 2017

Baud-rate for 8051 Microcontroller


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!



Answer



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.


No comments:

Post a Comment

arduino - Can I use TI's cc2541 BLE as micro controller to perform operations/ processing instead of ATmega328P AU to save cost?

I am using arduino pro mini (which contains Atmega328p AU ) along with cc2541(HM-10) to process and transfer data over BLE to smartphone. I...