Hi, I’m trying to create a software usart for a project and to learn how it works. I’ve looked up some timing diagrams on the net and coded a little routine. I use WinAVR C, Mega168 at 8Mhz. Here’s what I have:
void DebugTransmit2( unsigned char Data )
{
int i;
unsigned char Byte;
setBit( PORTB, 0 );
_delay_us( 104 );
clearBit( PORTB, 0 );
_delay_us( 104 );
Byte = Data;
for ( i = 0; i < 8; i++ ) //Shift out the data
{
if ( Byte & 1 ) //Shift out the LSB
setBit( PORTB, 0 );
else
clearBit( PORTB, 0 );
Byte = Byte >> 1; //Shift down the data for the next bit
_delay_us( 104 ); //Delay to the next bit
}
setBit( PORTB, 0 );
_delay_us( 104 );
_delay_us( 104 );
}
Ok, I got it to work. I had to clear the bit right after the for loop and delay for one bit and insert a line into the for loop which doesn’t make much sense to me. The line is: if (i == 3) _delay_us(104);
so after 4 bits, I delay a dummy bit and go another 4 bits. Must be a timing problem somewhere.
Hi, I added the one stop bit (8N1 is one stop bit, verified already), but I still had to add the one bit delay after 4 bits. I tested it with a couple serial terminals that come with boot loaders and it works there, but not in HyperTerminal.
I got the transmit function to work too and had to add the bit delay there also. Strange eh?
That’s right. 8N1=1 start, 8 data, 1 stop. all same duration.
Beware this: If you do a constant transmission of back to back bytes in 8N1 and enable a receiving UART anywhere in this, it will likely not be able to find the start bit and get the correct frame synch. Solution: don’t do that. Or put in a 10 bit “marking” delay or so every now and then for the receiver to re-synch on the start bit.