在使用USART外设HAL库或者LL库例程进行串口接收通信时,如果我们不知道如何使用对方会发多少个字节数据,就很难使用库函数对MCU进行初始化,因为这涉及到一个接收字节数设定的问题。
首先贴一下main函数的初始化程序,开启串口接收中断即可:
int main(void)
{
HAL_Init(); //systick初始化
USART_Config(); //USART初始化
__HAL_UART_ENABLE_IT(&UartHandle, UART_IT_RXNE);//中断接收使能
/*printf重定向发送数据*/
printf("Hello world!");
while(1)
{
}
}
随后在中断源文件it.c中重写中断服务函数,若MCU接收到一个字节数据,就会触发中断,我们在中断函数中判断接收标志,标志置起就把DR寄存器的数据读到buffer里面,索引自增。随后为了易于观察现象,可以把接收到的数据发送回去。解析接收数据,就只需要读接收buffer就可以了。
void USART2_IRQHandler(void)
{
uint32_t isrflags = READ_REG((&UartHandle)->Instance->SR);
if ((isrflags & USART_SR_RXNE) != RESET)//接收标志
{
aRxBuffer[cRxIndex] = (&UartHandle)->Instance->DR;
HAL_UART_Transmit_IT(&UartHandle, aRxBuffer + cRxIndex, 1);//将接收的数据回传回去
if(cRxIndex == 120) cRxIndex = 0;//超过Buffer 大小,重置索引
else cRxIndex++;
}
else //发送
{
HAL_UART_IRQHandler(&UartHandle);
}
}
贴一下usart配置程序:
void USART_Config(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
//====================
//USART2初始化
//====================
__HAL_RCC_USART2_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
UartHandle.Instance = USART2;
UartHandle.Init.BaudRate = 115200;
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;
if(HAL_UART_Init(&UartHandle) != HAL_OK)
{
Error_Handler();
}
/**USART2 GPIO Configuration
PA0 ------> USART2_TX
PA1 ------> USART2_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_USART2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* 使能NVIC */
HAL_NVIC_SetPriority(USART2_IRQn,0,1);
HAL_NVIC_EnableIRQ(USART2_IRQn );
}
最后说一下串口发送printf重定向,只需要重写这个函数,内部就是调用一个串口发送函数,就能使用printf发送函数发送串口数据了。
int fputc(int ch, FILE *f)
{
/* Send a byte to USART */
HAL_UART_Transmit(&UartHandle, (uint8_t *)&ch, 1,1000);
return (ch);
}
完结撒花✿✿ヽ(°▽°)ノ✿