USART read write tutorial using MPLAB Harmony

This tutorial shows how to use USART driver with MPLAB Harmony to read and write to hyperterminal

The USART(Universal Synchronous Asynchronous Receiver Transmitter) is serial communication protocol that allows two devices communicate with each other. Many microcontrollers such as the PIC32 microcontroller has dedicated USART hardware build inside it to ease interface and control, transfer data to or fro with external devices. Learning Microcontrollers USART is important for any electronics undergraduates and graduate students as this allows you to create communication interface between the mircocontroller and the external devices. In electronics engineering schools or electrical engineering schools you might have learned the theory behind USART. You can here now learn how to use and configure PIC32 USART.

There are multiple ways you can configure PIC32 USART and transfer data but here we will use the Microchip Harmony framework to do this. In this tutorial we will create a simple application in which the user are prompted to enter some text which is then send to the PIC32 microcontroller. Then the PIC32 micrcontroller will read the data and resend it back to the terminal screen.

In this tutorial PIC32MX470L will be used.

1.Creating Harmony Project

The first step is to create a new Harmony Project. This step was explained numerous times in earlier project such as Reading and Writing data to USART in MPLAB harmony. However here we will again explain it. After opening the MPLABX IDE use the New > Project from the toolbar to create a new MPLAB Harmony Project.

Specify the name of the project and the directory as shown below. Note that you have also to select the microcontroller with which you are working. Here this is PIC32MX470F512L.

After this a project directory in the project window in MPLABX IDE will be created. There are folders but they are empty.


2. Configure microcontroller Clock, Ports/Pins and USART Drivers using MHC

The next step is to configure the PIC32 microcontroller clock, ports and pins and drivers which you want to use. Microchip provides the MHC(MPLAB Harmony Configurator) tool to do all these.

The step to use MHC is to first configure the clock for the microcontroller, configure ports/pins if you have specific use for them such as using LED, and then configure what drivers to use.

From the toolbar you have to open the MHC as shown below.

Using the clock tab we can visually set the clock. In our case, it is 12MHz and so HS(High Speed) should be selected. Also for the USB of the PIC32 we need to set divider to 3 to give 48MHz frequency.

The next step usually is to set the ports and pins from the pin diagram and pin setting tabs. But for our purpose we don’t need it. The USART driver and its pins can be directly set from the Options tab.

From the options tab we should configure the USART driver. To configure the USART driver, navigate to the Harmony Framework Configuration > Drivers > USART. Check the Use USART checkbox the configure the USART driver to be used in dynamic mode, without interrupt and use to Read\Write Model Support as shown in the animation below.

Configuring USART driver using MPLAB Harmony Configurator

Then save and generate the code. Now required configuration codes will be populated into the appropriate project folders.

This generated codes are system initialization codes, driver initialization codes, codes related to application etc.

For example, MHC generates the necessary USART driver initialization code according to the configuration we made earlier. The USART driver initialization code is realized as a structure using the  DRV_USART_Init type. Most of the driver requires initialization structure and are named usually DRV_XXXXX_Init where XXXXX stands for the name of the driver like USART or ADC etc. This initialization data structure is found in the system_init.c file in the source files > app > system_config > default and this initialization structure is shown below.

This data structure is then used to initialize the USART driver using the DRV_USART_Initialize() function within the function SYS_Initialize() function which resides in the same file system_init.c. What we get is a handle to driver used by the system. This part of the code is shown below.

The sysObj.drvUsart0 is the handle to the USART driver used by the system via system API to monitor, update the USART driver. The following code illustrates this. In the system_tasks.c file, within the function SYS_Tasks(), the system API such as DRV_USART_TasksTransmit(), DRV_USART_TasksError and DRV_USART_TasksRecieve() uses the handle to maintain the driver services.

The meaning of sysObj.drvUsart0 is that drvUsart0 is an instance of sysObj. In MPLAB Harmony, data structures, pointers are used to create objects and handles. So you have to learn basics of creating structures in C programming language. See Learning to Write Structures in C for simple example.

The drvUsart0 is declared as element of sysObj in the system_defination.c file.

So anytime you need to create system handle to drivers, you can create that in the system_definition.c file.

3. Creating Application Codes

Once the microcontroller is configured(clock,pins etc) and the USART driver is initialized the next step is work on the application code.

In MPLAB Harmony, the user application codes resides in the two files- app.h header file and app.c file. In the app.h file all the initial application variable(the state machine variable) and state of the state machine should be put. Then in the app.c the application code should be put.

