STM32
直播中

李欢

7年用户 1087经验值
私信 关注
[问答]

stm32H750VB LL库串口DMA空闲中断接收不到数据的原因?怎么解决?

//串口的初始化
void MX_USART1_UART_Init(void)
{

  /* USER CODE BEGIN USART1_Init 0 */

  /* USER CODE END USART1_Init 0 */

  LL_USART_InitTypeDef USART_InitStruct = {0};

  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

  LL_RCC_SetUSARTClockSource(LL_RCC_USART16_CLKSOURCE_PCLK2);

  /* Peripheral clock enable */
  LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1);

  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1);

  LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOA);
  /**USART1 GPIO Configuration
  PA9   ------> USART1_TX
  PA10   ------> USART1_RX
  */
  GPIO_InitStruct.Pin = LL_GPIO_PIN_9|LL_GPIO_PIN_10;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_7;
  LL_GPIO_Init(GPIOA,  GPIO_InitStruct);

  /* USART1 DMA Init */

  /* USART1_RX Init */
  LL_DMA_DisableStream(DMA1, LL_DMA_STREAM_0);

  LL_DMA_SetPeriphAddress(DMA1, LL_DMA_STREAM_0, LL_USART_DMA_GetRegAddr(USART1, LL_USART_DMA_REG_DATA_RECEIVE));
  LL_DMA_SetMemoryAddress(DMA1, LL_DMA_STREAM_0, buffer);
  LL_DMA_SetDataLength(DMA1, LL_DMA_STREAM_0, 256);

  LL_DMA_SetPeriphRequest(DMA1, LL_DMA_STREAM_0, LL_DMAMUX1_REQ_USART1_RX);

  LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_STREAM_0, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);

  LL_DMA_SetStreamPriorityLevel(DMA1, LL_DMA_STREAM_0, LL_DMA_PRIORITY_LOW);

  LL_DMA_SetMode(DMA1, LL_DMA_STREAM_0, LL_DMA_MODE_NORMAL);

  LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_STREAM_0, LL_DMA_PERIPH_NOINCREMENT);

  LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_STREAM_0, LL_DMA_MEMORY_INCREMENT);

  LL_DMA_SetPeriphSize(DMA1, LL_DMA_STREAM_0, LL_DMA_PDATAALIGN_BYTE);

  LL_DMA_SetMemorySize(DMA1, LL_DMA_STREAM_0, LL_DMA_MDATAALIGN_BYTE);

  LL_DMA_DisableFifoMode(DMA1, LL_DMA_STREAM_0);

  LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_0);

  /* USART1 interrupt Init */
  NVIC_SetPriority(USART1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
  NVIC_EnableIRQ(USART1_IRQn);

  /* USER CODE BEGIN USART1_Init 1 */

  /* USER CODE END USART1_Init 1 */
  USART_InitStruct.PrescalerValue = LL_USART_PRESCALER_DIV1;
  USART_InitStruct.BaudRate = 115200;
  USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B;
  USART_InitStruct.StopBits = LL_USART_STOPBITS_1;
  USART_InitStruct.Parity = LL_USART_PARITY_NONE;
  USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX;
  USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
  USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16;
  LL_USART_Init(USART1,  USART_InitStruct);
  LL_USART_SetTXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_8);
  LL_USART_SetRXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_8);
  LL_USART_DisableFIFO(USART1);
  LL_USART_ConfigAsyncMode(USART1);

  /* USER CODE BEGIN WKUPType USART1 */

  LL_USART_ClearFlag_IDLE(USART1);
  LL_USART_EnableIT_RXNE_RXFNE(USART1);
  LL_USART_EnableIT_IDLE(USART1);
  LL_USART_EnableDMAReq_RX(USART1);
  /* USER CODE END WKUPType USART1 */

  LL_USART_Enable(USART1);

  /* Polling USART1 initialisation */
  while((!(LL_USART_IsActiveFlag_TEACK(USART1))) || (!(LL_USART_IsActiveFlag_REACK(USART1))))
  {
  }
  /* USER CODE BEGIN USART1_Init 2 */


  /* USER CODE END USART1_Init 2 */

}


tips:buffer运行在0x24000000后, 也没有开启cache,我之前在f103上有做过,按照芯片大概流程初始化后buffer一直为空。但是用HAL库的话可以正常接收数据,求大佬指导下!


回帖(1)

于扬

2024-3-21 15:31:20
空闲中断本身与数据收发无关,你的问题核心是使用LL库组织代码时没法实现UART的DMA传输吧。


你先用CubeMx配置完成后,生成基于LL库的初始化代码。然后像下面一样组织用户代码,实现UART的
DMA收发是没有问题的,注意代码顺序。我使用H7芯片做了测试,可以正常运行。


  /* Enable DMA RX Interrupt */  LL_USART_EnableDMAReq_RX(USART1);


  /* Enable DMA TX Interrupt */
  LL_USART_EnableDMAReq_TX(USART1);


      
LL_DMA_ConfigAddresses(DMA1, LL_DMA_STREAM_0,
                         LL_USART_DMA_GetRegAddr(USART1, LL_USART_DMA_REG_DATA_RECEIVE),
           (uint32_t)RxBuffer,                                                                     LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
                     
                                                                        
  LL_DMA_SetDataLength(DMA1, LL_DMA_STREAM_0, Length_RX);
      
      
       LL_DMA_ConfigAddresses(DMA1, LL_DMA_STREAM_1,
                         (uint32_t)TxBuffer,
                         LL_USART_DMA_GetRegAddr(USART1, LL_USART_DMA_REG_DATA_TRANSMIT),
           LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
                     
                                                                        
  LL_DMA_SetDataLength(DMA1, LL_DMA_STREAM_1, Length_TX);
      
      
  /* Enable DMA Channel Rx */     
  LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_0);


  /* Enable DMA Channel Tx */
  LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_1);



至于,空闲中断是另外回事。开启了空闲中断,UART接收发生空闲时自然会进入中断。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分