Need help with these two methods of UART Tx.....

Go To Last Post
4 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hello avrfreaks!
i have been working over the avr UART for some time now. By this time, i have understood the Rx, and i can play with it quite well, but i still have not been able to completely understand the Tx. there are two basic approaches to the UART Tx:
1.By using the interrupts
2.By waiting for UDR to empty

i am able to perform the Tx through the second approach easily, but i still cannot use the first approach correctly.

for the second approach(that worked), the program i have written is:

void UARTTx(unsigned char ch)
{
 while(!(UCSRA & (1<<UDRE)));
 UDR=ch;
}

and, for the first approach that didn't worked, the program i have written is:

ISR(USART_UDRE_vect)
{
 if(IsTxData())
 {
  UDR=Txbuffer[Txread1++];
  if(Txread1==BUFFER_SIZE) Txread1=0;
 }
}


uint8_t IsTxData()
{
 if(Txread1==Txwrite1) return 0;
 else return 1;
}


void UARTTx(unsigned char ch)
{
 Txbuffer[Txwrite1++]=ch;
 if(Txwrite1==BUFFER_SIZE) Txwrite1=0;
}

which is not working as it sould.

can anyone please tell me where i am going wrong, and what corrections are to be made. why is it not working?

please note that that i have posted only those fragments of the two programs which differ from each other. everything else is the same in the same in both programs, obviously except that i have to enable UDRIE and global interrupts in the second approach and not in the first one.

thank you.

This topic has a solution.

Long live my MASTER.

Last Edited: Tue. Aug 4, 2015 - 05:23 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In the tx isr, you need to turn off the tx interrupt when there is no more data to send, otherwise it will keep on interrupting. When you send data, you need to enable the tx interrupt.

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

putchar:
1. if UDRE, write directly to UDR
2. else wait until space in TX buffer
3. ATOMIC(add to tail of buffer. increment tail)

TX_ISR:
1. if data in buffer, pull data from head of buffer. increment head.

There have been many textbook examples. Any form of interrupt transmission works the same. i.e. punter fills a buffer, ISR() empties the buffer.

You just choose your style of buffer. make sure that you stop interrupts when you access the buffer (atomicity).

Circular buffers are very convenient. You can fill the buffer at any time. You never lose data. In practice, your app runs very efficiently.

Your 'implementation' relies on a buffer being filled in one go. Then you can't add anything more until the ISR() has emptied the whole buffer.

Yes, you can turn TXCIE and UDRIE interrupts on and off all over the place. But a single TXCIE works pretty well.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:
In the tx isr, you need to turn off the tx interrupt when there is no more data to send, otherwise it will keep on interrupting. When you send data, you need to enable the tx interrupt.

got it!

solved the problem......

thanks a lot........

Long live my MASTER.