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();
}
}
}
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
Post a Comment