2023-02-24 00:30:16 +08:00

161 lines
4.0 KiB
C

/***
* Demo: RX Interrupts
*/
#include "main.h"
#define BUF_SIZE 128
uint8_t pBuf[BUF_SIZE], ch;
__IO uint8_t printFlag = 0, pos = 0;
static void APP_SystemClockConfig(void);
void APP_USART_Config(uint32_t baudRate);
void APP_USART_IRQCallback(USART_TypeDef *USARTx);
int main(void)
{
APP_SystemClockConfig();
APP_USART_Config(115200);
printf("PY32F0 UART Interrupt RX Demo\r\nClock: %ld\r\n", SystemCoreClock);
while (1)
{
if (printFlag == 1)
{
LL_GPIO_TogglePin(GPIOB, LL_GPIO_PIN_5);
printf("%s\r\n", pBuf);
printFlag = 0;
pos = 0;
}
}
}
void USART2_IRQHandler(void)
{
APP_USART_IRQCallback(USART2);
}
/**
* @brief USART2 GPIO & Interrupt Config
*/
void APP_USART_Config(uint32_t baudRate)
{
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART2);
/* USART2 Init */
LL_USART_SetBaudRate(USART2, SystemCoreClock, LL_USART_OVERSAMPLING_16, baudRate);
LL_USART_SetDataWidth(USART2, LL_USART_DATAWIDTH_8B);
LL_USART_SetStopBitsLength(USART2, LL_USART_STOPBITS_1);
LL_USART_SetParity(USART2, LL_USART_PARITY_NONE);
LL_USART_SetHWFlowCtrl(USART2, LL_USART_HWCONTROL_NONE);
// Both direction
LL_USART_SetTransferDirection(USART2, LL_USART_DIRECTION_TX_RX);
LL_USART_Enable(USART2);
LL_USART_ClearFlag_TC(USART2);
LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);
// PA2 ------> USART1_TX
LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_2, LL_GPIO_MODE_ALTERNATE);
LL_GPIO_SetPinSpeed(GPIOA, LL_GPIO_PIN_2, LL_GPIO_SPEED_FREQ_VERY_HIGH);
LL_GPIO_SetPinPull(GPIOA, LL_GPIO_PIN_2, LL_GPIO_PULL_UP);
LL_GPIO_SetAFPin_0_7(GPIOA, LL_GPIO_PIN_2, LL_GPIO_AF_4);
// PA3 ------> USART1_RX
LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_3, LL_GPIO_MODE_ALTERNATE);
LL_GPIO_SetPinSpeed(GPIOA, LL_GPIO_PIN_3, LL_GPIO_SPEED_FREQ_VERY_HIGH);
LL_GPIO_SetPinPull(GPIOA, LL_GPIO_PIN_3, LL_GPIO_PULL_UP);
LL_GPIO_SetAFPin_0_7(GPIOA, LL_GPIO_PIN_3, LL_GPIO_AF_4);
// Enable parity error interrupt
LL_USART_EnableIT_PE(USART2);
// Enable framing error, overrun error and noise error interrupt
LL_USART_EnableIT_ERROR(USART2);
// Enable RX not empty interrupt
LL_USART_EnableIT_RXNE(USART2);
// Interrupt priority
NVIC_SetPriority(USART2_IRQn, 1);
NVIC_EnableIRQ(USART2_IRQn);
#if defined (__GNUC__) && !defined (__clang__)
// To avoid io buffer
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stdin, NULL, _IONBF, 0);
#endif
}
void APP_USART_IRQCallback(USART_TypeDef *USARTx)
{
// Parity Error
if (LL_USART_IsActiveFlag_PE(USARTx))
{
LL_USART_ClearFlag_PE(USARTx);
}
// Framing Error
if (LL_USART_IsActiveFlag_FE(USARTx))
{
LL_USART_ClearFlag_FE(USARTx);
}
// OverRun Error
if (LL_USART_IsActiveFlag_ORE(USARTx))
{
LL_USART_ClearFlag_ORE(USARTx);
}
// Noise error
if (LL_USART_IsActiveFlag_NE(USARTx))
{
LL_USART_ClearFlag_NE(USARTx);
}
// RX Not Empty, RX Not Empty Interrupt is enabled
if (LL_USART_IsActiveFlag_RXNE(USARTx) && LL_USART_IsEnabledIT_RXNE(USARTx))
{
// Read one byte
ch = LL_USART_ReceiveData8(USARTx);
if (ch == '\r' || ch == '\n')
{
// Set print flag when meet \r or \n, ignore empty string
if (pos > 0)
{
pBuf[pos++] = '\0';
printFlag = 1;
}
}
else
{
// Append new char
pBuf[pos++] = ch;
if (pos == BUF_SIZE)
{
pos = 0;
}
}
// Read USART_DR will clear RXNE flag, so LL_USART_ClearFlag_RXNE() is not necessary
}
}
static void APP_SystemClockConfig(void)
{
LL_RCC_HSI_Enable();
while(LL_RCC_HSI_IsReady() != 1);
LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSISYS);
while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSISYS);
LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1);
LL_Init1msTick(8000000);
LL_SetSystemCoreClock(8000000);
}
void APP_ErrorHandler(void)
{
while (1);
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t *file, uint32_t line)
{
while (1);
}
#endif /* USE_FULL_ASSERT */