中级会员
 
- 积分
- 267
- 金钱
- 267
- 注册时间
- 2019-5-16
- 在线时间
- 94 小时
|
10金钱
本帖最后由 BlueCrystal 于 2019-9-4 08:40 编辑
看到别人分享的串口+DMA 空闲中断代码,调试了两天还是不行,只有在DEBUG的时候第一下能接收到数据。
尝试过把串口DMA发送去掉,只留接收部分也还是不行。
有大神能帮忙看看问题在哪里吗?
代码贴在下面:
第一部分:串口+DMA配置
UART_HandleTypeDef UartHandle;
DMA_HandleTypeDef hdma_tx,hdma_rx;
/* Buffer used for transmission :
Size should be a Multiple of cache line size (32 bytes) */
ALIGN_32BYTES (uint8_t TX_BUFFER_UART1[10]);
/* Buffer used for reception :
Size should be a Multiple of cache line size (32 bytes) */
ALIGN_32BYTES (uint8_t RX_BUFFER_UART1[66]);
void DEBUG_USART_DMA_Config(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit;
//开启GPIOA时钟
__HAL_RCC_GPIOA_CLK_ENABLE();
/*开启DMA时钟*/
__HAL_RCC_DMA2_CLK_ENABLE();
/* NVIC configuration for DMA receive complete interrupt (USART1_RX) */
HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);
/* 配置串口1时钟源*/
RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
RCC_PeriphClkInit.Usart16ClockSelection = RCC_USART16CLKSOURCE_D2PCLK2;
HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit);
/* 使能串口1时钟 */
__HAL_RCC_USART1_CLK_ENABLE();
/* 配置Tx引脚为复用功能 */
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* 配置Rx引脚为复用功能 */
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* 配置串DEBUG_USART 模式 */
UartHandle.Instance = USART1;
UartHandle.Init.BaudRate = 19200;
UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
UartHandle.Init.StopBits = UART_STOPBITS_1;
UartHandle.Init.Parity = UART_PARITY_NONE;//无奇偶校验位
UartHandle.Init.Mode = UART_MODE_TX_RX; //收发模式
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE; //无硬件流控
UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
UartHandle.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;
UartHandle.Init.Prescaler = UART_PRESCALER_DIV1;
UartHandle.Init.FIFOMode = UART_FIFOMODE_DISABLE;
UartHandle.Init.TXFIFOThreshold = UART_TXFIFO_THRESHOLD_1_8;
UartHandle.Init.RXFIFOThreshold = UART_RXFIFO_THRESHOLD_1_8;
UartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
HAL_UART_Init(&UartHandle);
/* Configure the DMA handler for reception process */
hdma_rx.Instance = DMA2_Stream1;
/*usart1 rx对应dma2,数据流1*/
hdma_rx.Init.Request = DMA_REQUEST_USART1_RX;
/*方向:从外设到内存*/
hdma_rx.Init.Direction= DMA_PERIPH_TO_MEMORY;
/*外设地址不增*/
hdma_rx.Init.PeriphInc = DMA_PINC_DISABLE;
/*内存地址自增*/
hdma_rx.Init.MemInc = DMA_MINC_ENABLE;
/*外设数据单位*/
hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
/*内存数据单位 8bit*/
hdma_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
/*DMA模式:不断循环*/
hdma_rx.Init.Mode = DMA_NORMAL;
/*优先级:中*/
hdma_rx.Init.Priority = DMA_PRIORITY_MEDIUM;
/*禁用FIFO*/
hdma_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
hdma_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
/*存储器突发传输 1个节拍*/
// hdma_rx.Init.MemBurst = DMA_MBURST_SINGLE;
/*外设突发传输 1个节拍*/
// hdma_rx.Init.PeriphBurst = DMA_PBURST_SINGLE;
/*配置DMA2的数据流7*/
// /* Deinitialize the stream for new transfer */
HAL_DMA_DeInit(&hdma_rx);
/* Configure the DMA stream */
HAL_DMA_Init(&hdma_rx);
/* Associate the DMA handle */
__HAL_LINKDMA(&UartHandle, hdmarx, hdma_rx);
/*开启串口中断 */
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
__HAL_UART_ENABLE_IT(&UartHandle, UART_IT_IDLE);
*开启DMA接收*/
HAL_UART_Receive_DMA(&UartHandle, RX_BUFFER_UART1, 66);
__HAL_UART_DISABLE_IT(&UartHandle, UART_IT_ERR);
__HAL_UART_DISABLE_IT(&UartHandle, UART_IT_PE);
}
第一部分:中断
/**
1. @brief Stop the DMA Receive.
2. @param huart: UART handle.
3. @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_DMAStopRx(UART_HandleTypeDef *huart)
{
/* Stop UART DMA Rx request if ongoing */
if ((huart->RxState == HAL_UART_STATE_BUSY_RX) &&(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)))
{
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
/* Abort the UART DMA Rx channel */
if(huart->hdmarx != NULL)
{
HAL_DMA_Abort(huart->hdmarx);
}
/* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
/* At end of Rx process, restore huart->RxState to Ready */
huart->RxState = HAL_UART_STATE_READY;
}
return HAL_OK;
}
void DMA2_Stream1_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Stream1_IRQn 0 */
/* USER CODE END DMA1_Stream1_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_rx);
/* USER CODE BEGIN DMA1_Stream1_IRQn 1 */
/* USER CODE END DMA1_Stream1_IRQn 1 */
}
void USART1_IRQHandler(void)
{
HAL_UART_IRQHandler(&UartHandle); //调用HAL库中断处理公用函数
/* USER CODE BEGIN UART1_IRQn 1 */
uint32_t isrflags = READ_REG(UartHandle.Instance->ISR);
uint32_t cr1its = READ_REG(UartHandle.Instance->CR1);
if(((isrflags & USART_ISR_IDLE) != RESET) && ((cr1its & USART_CR1_IDLEIE) != RESET))
{
__HAL_UART_CLEAR_IDLEFLAG(&UartHandle);
uint32_t _len_dmarev = MAX_RX_DATA_UART1 - __HAL_DMA_GET_COUNTER(UartHandle.hdmarx);
if(_len_dmarev)
{
HAL_UART_DMAStopRx(&UartHandle);
HAL_UART_Receive_DMA(&UartHandle, RX_BUFFER_UART1, 66);
__HAL_UART_DISABLE_IT(&UartHandle, UART_IT_ERR);
__HAL_UART_DISABLE_IT(&UartHandle, UART_IT_PE);
}
else
{
READ_REG(UartHandle.Instance->RDR);
__HAL_UART_CLEAR_OREFLAG(&UartHandle);
}
}
/* USER CODE END UART1_IRQn 1 */
}
第三部分:main初始化
int main(void)
{
Cache_Enable(); //打开L1-Cache
HAL_Init(); //初始化HAL库
Stm32_Clock_Init(160,5,2,2); //设置时钟,400Mhz
delay_init(400);
Global_GPIO_Config();
DEBUG_USART_DMA_Config();
while(1)
{
}
}
|
最佳答案
查看完整内容[请看2#楼]
刚好搞过H7的串口DMAhttp://www.openedv.com/forum.php?mod=viewthread&tid=293299&extra=
|