UART stands for Universal Asynchronous Receiver/Transmitter, which is a useful hardware feature in any microcontroller unit. Microcontrollers need to receive data, process it, and send it to other devices. There are different types of communication protocols available in microcontrollers, however, UART is the most commonly used among others such as SPI and I2C. If someone needs to receive or send data serially, UART is always the easiest and common choice. The advantage of UART is that it only requires two wires to transfer data between devices. Continuing with our Nuvoton microcontroller tutorial, in this article we will learn how to perform serial communication using the N76E003 microcontroller.

UART Communication Basics

Now, now that we know what UART is, it is important to understand the parameters related to UART.

Both UART devices receive and transmit data at the same frequency. When the receiving UART device detects a start bit, it starts reading incoming bits at a specific frequency called the baud rate. Baud rate is important for UART communication and it measures the speed of data transfer in bits per second (bps). The baud rate speed must be the same baud rate for sending and receiving. The difference in baud rate speed between the transmitting and receiving UARTs can only be about 10% before the bit timing deviates too far. The most popular baud rate speeds are 4800, 9600, 115200 bps, etc.

The N76E003 has two UARTs – UART0 and UART1. In this tutorial we will use the UART peripheral on the N76E003 microcontroller unit. Without wasting too much time, let’s evaluate what kind of hardware setup this application requires.

Hardware Requirements and Setup

The main component required for this project is a USB to UART or TTL converter module which will establish the required interface between the PC or laptop and the microcontroller module. For this project, we will be using a CP2102 based USB to UART module as shown below.

Not to mention, in addition to the above components, we will also need a development board based on the N76E003 microcontroller as well as a Nu-Link programmer. An additional 5V power supply unit may be required if the programmer is not used as a power supply.

Nuvoton N76E003 UART communication circuit diagram

As we can see in the board schematic below, pins 2 and 3 of the microcontroller unit are used as UART0 Tx and Rx respectively. On the far left, the programming interface connections are shown.

UART pins on Nuvoton N76E003 microcontroller

N76E003 has 20 pins, 4 of which can be used for UART communication. The figure below shows the UART pins highlighted in red boxes (Rx) and blue boxes (Tx).

For UART0, pins 2 and 3 are used for UART communication, and for UART1, pins 8 and 18 are used for communication.

UART Registers in Nuvoton N76E003 Microcontroller

The N76E003 has two enhanced full-duplex UARTs with automatic address recognition and frame error detection – UART0 and UART1. The two UARTs are controlled using registers categorized into two different UARTs. There are two pairs of RX and TX pins available for UART operation in the N76E003. Therefore, the first step is to select the desired UART port for operation.

In this tutorial we will be using UART0, so only the configuration for UART0 will be shown. UART1 will have the same configuration but the registers will be different.

After selecting a UART (UART0 in this example), the I/O pins required for RX and TX communication need to be configured as inputs and outputs. The RX pin of UART0 is pin 3 of the microcontroller, port 0.7. Since this is a serial receive pin, port 0.7 needs to be set as an input. On the other hand, port 0.6 which is the second pin of the microcontroller is the send pin or output pin. It needs to be set to quasi-bidirectional mode. These can be selected using the PxM1 and PxM2 registers. These two registers set the I/O mode, where x represents the port number (for example, port P1.0 registers will be P1M1 and P1M2, for P3.0 it will be P3M1 and P3M2 etc.) The configuration can be as shown in the following figure −

UART Operation Modes in N76E003

Then, the next step is to determine the mode of UART operation. Two UARTs can operate in 4 modes. The pattern is –

We can see that SM0 and SM1 (bits 7 and 6 of the SCON register) select the UART operating mode. Mode 0 is synchronous operation, the other three modes are asynchronous operation. However, the baud rate generator and framing bits are different for each serial port mode. Either mode can be selected according to the application requirements, the same is true for UART1. This tutorial uses 10-bit arithmetic and divides the Timer 3 overflow rate by 32 or 16.

Now, it’s time to get the information and configure the SCON register for UART0 (SCON_1 for UART1).

Bits 6 and 7 will set the UART mode as previously described. Bit 5 is used to set the multiprocessor communication mode to enable option. However, the procedure depends on the UART mode selected. Besides that, the REN bit will be set to 1 to enable reception and the TI flag will be set to 1 to use the printf function instead of the custom UART0 transmit function.

The next important register is the Power Control Register (PCON) (Timer 3 bits 7 and 6 of UART1) register. If you are new to timers, check out the Nuvoton N76E003 Timer Tutorial to learn how to use timers on the N76E003 microcontroller.

The SMOD bit is important to select the dual baud rate in UART0 Mode 1. Now, since we are using Timer 3, we need to configure the Timer 3 Control Register T3CON. However, bits 7 and 6 are reserved for the double data rate setting for UART1.

and Timer 3 prescaler value-

Bit 5, BRCK, sets Timer 3 as the baud rate clock source for UART1. Now, the datasheet of N76E003 gives the formula to calculate the required baud rate and the sampling setting value of timer 3 (16 bit) high and low register.

Sample values ​​for a 16 Mhz clock source –

Therefore the baud rate needs to be configured in the Timer 3 register using the above formula. For our example it will be formula 4. Afterwards, starting Timer 3 by setting the TR3 register to 1 will complete the UART0 initialization of Timer 3. To receive and transmit UART0 data, use the following registers −

