SparkFun Forums 

Where electronics enthusiasts find answers.

Your source for all things Atmel.
By brainwav
#56080
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:
Code: Select all
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 );
}

I get this out of it:
FF 11111111
FF 11111111
81 10000001
82 10000010
80 10000000
84 10000100
88 10001000
90 10010000
A0 10100000

When I call DebugTransmit2 with these values:
0xFF, 0xFF, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40

I got 104uSec from 8e6/9600 cycles at 1/8e6 per cycle = 104usec
I'm not sure what I'm doing wrong.
Brainwav.
By brainwav
#56092
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.
By stevech
#56094
For asynchronous UARTs, you need 1.5 or more bit times for the stop bit.

Each byte in a real UART is one start bit, 8 data bits, and 1.5 or 2 stop bits, or more. At least that's what 8N1 is.

So check out marking/spacing for start/stop bits.

Your code to add a mid-byte delay isn't correct.
User avatar
By leon_heller
#56095
8N1 is one stop bit!

Leon
By brainwav
#56097
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?
By stevech
#56110
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.

http://en.wikipedia.org/wiki/Asynchronous_start-stop