【记录】STM32串口测试
程序员文章站
2024-02-22 18:40:46
...
测试环境
正点原子战舰STM32F767
STM32串口
中断收发
为了验证硬件的正确性,最简单的方法是接收串口工具的数据,然后将接收到的数据发送
STM32串口-接收定长数据
uint8_t g_u8SndBuf[UART_LEN] = "USART1 Send test\n\r";
uint8_t g_u8RcvBuf[UART_LEN] = {0};
void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
//for test
HAL_UART_Transmit_IT(&huart1, g_u8SndBuf, sizeof(g_u8SndBuf));
HAL_UART_Receive_IT(&huart1, g_u8RcvBuf, 10); //to receive fixed lenght of data
}
void USART1_IRQHandler(void)
{
HAL_UART_IRQHandler(&huart1);
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance==USART1)
{
HAL_UART_Transmit_IT(&huart1, g_u8RcvBuf, sizeof(g_u8RcvBuf));
HAL_UART_Receive_IT(&huart1, g_u8RcvBuf, 10); //enable receive interrupt again
}
}
STM32串口-接收不定长数据
1. 定时接收
…
2. 固定结束符
当接收到固定字符(如:0x0D),认为接收完成
#define UART_LEN 128
UART_HandleTypeDef huart1;
uint8_t *s_pbSnd = NULL;
uint8_t *s_pbRcv = NULL;
uint16_t s_wSndCnt = 0;
uint16_t s_wSndIndex = 0;
uint16_t s_wRcvIndex = 0;
uint8_t s_bRcvDone = 0;
void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
/* Enable the UART RXNE interrupt*/
SET_BIT(huart1.Instance->CR1, USART_CR1_RXNEIE);
}
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(uartHandle->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspInit 0 */
/* USER CODE END USART1_MspInit 0 */
/* USART1 clock enable */
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART1 GPIO Configuration
PA9 ------> USART1_TX
PA10 ------> USART1_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USART1 interrupt Init */
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspInit 1 */
/* USER CODE END USART1_MspInit 1 */
}
}
void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{
if(uartHandle->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspDeInit 0 */
/* USER CODE END USART1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART1_CLK_DISABLE();
/**USART1 GPIO Configuration
PA9 ------> USART1_TX
PA10 ------> USART1_RX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
/* USART1 interrupt Deinit */
HAL_NVIC_DisableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspDeInit 1 */
/* USER CODE END USART1_MspDeInit 1 */
}
}
/**
* @brief This function handles USART1 global interrupt.
*/
void USART1_IRQHandler(void)
{
uint32_t isrflags = READ_REG(huart1.Instance->ISR);
uint32_t cr1its = READ_REG(huart1.Instance->CR1);
uint32_t cr2its = READ_REG(huart1.Instance->CR2);
uint8_t u8RcvChar = 0;
/* UART in mode Receiver ---------------------------------------------------*/
if ((isrflags & USART_ISR_RXNE) && (cr1its & USART_CR1_RXNEIE))
{
u8RcvChar = (uint8_t)(huart1.Instance->RDR & 0xFF);
s_pbRcv[s_wRcvIndex++] = u8RcvChar;
if (u8RcvChar == 0x0D)
{
s_bRcvDone = 1;
//isr_evt_set(RECV_READY_EVT)
}
}
else
{
/* UART in mode Transmitter ------------------------------------------------*/
if((isrflags & USART_ISR_TXE) && (cr1its & USART_CR1_TXEIE))
{
if (s_wSndCnt == 0)
{
/* Disable the UART Transmit Data Register Empty Interrupt */
CLEAR_BIT(huart1.Instance->CR1, USART_CR1_TXEIE);
/* Clear the UART Transmit Complete Interrupt Flag */
__HAL_UART_CLEAR_IT(&huart1, UART_CLEAR_TCF);
/* Enable the UART Transmit Complete Interrupt */
SET_BIT(huart1.Instance->CR1, USART_CR1_TCIE);
}
else
{
huart1.Instance->TDR = s_pbSnd[s_wSndIndex++];
s_wSndCnt--;
}
}
/* UART in mode Transmitter (transmission end) -----------------------------*/
if((isrflags & USART_ISR_TC) && (cr1its & USART_CR1_TCIE))
{
/* Clear the UART Transmit Complete Interrupt Flag */
__HAL_UART_CLEAR_IT(&huart1, UART_CLEAR_TCF);
/* Disable the UART Transmit Complete Interrupt */
CLEAR_BIT(huart1.Instance->CR1, USART_CR1_TCIE);
//isr_evt_set(SEND_READY_EVT)
}
}
}
int8_t USART1_Snd(uint8_t* pbSndBuf, uint16_t wSndCnt)
{
int8_t ret = 0;
if ((pbSndBuf == NULL) && (wSndCnt == 0))
{
return -1;
}
s_pbSnd = pbSndBuf;
s_wSndCnt = wSndCnt;
s_wSndIndex = 0;
/* Enable the UART Transmit Data Register Empty Interrupt */
SET_BIT(huart1.Instance->CR1, USART_CR1_TXEIE);
return ret;
}
int8_t USART1_Rcv(uint8_t* pbRcvBuf, uint16_t *pwRcvCnt, uint16_t wResponseTimeout)
{
int8_t ret = 0;
s_bRcvDone = 0;
s_wRcvIndex = 0;
s_pbRcv = pbRcvBuf;
//os_evt_wait_or(RECV_READY_EVT,WAITFOREVER);
*pwRcvCnt = s_wRcvIndex;
return ret;
}
void USART1_Test(void)
{
static uint8_t s_bInit = 0;
static uint8_t s_bSndBuf[UART_LEN] = "USART1 Send test!!!\n\r";
static uint8_t s_bRcvBuf[UART_LEN] = {0};
uint16_t wRcvCnt = 0;
if (s_bInit == 0)
{
USART1_Rcv(s_bRcvBuf, &wRcvCnt, 1000);
s_bInit = 1;
}
if (s_bRcvDone == 1)
{
memcpy(s_bSndBuf, s_bRcvBuf, s_wRcvIndex);
USART1_Snd(s_bSndBuf, s_wRcvIndex);
USART1_Rcv(s_bRcvBuf, &wRcvCnt, 1000);
HAL_Delay(1);
}
}
3. Idle中断
当检测到空闲状态时,认为接收完成
void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
/* Enable the UART RXNE interrupt*/
SET_BIT(huart1.Instance->CR1, USART_CR1_RXNEIE);
/* Enable IDLE interrupt, as the end of frame*/
SET_BIT(huart1.Instance->CR1, USART_CR1_IDLEIE);
}
void USART1_IRQHandler(void)
{
uint32_t isrflags = READ_REG(huart1.Instance->ISR);
uint32_t cr1its = READ_REG(huart1.Instance->CR1);
uint32_t cr2its = READ_REG(huart1.Instance->CR2);
uint8_t u8RcvChar = 0;
/* UART in mode Receiver ---------------------------------------------------*/
if ((isrflags & USART_ISR_RXNE) && (cr1its & USART_CR1_RXNEIE))
{
u8RcvChar = (uint8_t)(huart1.Instance->RDR & 0xFF);
s_pbRcv[s_wRcvIndex++] = u8RcvChar;
}
/* UART IDLE Interrupt ---------------------------------------------------*/
else if (((isrflags & USART_ISR_IDLE) != RESET) && ((cr1its & USART_CR1_IDLEIE) != RESET))
{
/* Clear the UART Idle Interrupt Flag */
__HAL_UART_CLEAR_IT(&huart1, UART_CLEAR_IDLEF);
s_bRcvDone = 1;
//isr_evt_set(RECV_READY_EVT)
}
else
{
/* UART in mode Transmitter ------------------------------------------------*/
if((isrflags & USART_ISR_TXE) && (cr1its & USART_CR1_TXEIE))
{
if (s_wSndCnt == 0)
{
/* Disable the UART Transmit Data Register Empty Interrupt */
CLEAR_BIT(huart1.Instance->CR1, USART_CR1_TXEIE);
/* Clear the UART Transmit Complete Interrupt Flag */
__HAL_UART_CLEAR_IT(&huart1, UART_CLEAR_TCF);
/* Enable the UART Transmit Complete Interrupt */
SET_BIT(huart1.Instance->CR1, USART_CR1_TCIE);
}
else
{
huart1.Instance->TDR = s_pbSnd[s_wSndIndex++];
s_wSndCnt--;
}
}
/* UART in mode Transmitter (transmission end) -----------------------------*/
if((isrflags & USART_ISR_TC) && (cr1its & USART_CR1_TCIE))
{
/* Clear the UART Transmit Complete Interrupt Flag */
__HAL_UART_CLEAR_IT(&huart1, UART_CLEAR_TCF);
/* Disable the UART Transmit Complete Interrupt */
CLEAR_BIT(huart1.Instance->CR1, USART_CR1_TCIE);
//isr_evt_set(SEND_READY_EVT)
}
}
}
4. RTO中断
接收器超时中断(UART receiver timeout interrupt),当RX线路在RTOR设定的超时时间内,持续处于空闲状态,表示接收完成。RTOR以bit为单位
int8_t USART1_Rcv(uint8_t* pbRcvBuf, uint16_t *pwRcvCnt, uint16_t wResponseTimeout)
{
int8_t ret = 0;
s_bRcvDone = 0;
s_wRcvIndex = 0;
s_pbRcv = pbRcvBuf;
/* Enable the UART RXNE interrupt*/
SET_BIT(huart1.Instance->CR1, USART_CR1_RXNEIE);
// set character time out = 28bit = 2,5 character with 11bit frame format
WRITE_REG(huart1.Instance->RTOR,28);
/* Clear the UART Receiver Timeout Interrupt Flag */
__HAL_UART_CLEAR_IT(&huart1, USART_ICR_RTOCF);
/* Enable the UART Receiver Timeout Interrupt */
SET_BIT(huart1.Instance->CR1, USART_CR1_RTOIE);
SET_BIT(huart1.Instance->CR2, USART_CR2_RTOEN);
//os_evt_wait_or(RECV_READY_EVT,WAITFOREVER);
*pwRcvCnt = s_wRcvIndex;
return ret;
}
void USART1_IRQHandler(void)
{
uint32_t isrflags = READ_REG(huart1.Instance->ISR);
uint32_t cr1its = READ_REG(huart1.Instance->CR1);
uint32_t cr2its = READ_REG(huart1.Instance->CR2);
uint8_t u8RcvChar = 0;
/* UART in mode Receiver ---------------------------------------------------*/
if ((isrflags & USART_ISR_RXNE) && (cr1its & USART_CR1_RXNEIE))
{
u8RcvChar = (uint8_t)(huart1.Instance->RDR & 0xFF);
s_pbRcv[s_wRcvIndex++] = u8RcvChar;
}
/* UART Receiver Timeout Interrupt -----------------------------------------*/
else if ((isrflags & USART_ISR_RTOF) && (cr2its & USART_CR2_RTOEN))
{
/* Clear the UART Receiver Timeout Interrupt Flag */
__HAL_UART_CLEAR_IT(&huart1, UART_CLEAR_OREF);
/* Disable the UART Receiver Timeout Interrupt */
CLEAR_BIT(huart1.Instance->CR1, USART_CR1_RTOIE);
CLEAR_BIT(huart1.Instance->CR2, USART_CR2_RTOEN);
s_bRcvDone = 1;
//isr_evt_set(RECV_READY_EVT)
}
else
{
/* UART in mode Transmitter ---------------------------------------------*/
if((isrflags & USART_ISR_TXE) && (cr1its & USART_CR1_TXEIE))
{
if (s_wSndCnt == 0)
{
/* Disable the UART Transmit Data Register Empty Interrupt */
CLEAR_BIT(huart1.Instance->CR1, USART_CR1_TXEIE);
/* Clear the UART Transmit Complete Interrupt Flag */
__HAL_UART_CLEAR_IT(&huart1, UART_CLEAR_TCF);
/* Enable the UART Transmit Complete Interrupt */
SET_BIT(huart1.Instance->CR1, USART_CR1_TCIE);
}
else
{
huart1.Instance->TDR = s_pbSnd[s_wSndIndex++];
s_wSndCnt--;
}
}
/* UART in mode Transmitter (transmission end) -----------------------------*/
if((isrflags & USART_ISR_TC) && (cr1its & USART_CR1_TCIE))
{
/* Clear the UART Transmit Complete Interrupt Flag */
__HAL_UART_CLEAR_IT(&huart1, UART_CLEAR_TCF);
/* Disable the UART Transmit Complete Interrupt */
CLEAR_BIT(huart1.Instance->CR1, USART_CR1_TCIE);
//isr_evt_set(SEND_READY_EVT)
}
}
}
参考资料
STM32使用HAL库实现串口通讯——理论讲解
STM32CubeMX系列教程5:串行通信(USART)
STM32串口接收不定长数据原理与源程序***
适用于所有STM32单片机的串口不定长接收***
STM32之串口DMA接收不定长数据***
如何判断串口接收完成一帧数据***
STM32 Uart 接收不定长数据***
上一篇: STM32 lwip freeRTOS实现ping
下一篇: stm32f4编码器模式