The SBUF register is automatically configured for receive and transmit. To receive data from UART, wait for RI flag to be set and read SBUF register and send data to UART0, send data to SBUF and wait for TI flag to be set to confirm successful data transfer.

Programming Nuvoton N76E003 for UART communication

The coding part is simple, the full code used in this tutorial can be found at the bottom of this page. The code is explained below, use the statement in the main function to initialize UART0 to 9600 baud rate –

initial UART0_TImer3(9600);

The above function is defined in common.c file, it configures UART0, timer 3 as baud rate source, mode 1, baud rate 9600. The function is defined as follows −

void InitialUART0_Timer3(UINT32 u32Baudrate) //Use timer3 as a baud rate generator { P06_Quasi_Mode; //Set the UART pin as quasi-mode transmission P07_Input_Mode; //Set the UART pin to receive the input mode of SCON = 0x50; //UART0 Mode1,REN=1,TI=1 set_SMOD; //UART0 double rate enable T3CON &= 0xF8; //T3PS2=0,T3PS1=0,T3PS0=0(Prescale=1) set_BRCK; //UART0 baud rate Clock Source = Timer3 #ifdef FOSC_160000 RH3= HIBYTE(65536 - (1000000/u32Baudrate)-1); /*16 MHz */ RL3= LOBYTE(65536 - (1000000/u32Baudrate)-1); /*16 MHz */ # endif #ifdef FOSC_166000 RH3= HIBYTE(65536 - (1037500/u32Baudrate)); /*16.6 MHz*/ RL3 = LOBYTE(65536 - (1037500/u32Baudrate)); /*16.6 MHz */ #endif set_TR3; //trigger Timer3 set_TI; // must set TI = 1 for printf function }

As mentioned before, the declaration is done step by step and the registers are configured accordingly. However, in the BSP library of N76E003, there is a bug that replaces P07_Input_Mode; there is P07_Quasi_Mode. Therefore, the UART receive function will not work.

The baud rate is also entered according to the baud rate and configured using the formula given in the datasheet. Now, in the main function or in the while loop, the printf function is used. To use the printf function, TI needs to be set to 1. Besides that, in the while loop, use switch case and print the value based on the received UART data.

while(1) { printf("\r\npress 1 or press 2 or press 3 or press 4"); operation = Receive_Data_From_UART0(); switch (oper) { case '1': printf("\r\n1 is pressed"); break; case '2': printf("\r\n2 was pressed"); break; case '3': printf("\r\n3 was pressed"); break; case '4 ': printf("\r\n4 was pressed"); break; default: printf("\r\nwrong key pressed"); } Timer0_Delay1ms(300); }}

Well, for UART0 receive Receive_Data_From_UART0(); use function. It is also defined in the common.c library.

UINT8 Receive_Data_From_UART0(void) { UINT8 c; while(!RI); c = SBUF; RI = 0; return(c); }

It will wait for RI flag to be 1 and return received data using variable c.

Blink codes and output

The code returns 0 warnings and 0 errors, and blinks using Keil’s default blink method. If you’re not sure how to compile and upload your code, check out the getting started with nuvoton article. The following lines confirm that our code was successfully uploaded.

Rebuild started: Project: printf_UART0 Rebuild target 'GPIO' Compiling PUTCHAR.C...Compiling Print_UART0.C...Compiling Delay.c...Compiling Common.c...Assembling STARTUP.A51.. .Linking... program size: data=54.2 xdata=0 code=2341 creating hex file from ".\Output\Printf_UART1"... ".\Output\Printf_UART1" - 0 errors, 0 warnings . Build Time Elapsed: 00:00:02 Loading "G:\\n76E003\\software\\N76E003_BSP_Keil_C51_V1.0.6\\Sample_Code\\UART0_Printf\\Output\\Printf_UART1" Flash Erase Completed. Flash write completed: 2341 bytes programmed. Flash verification complete: 2341 bytes verified. Flash load completed at 15:48:08

The development board is connected to the power supply through a programmer and a laptop using a USB-to-UART module. To display or send UART data, serial monitor software is required. I’m using tera term in this process.

As shown in the picture below, I am able to display the string sent from our nuvoton controller and display it on the serial monitor software. Also able to read values ​​from serial monitor.

#include “N76E003.h”
#include “SFR_Macro.h”
#include “Function definition.h”
#include “Common.h”
#include “Delay.h”
/*================================================= ============================*/
void main(void)
{
character manipulation;
initial UART0_Timer3(9600);
TI = 1; // The printft function is used.
printf(“Hello CircuitDigest\r\n”);
while (1)
{
printf(“\r\npress 1 or press 2 or press 3 or press 4”);
Operation = Receive_Data_From_UART0();
switch(action) {
Case 1′:
printf(“\r\n1 is pressed”);
rest;
Case “2”:
printf(“\r\n2 is pressed”);
rest;
Case “3”:
printf(“\r\n3 is pressed”);
rest;
Case “4”:
printf(“\r\n4 is pressed”);
rest;
default:
printf(“\r\npress the wrong key”);
}
Timer0_Delay1ms(300);
}
}

Leave a Reply

Your email address will not be published.