In this USART example, we want to illustrate how to perform USART read and write. And for this purpose, we want to write a message to the terminal to inform user to input some text. After the user has entered the text, the PIC32 should read the text and then send out the same text to the user.

Creating Application states and variables

According to our application requirement we create 3 states- APP_Inform_Write, APP_Message_Read, APP_Message_Write. The first state APP_Inform_Write will open the USART driver and obtain a client handle. How this USART client handle is created and used is explained later. Once we have obtained the client handle, we create a function to write to the user a message to enter any text. After completion of this, the state machine advances to the next state which is the APP_Message_Read state. Here in this 2nd state, we read the user input text. And then finally in the 3rd state, we send the read text back to the user via terminal.

So to create these new states, we first write the following in the app.h file.

We also need one global variables which is the size of the buffer we will be using. Global variables can be placed in the system_config.h file as follows.

Then we add one application variable char buffer[BUFF_SIZE] to hold the data in the app.h file.

Creating USART client handle

Also in the same app.h header file, we create a client handle to the USART driver. The concept is similar to creating system handle to USART, explained previously. Like application states and variables, the usual place to declare the client handle is in the app.h file. The client handle is created using DRV_HANDLE similar to SYS_MODULE_OBJ for system handle.

The following code shows how to create USART client handle.

Initializing the application state and variables

The next step is to initialize the application states and variables, that is, to put the state machine in known initial state and to initialize variables. We have not used any variables in this example. This initialization of state is done within the APP_Initialize() function in app.c.

Writing State Machine

Then the next step is to write the actual application as state machine. This is shown below and explained afterwards.

In the first state APP_Inform_Write, we first obtain a handle to the USART driver to use with the application. This is done using the DRV_USART_Open() function. What we have to pass to this DRV_USART_Open() function is the system USART object and the read, write or both intention and blocking or non-blocking mode.

The function returns the client handle appData.usartHandle.

Using this client handle we check using if statement whether we obtained a valid handle. If the handle is valid then we use the WriteUSART() function to send message “Enter Some Text:” to the user via terminal. The function WriteUSART() is user created function(explained later) and accepts two arguments, the USART client handle and the message. This function returns true if the writing work is completed and returns false if the writing by the USART is not completed. If the return is true, which means the message is sent successfully, we move to next state APP_Message_Read. The WriteUSART()  function has still to be implemented which is explained later on.

In the 2nd state APP_Message Read, the application should read the text typed by the user on the terminal. In similar manner to write operation in the first state, we create a function called ReadUSART() to read the USART buffer. This function is explained later but for now, it accepts 3 agruments- the client handle, the buffer character array and the size of the array. The function returns true if all the data has been read otherwise it will return false. If the return is true we move to the next state which is the APP_Message_Write.

In the third state APP_Message_Write, we send back the text read by USART using the same earlier write function WriteUSART(). If the write is sucessful, it returns true and we go back to the initial state APP_Inform_Write.

Creating local functions

Now we explain the two functions, ReadUSART() and WriteUSART(). These function should be implemented in the app.c file.

The ReadUSART() function is as follows.

And the WriteUSART() function is as follows.

These functions should be implemented after the APP_Tasks() function. The prototype for these functions should be placed somewhere at the top, after APP_Initialize() function. The prototype functions are as follows.

Running the Application

Now the application code is completed. You should compile and run the code on your PIC32 microcontroller. Then you should use a hyperterminal window and once you connect you should see the message Enter Some Text: Type in some text and it should be shown back to you.

This completes the USART read and write tutorial using MPLAB Harmony.


What do you think?

0 points
Upvote Downvote

Total votes: 0

Upvotes: 0

Upvotes percentage: 0.000000%

Downvotes: 0

Downvotes percentage: 0.000000%


Leave a Reply
  1. Hi very good page. I can’t understand where you configure the pins for TX and RX. This PIC has PPS and you need to remap TX and RX to some pins. Who are the pins for TX and RX?

  2. hi,

    did you try the Pin Diagram and pin table feature of MHC? there you can set the which USART pins to use for TX and RX. You will see a diagram of the PIC32 chip and its pin where you can directly select the right pin and mark them as TX and RX(you need to also look datasheet to know where the USART pins are). After that you generate the code.

    Example see how to set the pins in this post

    hopes this helps

Leave a Reply

Your email address will not be published. Required fields are marked *

Pass an entire array to a function using Pointers

How to configure CODEC driver using MPLAB Harmony

How to configure CODEC driver using MPLAB Harmony