1. 初始化函数不变
void MX_USART6_UART_Init(void)
{
huart6.Instance = USART6;
huart6.Init.BaudRate = 115200;
huart6.Init.WordLength = UART_WORDLENGTH_8B;
huart6.Init.StopBits = UART_STOPBITS_1;
huart6.Init.Parity = UART_PARITY_NONE;
huart6.Init.Mode = UART_MODE_TX_RX;
huart6.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart6.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart6) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
2. MspInit函数中设置中断优先级,开启中断
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(uartHandle->Instance==USART6)
{
/* USER CODE BEGIN USART6_MspInit 0 */
/* USER CODE END USART6_MspInit 0 */
/* USART6 clock enable */
__HAL_RCC_USART6_CLK_ENABLE();
/**USART6 GPIO Configuration
PC6 ------> USART6_TX
PG9 ------> USART6_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF8_USART6;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF8_USART6;
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
/* USER CODE BEGIN USART6_MspInit 1 */
/* USART6 interrupt Init */
HAL_NVIC_SetPriority(USART6_IRQn, 6, 0);
HAL_NVIC_EnableIRQ(USART6_IRQn);
/* Enable the UART Data Register not empty Interrupts */
SET_BIT(uartHandle->Instance->CR1, USART_CR1_RXNEIE);
/* USER CODE END USART6_MspInit 1 */
}
}
3. MspDeInit中关闭中断
void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{
if(uartHandle->Instance==USART6)
{
/* USER CODE BEGIN USART6_MspDeInit 0 */
/* USER CODE END USART6_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART6_CLK_DISABLE();
/**USART6 GPIO Configuration
PC6 ------> USART6_TX
PG9 ------> USART6_RX
*/
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_6);
HAL_GPIO_DeInit(GPIOG, GPIO_PIN_9);
/* USER CODE BEGIN USART6_MspDeInit 1 */
/* USART6 interrupt Deinit */
HAL_NVIC_DisableIRQ(USART6_IRQn);
/* Disable the UART RXNE interrupt*/
CLEAR_BIT(uartHandle->Instance->CR1, USART_CR1_RXNEIE);
/* USER CODE END USART6_MspDeInit 1 */
}
}
4. 重写串口中断服务函数
void USART6_IRQHandler(void)
{
uint32_t isrflags = READ_REG(huart6.Instance->SR);
uint32_t cr1its = READ_REG(huart6.Instance->CR1);
uint32_t errorflags = 0x00U;
uint8_t dump;
errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE)); //检查所有错误,有错误就丢弃
if(errorflags == RESET)
{
/* UART in mode Receiver -------------------------------------------------*/
if(((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
{
Rx_Buf[0] = (uint8_t)(huart6.Instance->DR & (uint8_t)0x00FF);
}
}
else
{
dump = (uint8_t)(huart6.Instance->DR & (uint8_t)0x00FF); //发生错误,数据丢弃
}
}
5. 测试串口各种错误
溢出错误
(RDR内容未及时读出,RDR内容将不会丢失。读USART_DR寄存器仍能得到先前的数据。USART_DR中数据有效。
噪声错误(开始信号、数据3次采样值不同)、帧错误(没接收到STOP信号),
无效数据从移位寄存器传送到USART_DR寄存器。USART_DR中数据无效。
极性错误
该错误一定要Parity = UART_PARITY_EVEN或者Parity = UART_PARITY_ODD。这样才能使能该错误。
读完SR寄存器,哪些错误标志位会都清零。
5.1 测试极性错误(PE)
以115200发送为例
先设置huart6.Init.Parity = UART_PARITY_EVEN;
再按下图设置发送“0x31”
5.2 测试帧错误(FE)
按下图设置
发送“0x31”
5.3 测试溢出错误(ORE)
连续发送“0x31 0x32”
5.4 噪声错误
暂时不测试。