UART  Data Register Empty Interrupt

As described the USART can generate interrupt if the data register is empty. The interrupt could be enabled setting the Data Register Empty Interrupt Enable(UDRIE0) . 

The USART Data Register Empty ISR will be executed until the UDRE0 is set (if the global interrupts are enabled).

Note that the UDRE0 flag is cleared by writing UDR0. 

When we want to transmit data we can put them into a transmission buffer and then we need to enabled the Data register empty interrupt. The Data Register Empty interrupt routine must either write new data to UDR0 in order to clear UDRE0 or disable the Data Register Empty interrupt, otherwise a new interrupt will occur once the interrupt routine terminates.

The following meta-code illustrates the usage of this type of interrupt and the routine used to send the data.


ISR(USART_UDRE_vect)

{

    unsigned char ucTail;

   /* if there's at least one "character" into the transmitter buffer then send it 

    * if there was a tx interrupt

    * writing the UDR0 register.

    * UDR0 =  char to send.

    */

    

   /* If the tx buffer is empty then we disable the UDRE interrupt 

      so to stop this interrupt generation !!! 

      we enable it if there will be at least one character to send         

    */

    UCSR0B &= ~_BV(UART0_UDRIE);

}


/** Send a character identified by the ucData

  */

void uart_putc(unsigned char ucData)

{

    unsigned char ucHead;


    /* check if the tx buffer isn't full, else loop until it will be not full.

     */

    

    /* put the data to be transmitted into the Tx buffer 

     */

    

    /* If we have disabled the TX interrupt in the ISR now I need to enable again it 

       (UDRE) bit register 

*/

    UCSR0B  |= _BV(UART0_UDRIE);


}

Transmit complete interrupt.

The third interrupt that USART can generate is the Transmit Complete Interrupt. It will be generated when the transmission of the data will be completed, if the Transmission interrupt enable bit is set in the UCSR0B register. This interrupt is connected to the Transmit Complete (TXC0) Flag bit that will be set to one when the entire frame in the Transmit Shift Register has been shifted out and there are no new data currently present in the transmit buffer.

The TXC0 Flag bit is automatically cleared when a transmit complete interrupt is executed. The TXC0 Flag is useful in half-duplex communication interfaces where a transmitting application must enter receive mode and the application needs to release the communication bus immediately after the transmission.

The following meta-code illustrates the usage of this type of interrupt and the routine used to send the data.

 

/* this var specify if there are the possibilities to send a character  */

volatile unsigned char gucUartReadyTx ;


ISR(USART_TX_vect)

{

    /* if there's at least one "character" in the buffer then take it, from the software Tx buffer, 

     * and send it  

     */

    

    /* send the data */

    UDR0 = data to send 

    /* else  put to no data ready to be transmitted 

     */

    gucUartReadyTx = 1;   


    }


void uart_putchar(unsigned char ucData)

{

   /*  wait for the transmitter to be ready

    */

   while(!gucUartReadyTx);

   

   /* put the data  in the tx buffer 

    */

   UDR0 = ucData;

   /* set ready state to FALSE

    */

   gucUartReadyTx = 0;

}


void uartSendTxBuffer(void)

{

   /* Put the data into the software Tx buffer if there is the appropriate space, 

    * or put all the possible data into the buffer (possible improvement)and return

    * the number of characters inserted into the Tx buffer.

    */

   /* If I inserted the data in the Tx buffer  i can extract the first element from the buffer 

    * and call the uart_putchar function.

    */

 

}

 

(to be continued…)

The index page