STM32/STM8技术william hill官网
直播中

杨秀英

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

STM32 HAL UART发送DMA问题

在为包含FT2232H UART < - > USB转换器的自定义STM32F7板设置项目后,我在发送(和接收数据)时遇到了多个问题。我使用的代码主要由CubeMX生成,位于帖子的末尾。
首先,根据数据表,FT2232H和STM32F7的波特率至少应为12M波特,我无法让波特率高于标准115200。对于FT2232H,我正在工作,因为我从终端(USB端)发送一些字符,并在我短接FT2232H输出端的RX和TX引脚时收回了字符。
其次是我不能连续多次调用sendUART()函数,为什么DMA Fifo不用于存储我想要发送的东西?
还有什么方法可以回显所有收到的数据,但是利用了fifo,这样当没有及时轮询数据时,没有数据丢失?
  1. void MX_UART4_Init(void)
  2. {

  3.   huart4.Instance = UART4;
  4.   huart4.Init.BaudRate = 115200;
  5.   huart4.Init.WordLength = UART_WORDLENGTH_8B;
  6.   huart4.Init.StopBits = UART_STOPBITS_1;
  7.   huart4.Init.Parity = UART_PARITY_NONE;
  8.   huart4.Init.Mode = UART_MODE_TX_RX;
  9.   huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  10.   huart4.Init.OverSampling = UART_OVERSAMPLING_16;
  11.   huart4.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  12.   huart4.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  13.   if (HAL_UART_Init(&huart4) != HAL_OK)
  14.   {
  15.     _Error_Handler(__FILE__, __LINE__);
  16.   }

  17. }

  18. void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
  19. {

  20.   GPIO_InitTypeDef GPIO_InitStruct;
  21.   if(uartHandle->Instance==UART4)
  22.   {
  23.   /* USER CODE BEGIN UART4_MspInit 0 */

  24.   /* USER CODE END UART4_MspInit 0 */
  25.     /* UART4 clock enable */
  26.     __HAL_RCC_UART4_CLK_ENABLE();

  27.     /**UART4 GPIO Configuration   
  28.     PA0/WKUP     ------> UART4_TX
  29.     PA1     ------> UART4_RX
  30.     */
  31.     GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
  32.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  33.     GPIO_InitStruct.Pull = GPIO_PULLUP;
  34.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  35.     GPIO_InitStruct.Alternate = GPIO_AF8_UART4;
  36.     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  37.     /* UART4 DMA Init */
  38.     /* UART4_TX Init */
  39.     hdma_uart4_tx.Instance = DMA1_Stream4;
  40.     hdma_uart4_tx.Init.Channel = DMA_CHANNEL_4;
  41.     hdma_uart4_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
  42.     hdma_uart4_tx.Init.PeriphInc = DMA_PINC_DISABLE;
  43.     hdma_uart4_tx.Init.MemInc = DMA_MINC_ENABLE;
  44.     hdma_uart4_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
  45.     hdma_uart4_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
  46.     hdma_uart4_tx.Init.Mode = DMA_NORMAL;
  47.     hdma_uart4_tx.Init.Priority = DMA_PRIORITY_MEDIUM;
  48.     hdma_uart4_tx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
  49.     hdma_uart4_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
  50.     hdma_uart4_tx.Init.MemBurst = DMA_MBURST_SINGLE;
  51.     hdma_uart4_tx.Init.PeriphBurst = DMA_PBURST_SINGLE;
  52.     if (HAL_DMA_Init(&hdma_uart4_tx) != HAL_OK)
  53.     {
  54.       _Error_Handler(__FILE__, __LINE__);
  55.     }

  56.     __HAL_LINKDMA(uartHandle,hdmatx,hdma_uart4_tx);

  57.     /* UART4_RX Init */
  58.     hdma_uart4_rx.Instance = DMA1_Stream2;
  59.     hdma_uart4_rx.Init.Channel = DMA_CHANNEL_4;
  60.     hdma_uart4_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
  61.     hdma_uart4_rx.Init.PeriphInc = DMA_PINC_DISABLE;
  62.     hdma_uart4_rx.Init.MemInc = DMA_MINC_ENABLE;
  63.     hdma_uart4_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
  64.     hdma_uart4_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
  65.     hdma_uart4_rx.Init.Mode = DMA_NORMAL;
  66.     hdma_uart4_rx.Init.Priority = DMA_PRIORITY_MEDIUM;
  67.     hdma_uart4_rx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
  68.     hdma_uart4_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
  69.     hdma_uart4_rx.Init.MemBurst = DMA_MBURST_SINGLE;
  70.     hdma_uart4_rx.Init.PeriphBurst = DMA_PBURST_SINGLE;
  71.     if (HAL_DMA_Init(&hdma_uart4_rx) != HAL_OK)
  72.     {
  73.       _Error_Handler(__FILE__, __LINE__);
  74.     }

  75.     __HAL_LINKDMA(uartHandle,hdmarx,hdma_uart4_rx);

  76.   /* USER CODE BEGIN UART4_MspInit 1 */

  77.   /* USER CODE END UART4_MspInit 1 */
  78.   }
  79. }

  80. void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
  81. {

  82.   if(uartHandle->Instance==UART4)
  83.   {
  84.   /* USER CODE BEGIN UART4_MspDeInit 0 */

  85.   /* USER CODE END UART4_MspDeInit 0 */
  86.     /* Peripheral clock disable */
  87.     __HAL_RCC_UART4_CLK_DISABLE();

  88.     /**UART4 GPIO Configuration   
  89.     PA0/WKUP     ------> UART4_TX
  90.     PA1     ------> UART4_RX
  91.     */
  92.     HAL_GPIO_DeInit(GPIOA, GPIO_PIN_0|GPIO_PIN_1);

  93.     /* UART4 DMA DeInit */
  94.     HAL_DMA_DeInit(uartHandle->hdmatx);
  95.     HAL_DMA_DeInit(uartHandle->hdmarx);
  96.   /* USER CODE BEGIN UART4_MspDeInit 1 */

  97.   /* USER CODE END UART4_MspDeInit 1 */
  98.   }
  99. }

  100. /* USER CODE BEGIN 1 */
  101. void sendUART(char msg[]){
  102.     //HAL_UART_Transmit(&huart4,(uint8_t *) msg, strlen(msg),10000);
  103.     HAL_UART_Transmit_DMA(&huart4,(uint8_t *) msg, strlen(msg));
  104. }

  105. void echo(){
  106.     if(HAL_UART_Receive_DMA(&huart4, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK){}
  107.     else if(HAL_UART_Transmit_DMA(&huart4, (uint8_t*)aRxBuffer, RXBUFFERSIZE)!= HAL_OK){
  108.     }
  109. }


回帖(3)

李鑫

2018-9-27 14:17:31
硬件支持高达27 Mbit的速度(嗯,你没有告诉你的部件号,我正在看F756数据表),但据说stm32f7xx_hal_uart.h,HAL不会接受高于9M的速度
#define IS_UART_BAUDRATE(BAUDRATE) ((BAUDRATE) < 9000001)
此外,它取决于系统时钟速度,在默认配置中,当您不触摸STM32CubeMX中的时钟配置选项卡时,一切都在16 MHz内部HSI时钟上运行。这意味着在您使用时最多为1 MbitUART_OVERSAMPLING_16,如果切换到最多则为两倍UART_OVERSAMPLING_8(但之后您将失去噪声检测)。
虽然有一个16字节的DMA FIFO,但软件无法访问它。没有办法只为正在进行的DMA传输添加更多数据。HAL什么都不做,只是从调用者提供的缓冲区地址开始DMA传输。
您必须等到传输完成或暂停DMA,然后等待FIFO为空。您当然可以自己分配缓冲区,在数据到来时添加数据,并在完成后重新启动DMA并在缓冲区中有新数据。
在我看来,你不能在每个收到的角色上同时拥有DMA和中断。至少,ISR状态寄存器值是无用的,中断处理程序将无法决定做什么。读它甚至可能会干扰DMA传输。因此,您必须选择一个。
使用DMA将数据放入缓冲区(或两个),然后可以在空闲循环或定时器中断中定期轮询传输计数器。没有立即响应,但它可能根本不重要,因为USB接口也会引起一些延迟。
举报

杨秀英

2018-9-27 14:18:05
感谢你的回答。我配置了时钟,UART在200Mhz SYSCLK上运行,因此根据CubeMX应该有理论上的最大值。波特率为12.5M,过采样设置为16个样本。
举报

刘桂英

2018-9-27 14:18:37
如果你将UART时钟源设置为200MHz SYSCLK(你在哪里做?它不在上面的代码中),那么你得到12.5M,对,但这不是12M,FTDI部分正在运行。当其他一切都很完美时(控制器不是太热,信号很清晰,没有噪声),它有4.167%的差异,再加上它可以工作的HSI振荡器的不准确性,但是我试用192 MHz以获得更好的匹配。
举报

更多回帖

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