In this tutorial, we are going to use interrupt to send and receive data from the computer via UART. I have already covered the basic UART interface, which was using the blocking mode. This tutorial will continue from where we left the previous one. If you haven’t checked it out, better take a look at the UART tutorial first.

Extra Registers that we are going to use

Other than the ones mentioned in the tutorial linked above, we are also going to use some additional set of registers here. These registers are related to interrupts

uart interrupt registers
  •  U0IER  is the Interrupt Enable Register. We will enable the Tx and Rx interrupts here
  •  U0IIR  is the interrupt identification register. It is used to identify, which interrupt got triggered.

There are some more Vectored Interrupt Controller (VIC) Registers, which we have to use, generally for all types of interrupts.

VIC interrupt registers
  • VICIntSelect selects the interrupt is either FIQ or IRQ. We will be using IRQ for most of our applications
  • VICIntEnable enables the respective interrupt
  • VICVectCntl0 sets the priority to the interrupt. 0 being highest, and 15 being lowest
  • VICVectAddr0 sets the address to the ISR for the Slot 0

Some Insight into the CODE

void UART0_Init (void)
	U0LCR |= (1<<7);  // DLAB=1
	/* Set the BR = 9600 for PCLK = 60MHz*/
	U0DLM = 1;
	U0DLL = 134;
	U0LCR = 0x03;  // DLAB=0, 8 bit character length, parity disabled, 1 stop bit
	U0IER |= (1<<0)|(1<<1);  // Enable the RDR and THRE interrupts

Other than the basic initialization, as mentioned in the previous tutorial, we also have to enable the interrupts for the UART0 Tx and Rx. The initialization procedure is as follows:

  • Enable the DLAB bit to enable the write access to the DLM and DLL registers
  • Set the baud rate according to the PCLK
  • clear the DLAB, set 8 bit character length, disable the priority, and select 1 stop bit
  • Enable the RDR, and THRE interrupts of UART0

the  main Function  is given below

int main ()
	PINSEL0 |= (1<<0)|(1<<2);  // 0101 == select alternate functions for RX and Tx pins
	PLL_Init ();
	VPBDIV = 0x01;  // PCLK = CCLK = 60 MHz
	UART0_Init ();
	VICIntEnable |= (1<<6);  // Enable the UART0 Interrupt
	VICIntSelect |= (0<<6);  // UART0 is IRQ and not FIQ
	VICVectCntl0 = 0x20|6;   // UART0 interrupt have highest priority
	VICVectAddr0 = (unsigned) UART0_ISR;
	while (1);
  • Set the PINSEL register to enable the alternate function for the Rx and Tx pins
  • Enable PLL and set the PCLK to 60 MHz
  • Initialize the UART0 in the interrupt mode
  • Enable UART0 in the vectored interrupt
  • Set the UART0 interrupt as IRQ
  • Give the priority slot to the UART0 interrupt
  • Assign the ISR function to the slot
void UART0_ISR (void) __irq
	uint16_t IIR = U0IIR;
	if (IIR&(1<<2))  // If the RDA interrupt is triggered
		Rx_data = U0RBR;
		U0THR = Rx_data;

	VICVectAddr = 0;

Inside the ISR (Inetrrupt Service Routine), we will check if the interrupt is triggered by the RDR. This would mean that there is some data available in the U0RBR register. If the condition is true, we will read this data and send it back to the UART, by writing it to the U0THR register.

Note that once we read the data from the U0RBR register, the interrupt bit (RDR) gets cleared automatically.



uart0 interrupt result

In the above picture, the PINK color is the one we send to the MCU, and the BLACK color is the one which is received back from mcu.

Check out the VIDEO Below


Notify of
Inline Feedbacks
View all comments