Monday, 17 July 2017

Serial data reception using UART

We already discussed data transmission using UART where we sent the data from microcontroller to the computer. Today I will show you how to receive data using UART and display it on LCD.
Here I will connect LCD with PCF8574 using I2C. You can check my previous tutorial here if you haven't did it yet.
Basically what I am going to do is, i will send data using a serial monitor from the computer and that data will be displayed on the LCD. We can do this using two ways:-
1.) We continuously check for incoming data and when data is received, display it on the lcd.
2.) Use interrupt. Microcontroller does it's normal operations, and whenever the data receiving completes, an interrupt is generated and ISR is executed, after completing ISR, control returns back to normal operation.

STM32CubeMx setup is as follows

Some insight into the code:-

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) is a receive complete callback function. When the data is received via UART, this function is called. So in order to display data on LCD, we have to write our code inside this function.

if (huart->Instance == USART2)  checks whether the data received is from UART2 ?

HAL_UART_Receive_IT (&huart2, Rx_data, 1) enables the interrupt receive function. Whenever the data is received, an interrupt will be generated and ISR will be served. This function takes the following arguments:-

UART_HandleTypeDef *huart is the handletype of UART we are using 
uint8_t *pData is the pointer to the variable, where data need to be stored
uint16_t Size is the size in bytes

I am going to use I2C to connect LCD with the Nucleo using PCF8574. Also I will use COMPIM in proteus to communicate with Nucleo. Here is my proteus setup

CODE:-
I am writing only the main part here. For full code go to the end of the post

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
uint8_t i;
if (huart->Instance == USART2)             //is current uart?
{
if (Rx_indx == 0)                       //if data is not being received
{
for (i=0;i<100;i++)
{
Rx_buffer[i]=0; // clear Rx_Buffer before receiving new data
}
}
if (Rx_data[0]!=13)                     //if received data different from ascii 13 (enter)
{
Rx_buffer[Rx_indx++]= Rx_data[0];     // store data in buffer
}
else // if received data = 13
{
Rx_indx= 0;
if (!(strcmp(Rx_buffer, "goto2")))
{
lcd_send_cmd (0xc0);    // goto line 2
}
else if (!(strcmp(Rx_buffer, "clear")))
{
lcd_send_cmd (0x01);     // clear screen
lcd_send_cmd (0x80);
}
else lcd_send_string (Rx_buffer);
}
HAL_UART_Receive_IT (&huart2, Rx_data, 1);     // activate receive
}
}

NOTE:- To go to next line on LCD, simply type goto2 and to clear the whole screen type clear.



This is it guys, Hope you understood the process. Feel free to comment in case of any doubt.
For full code, click download
Visit my youtube channel controllers tech

Servo motor with STM32

I have already covered a tutorial about Pulse Width Modulation in STM32  HERE  and in this tutorial i am going to cover one of its applicat...