|
|
View previous topic :: View next topic |
Author |
Message |
rmd
Joined: 19 May 2005 Posts: 1
|
Software implementation of a UART |
Posted: Thu May 19, 2005 2:57 pm |
|
|
I'm trying to build an appliance with two UARTS using a 16F877.
I have big problem with the UART implemented in software: when I transmit characters from a PC one by one or with a delay of 1ms between them, all goes fine. But when I try to transmit them without that delay, they are corrupted.
Using the library code from CCS (#use RS232...) corrupts characters too.
Here's my code (in CCS, for 16F877), for my getc routine:
If I use the pins 6 & 7 of the chip for tx and rx, it happens the same
I am pretty sure its a speed problem, but how can I fix it?
#define SERIAL_PORT 0x07
#define TX_PIN 0
#define RX_PIN 1
#bit txData = SERIAL_PORT.TX_PIN
#bit rxData = SERIAL_PORT.RX_PIN
// txData and rxData are mapped onto pins TX_PIN & RX_PIN of the chip...
char my_getc(void)
{
unsigned char c, bitno;
unsigned int16 dly = 104; // magic number: bit width at 9600bps
set_tris_c(1 << RX_PIN);
for(;;)
{
while(rxData); // wait for start bit
delay_us(dly/2); // to be sure its not a glitch
if(rxData)
continue; // was just noise
c = 0;
for(bitno = 0; bitno < 8; bitno++)
{
delay_us(dly);
c = (c >> 1) | (rxData << 7);
}
return c;
}
Whit this approach, I have also written a putc() routine, which works ok.
The magic number of 104us can be calculated at assembly time and not be hardcoded, but this is a test. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu May 19, 2005 4:04 pm |
|
|
What you're calling a "magic number" is really the bit period in micro-
seconds for 9600 baud.
You have somewhat less than two bit-times (208 us) between the
time when you finish receiving one byte, and the time when you
must detect the next start bit. I calculated this from:
Approximately 1/2 bit time is left after the last bit is sampled.
1 full bit time is left, during the stop bit.
Approximately 1/2 bit time is available if the next start bit is initially
sampled near the midpoint, instead of the beginning of the bit.
This adds up to approximately 2 bit times of "slack" time, between
the bytes.
You didn't show what you're doing between calls to my_getc().
You also didn't show your PIC type, or your oscillator speed.
You may have only 200 us (let's say) available between calls to
my_getc(). If you take more than 200 us to run other routines,
before you call my_getc() again, then you will miss characters. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|