The following example shows how we can use our queues as circular buffer to receive characters from the serial port, then catch them in our main loop and assemble a potential message, using this technique for serial reception reduce a lot the complexity in our ISR routine
#include "bsp.h"
#include <string.h>
#include "queue.h"
#define BUFFER_SIZE 10
QueueType Queue; /*queue control structure */
UART_HandleTypeDef UartHandle; /*uart handler*/
int main( void )
{
GPIO_InitTypeDef GPIO_InitStruct; /*gpio init structure*/
static uint8_t RxByte; /*variable to store the received byte*/
static uint8_t RxBuffer[ BUFFER_SIZE ]; /* array of ten elements to use as queue memory space */
uint8_t Message[ BUFFER_SIZE ]; /*array to assemble the message from the queue*/
uint8_t iterator = 0; /*index for the message array*/
HAL_Init(); /*init cube library*/
__HAL_RCC_GPIOC_CLK_ENABLE(); /*enable clock on port C*/
/*config pins 0, 1 y 2 from port C as output push-pull*/
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
/*set configuration*/
HAL_GPIO_Init( GPIOC, &GPIO_InitStruct );
/*uart configuration options for module USART2, 9600 baudrate,
8bits, 1 stop bit, no parity, no flow control, and 8 bit lenght */
UartHandle.Instance = USART2;
UartHandle.Init.BaudRate = 9600;
UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
UartHandle.Init.StopBits = UART_STOPBITS_1;
UartHandle.Init.Parity = UART_PARITY_NONE;
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle.Init.Mode = UART_MODE_TX_RX;
UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
/*init uart2 with previous paramters*/
HAL_UART_Init( &UartHandle );
/*init the queue to store bytes with a maximum of 10 elements */
Queue_Init( &Queue, RxBuffer, BUFFER_SIZE, sizeof( uint8_t ) );
/*Set reception through interrupt of one character*/
HAL_UART_Receive_IT( &UartHandle, &RxByte, 1 );
while(1)
{
/*read the queue until it is empty, at this point we do not know
how many characters have been received*/
while( Queue_ReadData( &Queue, &Message[iterator] ) == 1 )
{
/*wait until a message is recieved*/
if( Message[iterator] == '\r' )
{
/*end of string*/
Message[iterator + 1] = '\0';
if( strcmp("one\r", (char*)Message ) == 0 )
{
/* toggle C0 if it was "one" string */
HAL_GPIO_TogglePin( GPIOC, GPIO_PIN_0 );
}
else if( strcmp("two\r", (char*)Message ) == 0 )
{
/* toggle C1 if it was "two" string */
HAL_GPIO_TogglePin( GPIOC, GPIO_PIN_1 );
}
else if( strcmp("three\r", (char*)Message ) == 0 )
{
/* toggle C2 if it was "three" string */
HAL_GPIO_TogglePin( GPIOC, GPIO_PIN_2 );
}
/*reset iterator*/
iterator = 0;
}
else
{
iterator++;
iterator %= BUFFER_SIZE;
}
}
}
}
/*This function is called everytime a new byte is received, the code in it stores the bytes
in the buffer RxBuffer and detects when the '\r' signaling the end of a string*/
void HAL_UART_RxCpltCallback( UART_HandleTypeDef *huart )
{
uint8_t *byte = huart->pRxBuffPtr - 1; /*get the byte received*/
/*store the byte in the queue if it is a lower case letter or a '\r'*/
if( ((*byte >= 'a') && (*byte <= 'z')) || (*byte == '\r') )
{
Queue_WriteData( &Queue, byte );
}
/*Set reception through interrupt of one character again*/
HAL_UART_Receive_IT( &UartHandle, byte, 1 );
}