implementing uart by digital I/o

Thread Starter

embedded.world

Joined Feb 27, 2014
38
I am using AT89C51.
I need two uart in my application. One uart is available in MCU.

Second I am thinking to implement by digital I/o's


Is there any reference code available for this.
I am using Rx,Tx & Gnd only.

Data can rx/tx simultaneously on both uart, so rx procedure has to be in ISR.

Tx should be ideally high so can I put a 10K pull up on tx line
 
Last edited:

Thread Starter

embedded.world

Joined Feb 27, 2014
38
I have searched some reference from internet & trimmed the code for my requirement.

I have made a small algo for this. Can anyone look at it if this is correct.

Meanwhile I am writing the code for it.


void uart_configure(void)
{
rx_pin_Input__FallingEdgeInterrupt__NoPullUp__NoPullDown
tx_pin_Output_High
}


void rx_pin_ISR(void)
{
clear_isr_flag
disable_interrupt

/* communication start */
rx_start = 1;
}



void uart_tx(unit8_t data)
{

// start bit
tx_pin = 0;
__delay_us(OneBitDelay);

//data
for(cnt = 0 ; cnt < 8 ; cnt++)
{
if((data >> cnt) & 0x01)
{
tx_pin = 1;
}
else
{
tx_pin = 0;
}
__delay_us(OneBitDelay);
}

//stop bit
tx_pin = 1;
__delay_us(OneBitDelay);

}



uint8_t uart_rx(void)
{
/* initially data is rECeived here */
while(0 == rx_start);
rx_start = 0;

// IMP: Added so that pin can be sampled in mid of bit duration
__delay_us(OneBitDelay);
__delay_us(OneBitDelay/2);

/* data */
for(cnt = 0 ; cnt < 8 ; cnt++)
{
if(rx_pin_high)
{
data = data | (1 << cnt);
}
__delay_us(OneBitDelay);
}

/* stop bit */
if(rx_pin_high)
{
__delay_us(OneBitDelay/2)
return data;
}
else
{
__delay_us(OneBitDelay/2)
return 0;
}

}



void main(void)
{
rx_start = 0;
uart_configure();

while(1)
{
data = uart_rx();

/* tx the byte as sson as received */
uart_tx(data);

/* reenable rx pin interrupt */
enable_rx_pin_isr
}

}
 

John P

Joined Oct 14, 2008
2,025
With this software UART of yours, what will you do if there's a character being sent out, and half way through it a character starts coming in? It doesn't seem to me as if this can work.
 

THE_RB

Joined Feb 11, 2008
5,438
Agreed.

A better method is to use a timer interrupt at about 5* higher freq than one bit period. That int can constantly poll for incoming RX data and sync to it. It can also simultaneously (asynchronously) send TX data, sending one bit every 5 ints.

A timer interrupt setup this way can process multiple RX and TX signals, to multiple in/out pins.

So once it has been set up it is trivial to add more TX or RX channels.
 

shteii01

Joined Feb 19, 2010
4,644
I have a silly question.
Would it not be easier to use uart ic chip instead?

I just looked at one at mouser, the datasheet even had an example code in C.
 
Top