UART communication using Interrupts and Standard Peripheral Library

Steps:
1)Open CoIDE. New Project
2)Add STM32F10x_MD_STDLIB i.e. standard peripheral library . This will automatically add cmsis_core to the components menu.

add the following code in main.c

#include "stm32f10x.h"
#include "string.h"
#include "stm32f10x_usart.h"
#include "misc.h"

#define RX_BUF_SIZE 80

volatile RX_FLAG_END_LINE = 0;
volatile char RX_BUF[RX_BUF_SIZE] = {'\0'};
volatile char RXi;
volatile char RXc;

void clear_RXBuffer()
{
for(RXi=0; RXi<RX_BUF_SIZE; RXi++)
{
RX_BUF[RXi]='\0';
}
RXi = 0;
}

//USART1_IRQHandler ISR is being define in file 'startup_stm32f030.s'
//We just need to redefine to overwrite the original

void USART1_IRQHandler()
{
if((USART1->SR & USART_FLAG_RXNE)!= (u16)RESET)
{
RXc = USART_ReceiveData(USART1);
RX_BUF[RXi]=RXc;
RXi++;

if(RXc != 13 )
{
if(RXi > RX_BUF_SIZE-1)
{
clear_RXBuffer();
}
}
else
{
RX_FLAG_END_LINE = 1;
}

//Echo
USART_SendData(USART1, RXc);
}
}

void usart_init()
{
/*Enable USART1 and GPIOA clock */
RCC_APB2PeriphClockCmd(RCC_APB2ENR_USART1EN|RCC_APB2ENR_IOPAEN, ENABLE);

/* NVIC Configuration */
NVIC_InitTypeDef NVIC_InitStructure;

/* Enable the USARTx Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStructure);

/* Configure GPIOs */
GPIO_InitTypeDef GPIO_InitStructure;

/* Configure USART1 TX (PA09) as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

/* Configure USART1 RX (PA10) as input floating */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);

/* Configure USART1 */
USART_InitTypeDef USART_InitStructure;

/* USART1 configuration ------------------------------------------------------*/
/* USART1 configured as follow:
- BaudRate = 115200 baud
- Word Length = 8 Bits
- One Stop Bit
- No parity
- Hardware flow control disabled (RTS and CTS signals)
- Receive and transmit enabled
- USART Clock disabled
- USART CPOL: Clock is active low
- USART CPHA: Data is captured on the middle
- USART LastBit: The clock pulse of the last data bit is not output to
 the SCLK pin
*/

USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;

USART_Init(USART1, &USART_InitStructure);

/* Enable USART1 */
USART_Cmd(USART1,ENABLE);

/* Enable USART1 Receive Interrupt: this interrupt is invoked when receive buffer is not wmpty */
USART_ITConfig(USART1,USART_IT_RXNE, ENABLE);

}

void USARTSend(char *pucBuffer)
{
while(*pucBuffer)
{
USART_SendData(USART1, *pucBuffer++);
while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET)
{
}
}
}

void SetSysClockto72()
{
ErrorStatus HSEStartUpStatus;
/* SYSCLK, HCLK, PCLK2, PCLK1 config */
/* RCC system reset(for debug purpose) */
RCC_DeInit();

/* Enable HSE */
RCC_HSEConfig(RCC_HSE_ON);

/* Wait till HSE is ready */
HSEStartUpStatus = RCC_WaitForHSEStartUp();

if(HSEStartUpStatus == SUCCESS)
{
/* Enable Prefetch Buffer */
//FLASH_PrefetchBufferCmd( FLASH_PrefetchBuffer_Enable);

/* Flash 2 wait state */
//FLASH_SetLatency( FLASH_Latency_2);

/* HCLK = SYSCLK */
RCC_HCLKConfig(RCC_SYSCLK_Div1);

/* PCLK2 = HCLK */
RCC_PCLK2Config(RCC_HCLK_Div1);

/* PCLK1 = HCLK */
RCC_PCLK1Config(RCC_HCLK_Div2);

/* PLLCLK = 8 MHz * 9 = 72 MHz */
RCC_PLLConfig(0x00010000, RCC_PLLMul_9);

/* Enable PLL */
RCC_PLLCmd(ENABLE);

/* Wait till PLL is ready */
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{
}

/* Set PLL Clock as System Clock */
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

/* Wait till PLL is used as system clock source */
while(RCC_GetSYSCLKSource() != 0x08)
{
}
}
else
{
 /* If HSE fails to start-up, the application will have wrong clock configuration.
    User can add here some code to deal with this error */
/* Go to infinite loop */
while(1)
{

}
}
}

int main(void)
{
//Set system clock
SetSysClockto72();

/* Initialize LED which is connected to PC14 */
GPIO_InitTypeDef GPIO_InitStructure;

//Enable Port C clock
RCC_APB2PeriphClockCmd(RCC_APB2ENR_IOPCEN, ENABLE);

/* Configure the GPIO LED Pin */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOC, &GPIO_InitStructure);

GPIO_ResetBits(GPIOC, GPIO_Pin_14); //Set C14 = 0

//Initialize USART
usart_init();
USARTSend("Hello.\r\nUSART1 is ready\r\n");

    while(1)
    {
    if(RX_FLAG_END_LINE == 1)
    {
    //Reset End Line Flag
    RX_FLAG_END_LINE = 0;

    USARTSend("\r\nI have received a line:\r\n");
    USARTSend(RX_BUF);
    USARTSend("\r\n");

    if(strncmp(strupr(RX_BUF),"ON\r",3)==0) //strncmp returns 0 if both strings are equal else > 1 or < 1
    {
    USARTSend("\r\nLED is now ON" );
    //USARTSend(RX_BUF);
    USARTSend("\r\n");
    GPIO_SetBits(GPIOC,GPIO_Pin_14);
    }

    if(strncmp(strupr(RX_BUF),"OFF\r",2)==0) //strncmp returns 0 if both strings are equal else > 1 or < 1
    {
    USARTSend("\r\nLED is now OFF");
    //USARTSend(RX_BUF);
    USARTSend("\r\n");
    GPIO_ResetBits(GPIOC, GPIO_Pin_14);
    }

    clear_RXBuffer();
    }
    }
}


Comments

Popular posts from this blog

HackRF with srsLTE and openlte

Blinking a LED in STM32F103C8T6 (Blue Pill) Board

Read Continuously from Serial Port in QT