最近使用stm32f743VIT6 DMA通过空闲中断接收不定长度的字节。有个现象很奇怪,我接收GPS下发的数据的时候,使用的串口2的DMA的空闲中断来接收,(一般情况下GPS发出来的数据都是每秒钟一帧,美帧数据大约几百个字节),要么接收到1个字节就空闲中断了,要么就根本接收不到。
然后我换成用PC机模拟GPS通过USB转TTL 的线下发数据到串口2,这个时候能完整无误的接收到数据,无论下发的数据字节有多少都能 完整无误的接收到。 我把我的串口的配置和中断处理贴出来,希望有知道原因的大牛指点指点。谢谢
说明一下, 以上我做实验都是通过串口2接收的数据,然后用串口3转发接收的数据到PC机上来观察的。
以下是 串口1 和串口2和串口3 的初始化配置:
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
static DMA_HandleTypeDef U1hdma_tx;
static DMA_HandleTypeDef U1hdma_rx;
static DMA_HandleTypeDef U2hdma_tx;
static DMA_HandleTypeDef U2hdma_rx;
static DMA_HandleTypeDef U3hdma_tx;
static DMA_HandleTypeDef U3hdma_rx;
GPIO_InitTypeDef GPIO_InitStruct;
RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit;
if(huart->Instance==USART1)
{
USARTx_TX_GPIO_CLK_ENABLE();
RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART16;
RCC_PeriphClkInit.Usart16ClockSelection = RCC_USART16CLKSOURCE_D2PCLK2;
HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit);
USARTx_CLK_ENABLE();
DMAx_CLK_ENABLE();
GPIO_InitStruct.Pin = USARTx_TX_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = USARTx_TX_AF;
HAL_GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStruct);
GPIO_InitStruct.Pin = USARTx_RX_PIN;
GPIO_InitStruct.Alternate = USARTx_RX_AF;
HAL_GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStruct);
U1hdma_tx.Instance = USARTx_TX_DMA_STREAM;
U1hdma_tx.Init.Request = USARTx_TX_DMA_CHANNEL;
U1hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
U1hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE;
U1hdma_tx.Init.MemInc = DMA_MINC_ENABLE;
U1hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
U1hdma_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
U1hdma_tx.Init.Mode = DMA_NORMAL;
U1hdma_tx.Init.Priority = DMA_PRIORITY_LOW;
U1hdma_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
U1hdma_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
U1hdma_tx.Init.MemBurst = DMA_MBURST_INC4;
U1hdma_tx.Init.PeriphBurst = DMA_PBURST_INC4;
HAL_DMA_Init(&U1hdma_tx);
__HAL_LINKDMA(huart, hdmatx, U1hdma_tx);
HAL_NVIC_SetPriority(USARTx_DMA_TX_IRQn, 3, 1);
HAL_NVIC_EnableIRQ(USARTx_DMA_TX_IRQn);
HAL_NVIC_SetPriority(USARTx_IRQn, 3, 1);
HAL_NVIC_EnableIRQ(USARTx_IRQn);
}
if(huart->Instance==USART2)
{
UsartG_RX_GPIO_CLK_ENABLE();
RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;
RCC_PeriphClkInit.Usart234578ClockSelection = RCC_USART2CLKSOURCE_D2PCLK1;
HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit);
__HAL_RCC_USART2_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_InitStruct.Pin = UsartG_TX_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = UsartG_TX_AF;
HAL_GPIO_Init(UsartG_TX_GPIO_PORT, &GPIO_InitStruct);
GPIO_InitStruct.Pin = UsartG_RX_PIN;
GPIO_InitStruct.Alternate = UsartG_RX_AF;
HAL_GPIO_Init(UsartG_RX_GPIO_PORT, &GPIO_InitStruct);
U2hdma_rx.Instance = UsartG_RX_DMA_STREAM;
U2hdma_rx.Init.Request = UsartG_RX_DMA_CHANNEL;
U2hdma_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
U2hdma_rx.Init.PeriphInc = DMA_PINC_DISABLE;
U2hdma_rx.Init.MemInc = DMA_MINC_ENABLE;
U2hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
U2hdma_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
U2hdma_rx.Init.Mode = DMA_NORMAL;
U2hdma_rx.Init.Priority = DMA_PRIORITY_HIGH;
U2hdma_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
U2hdma_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
U2hdma_rx.Init.MemBurst = DMA_MBURST_INC4;
U2hdma_rx.Init.PeriphBurst = DMA_PBURST_INC4;
HAL_DMA_Init(&U2hdma_rx);
__HAL_LINKDMA(huart, hdmarx, U2hdma_rx);
HAL_NVIC_SetPriority(UsartG_DMA_RX_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(UsartG_DMA_RX_IRQn);
HAL_NVIC_SetPriority(UsartG_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(UsartG_IRQn);
}
if(huart->Instance==USART3)
{
UsartX_TX_GPIO_CLK_ENABLE();
RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART3;
RCC_PeriphClkInit.Usart234578ClockSelection = RCC_USART3CLKSOURCE_D2PCLK1;
HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit);
UsartX_CLK_ENABLE();
DMAX_CLK_ENABLE();
GPIO_InitStruct.Pin = UsartX_TX_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = UsartX_TX_AF;
HAL_GPIO_Init(UsartX_TX_GPIO_PORT, &GPIO_InitStruct);
U3hdma_tx.Instance = UsartX_TX_DMA_STREAM;
U3hdma_tx.Init.Request = UsartX_TX_DMA_CHANNEL;
U3hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
U3hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE;
U3hdma_tx.Init.MemInc = DMA_MINC_ENABLE;
U3hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
U3hdma_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
U3hdma_tx.Init.Mode = DMA_NORMAL;
U3hdma_tx.Init.Priority = DMA_PRIORITY_LOW;
U3hdma_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
U3hdma_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
U3hdma_tx.Init.MemBurst = DMA_MBURST_INC4;
U3hdma_tx.Init.PeriphBurst = DMA_PBURST_INC4;
HAL_DMA_Init(&U3hdma_tx);
__HAL_LINKDMA(huart, hdmatx, U3hdma_tx);
HAL_NVIC_SetPriority(UsartX_DMA_TX_IRQn, 1, 1);
HAL_NVIC_EnableIRQ(UsartX_DMA_TX_IRQn);
HAL_NVIC_SetPriority(UsartX_IRQn, 1, 1);
HAL_NVIC_EnableIRQ(UsartX_IRQn);
}
}
以下是串口2的中断处理:
注: GPS_UartHandle 是处理处理GPS 接收数据的一个Handle ,也就是串口2
void Usart2_IRQHandler(void)
{
uint32_t tmp_flag = 0;
uint32_t temp;
//HAL_UART_IRQHandler(&GPS_UartHandle);
tmp_flag = __HAL_UART_GET_FLAG(&GPS_UartHandle,UART_FLAG_IDLE); // 这里是获取空闲标志
if((tmp_flag ==SET))
{
__HAL_UART_CLEAR_IDLEFLAG(&GPS_UartHandle); // 清除空闲标志
temp=__HAL_DMA_GET_COUNTER(GPS_UartHandle.hdmarx); // 获取接收缓存的剩余字节数
HAL_UART_DMAStop(&GPS_UartHandle); /// 停止 串口2的DMA接收
rx_len = (RXBUFFERSIZE - temp); // 计算 接收到的数据长度
recv_end_flag = 1; // 置位接收完成标志,在main中提示处理接收到的数据
temp =0;
}
__HAL_UART_CLEAR_IT(&GPS_UartHandle,UART_CLEAR_PEF // 清除 其他的中断标志 等
|UART_CLEAR_FEF
|UART_CLEAR_NEF
|UART_CLEAR_OREF
//|UART_CLEAR_IDLEF
|UART_CLEAR_TCF
|UART_CLEAR_LBDF
|UART_CLEAR_CTSF
|UART_CLEAR_RTOF
|UART_CLEAR_WUF
|UART_CLEAR_CMF
|UART_CLEAR_TXFECF);
}
恳请 知道原因的大牛指点一二,谢谢
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
主要是百度了有STM32F743的例子,可惜有的连数据都收不到。原子哥你有合适的例程吗? 发一个, 我的40943596@qq.com
一周热门 更多>