硬汉嵌入式论坛

 找回密码
 立即注册
查看: 3619|回复: 11
收起左侧

[UART] STM32H7的串口收发函数源码学习,含查询,中断和DMA方式

[复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106746
QQ
发表于 2018-11-14 12:25:12 | 显示全部楼层 |阅读模式
我们新实现的H7的8串口FIFO,基本用不到这些函数,不过还是研究下,方便大家使用学习。

函数:HAL_UART_Transmit
QQ截图20181114153648.png

函数:HAL_UART_Receive
222.png

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106746
QQ
 楼主| 发表于 2018-11-14 16:08:04 | 显示全部楼层
中断方式发送函数HAL_UART_Transmit_IT
66.png

中断方式接收函数HAL_UART_Receive_IT
2.png




回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106746
QQ
 楼主| 发表于 2018-11-14 16:33:02 | 显示全部楼层
使用DMA方式,需要事先做好DMA配置才可以使用的。

DMA方式发送函数HAL_UART_Transmit_DMA
QQ截图20181114162319.png

DMA方式接收函数HAL_UART_Receive_DMA
QQ截图20181114163215.png
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106746
QQ
 楼主| 发表于 2018-11-14 17:48:45 | 显示全部楼层
中断函数是最核心的处理API,最最重要。

  1. /**
  2.   * @brief Handle UART interrupt request.
  3.   * @param huart: UART handle.
  4.   * @retval None
  5.   */
  6. void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
  7. {
  8.   uint32_t isrflags   = READ_REG(huart->Instance->ISR);
  9.   uint32_t cr1its     = READ_REG(huart->Instance->CR1);
  10.   uint32_t cr3its     = READ_REG(huart->Instance->CR3);
  11.   uint32_t errorflags;

  12.   /* If no error occurs */
  13.   errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE));
  14.   if (errorflags == RESET)
  15.   {
  16.     /* UART in mode Receiver ---------------------------------------------------*/
  17.     if(((isrflags & USART_ISR_RXNE) != RESET)
  18.      && (   ((cr1its & USART_CR1_RXNEIE) != RESET)
  19.          || ((cr3its & USART_CR3_RXFTIE) != RESET)) )
  20.     {
  21.       UART_Receive_IT(huart);
  22.       return;
  23.     }
  24.   }

  25.   /* If some errors occur */
  26.   if(   (errorflags != RESET)
  27.      && (   ((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != RESET)
  28.          || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET)))
  29.   {
  30.     /* UART parity error interrupt occurred -------------------------------------*/
  31.     if(((isrflags & USART_ISR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET))
  32.     {
  33.       __HAL_UART_CLEAR_IT(huart, UART_CLEAR_PEF);

  34.       huart->ErrorCode |= HAL_UART_ERROR_PE;
  35.     }

  36.     /* UART frame error interrupt occurred --------------------------------------*/
  37.     if(((isrflags & USART_ISR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
  38.     {
  39.       __HAL_UART_CLEAR_IT(huart, UART_CLEAR_FEF);

  40.       huart->ErrorCode |= HAL_UART_ERROR_FE;
  41.     }

  42.     /* UART noise error interrupt occurred --------------------------------------*/
  43.     if(((isrflags & USART_ISR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
  44.     {
  45.       __HAL_UART_CLEAR_IT(huart, UART_CLEAR_NEF);

  46.       huart->ErrorCode |= HAL_UART_ERROR_NE;
  47.     }

  48.     /* UART Over-Run interrupt occurred -----------------------------------------*/
  49.     if(   ((isrflags & USART_ISR_ORE) != RESET)
  50.         &&(  ((cr1its & USART_CR1_RXNEIE) != RESET) ||
  51.              ((cr3its & USART_CR3_RXFTIE) != RESET) ||
  52.              ((cr3its & USART_CR3_EIE) != RESET)) )
  53.     {
  54.       __HAL_UART_CLEAR_IT(huart, UART_CLEAR_OREF);

  55.       huart->ErrorCode |= HAL_UART_ERROR_ORE;
  56.     }

  57.     /* Call UART Error Call back function if need be --------------------------*/
  58.     if(huart->ErrorCode != HAL_UART_ERROR_NONE)
  59.     {
  60.       /* UART in mode Receiver ---------------------------------------------------*/
  61.       if(((isrflags & USART_ISR_RXNE) != RESET)
  62.          && (   ((cr1its & USART_CR1_RXNEIE) != RESET)
  63.              || ((cr3its & USART_CR3_RXFTIE) != RESET)) )
  64.       {
  65.         UART_Receive_IT(huart);
  66.       }

  67.       /* If Overrun error occurs, or if any error occurs in DMA mode reception,
  68.          consider error as blocking */
  69.       if (((huart->ErrorCode & HAL_UART_ERROR_ORE) != RESET) ||
  70.           (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)))
  71.       {
  72.         /* Blocking error : transfer is aborted
  73.            Set the UART state ready to be able to start again the process,
  74.            Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
  75.         UART_EndRxTransfer(huart);

  76.         /* Disable the UART DMA Rx request if enabled */
  77.         if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
  78.         {
  79.           CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);

  80.           /* Abort the UART DMA Rx channel */
  81.           if(huart->hdmarx != NULL)
  82.           {
  83.             /* Set the UART DMA Abort callback :
  84.                will lead to call HAL_UART_ErrorCallback() at end of DMA abort procedure */
  85.             huart->hdmarx->XferAbortCallback = UART_DMAAbortOnError;

  86.             /* Abort DMA RX */
  87.             if(HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
  88.             {
  89.               /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */
  90.               huart->hdmarx->XferAbortCallback(huart->hdmarx);
  91.             }
  92.           }
  93.           else
  94.           {
  95.             /* Call user error callback */
  96.             HAL_UART_ErrorCallback(huart);
  97.           }
  98.         }
  99.         else
  100.         {
  101.           /* Call user error callback */
  102.           HAL_UART_ErrorCallback(huart);
  103.         }
  104.       }
  105.       else
  106.       {
  107.         /* Non Blocking error : transfer could go on.
  108.            Error is notified to user through user error callback */
  109.         HAL_UART_ErrorCallback(huart);
  110.         huart->ErrorCode = HAL_UART_ERROR_NONE;
  111.       }
  112.     }
  113.     return;

  114.   } /* End if some error occurs */

  115.   /* UART wakeup from Stop mode interrupt occurred ---------------------------*/
  116.   if(((isrflags & USART_ISR_WUF) != RESET) && ((cr3its & USART_CR3_WUFIE) != RESET))
  117.   {
  118.     __HAL_UART_CLEAR_IT(huart, UART_CLEAR_WUF);
  119.     /* Set the UART state ready to be able to start again the process */
  120.     huart->gState  = HAL_UART_STATE_READY;
  121.     huart->RxState = HAL_UART_STATE_READY;
  122.     HAL_UARTEx_WakeupCallback(huart);
  123.     return;
  124.   }

  125.   /* UART in mode Transmitter ------------------------------------------------*/
  126.   if(((isrflags & USART_ISR_TXE) != RESET)
  127.      && (   ((cr1its & USART_CR1_TXEIE) != RESET)
  128.          || ((cr3its & USART_CR3_TXFTIE) != RESET)) )
  129.   {
  130.     UART_Transmit_IT(huart);
  131.     return;
  132.   }

  133.   /* UART in mode Transmitter (transmission end) -----------------------------*/
  134.   if(((isrflags & USART_ISR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))
  135.   {
  136.     UART_EndTransmit_IT(huart);
  137.     return;
  138.   }

  139.   /* UART TX FIFO Empty  -----------------------------------------------------*/
  140.   if(((isrflags & USART_ISR_TXFE) != RESET) && ((cr1its & USART_CR1_TXFEIE) != RESET))
  141.   {
  142.     CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXFEIE);
  143.   }
  144. }
复制代码


回复

使用道具 举报

610

主题

3051

回帖

4901

积分

至尊会员

积分
4901
发表于 2018-11-15 16:09:19 | 显示全部楼层
eric2013 发表于 2018-11-14 17:48
中断函数是最核心的处理API,最最重要。

貌似看起来蛮复杂的
回复

使用道具 举报

10

主题

130

回帖

160

积分

初级会员

积分
160
发表于 2019-3-30 12:20:42 | 显示全部楼层
本帖最后由 oneV 于 2019-3-30 12:27 编辑

遇到一个问题请教一下楼主  H7  usart2  DMA      发送和接收都使用DMA    发送DMA方式DMA_NORMAL     接收DMA方式DMA_CIRCULAR      如果只接收不发送即HAL_UART_Receive_DMA  接收正常没有漏数据    当打开发送HAL_UART_Transmit_DMA时 发送出去的数据没有漏  但接收的数据就严重漏  
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106746
QQ
 楼主| 发表于 2019-3-30 14:08:18 | 显示全部楼层
oneV 发表于 2019-3-30 12:20
遇到一个问题请教一下楼主  H7  usart2  DMA      发送和接收都使用DMA    发送DMA方式DMA_NORMAL     接收 ...

串口1整过

【STM32H743实验例程】实验14:STM32H743串口DMA方式收发,DMA方式问题比较多,要注意数据一致性
http://www.armbbs.cn/forum.php?m ... 6271&fromuid=58
(出处: 安富莱电子论坛)
回复

使用道具 举报

10

主题

130

回帖

160

积分

初级会员

积分
160
发表于 2019-3-30 14:18:32 | 显示全部楼层
本帖最后由 oneV 于 2019-3-30 14:22 编辑
eric2013 发表于 2019-3-30 14:08
串口1整过

【STM32H743实验例程】实验14:STM32H743串口DMA方式收发,DMA方式问题比较多,要注意数据 ...

硬汉可以做一下这个实验么  使用哪个串口没关系 发送使用HAL_UART_Transmit_DMA 发送DMA方式DMA_NORMAL     接收 HAL_UART_Receive_DMA  接收DMA方式DMA_CIRCULA  看一下两者同时进行时接收是否有漏数据的情况      波特率、发送接收数据量大小都无所谓
另外这个跟cache关系不大  因为现在想验证是发送接收同时进行时接收为什么严重漏数据 单独的接收没有问题  另外 不使能D-cache也可以

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106746
QQ
 楼主| 发表于 2019-3-30 14:23:23 | 显示全部楼层
oneV 发表于 2019-3-30 14:18
硬汉可以做一下这个实验么  使用哪个串口没关系 发送使用HAL_UART_Transmit_DMA 发送DMA方式DMA_NORMAL   ...

发送期间,上位机同时发送数据下来?
回复

使用道具 举报

10

主题

130

回帖

160

积分

初级会员

积分
160
发表于 2019-3-30 15:00:38 | 显示全部楼层
eric2013 发表于 2019-3-30 14:23
发送期间,上位机同时发送数据下来?

对  使用串口助手就可以的 串口助手也同时收发   

真是好奇怪 在NUCLEO-F446上  同时收发(HAL_UART_Receive_DMA、HAL_UART_Transmit_DMA)就很正常

硬汉可以帮忙验证一下H7么
回复

使用道具 举报

10

主题

130

回帖

160

积分

初级会员

积分
160
发表于 2019-3-30 19:10:09 | 显示全部楼层
oneV 发表于 2019-3-30 15:00
对  使用串口助手就可以的 串口助手也同时收发   

真是好奇怪 在NUCLEO-F446上  同时收发(HAL_UART_R ...

自我解答一下

问题找到了  使用cubemx生成代码的时候习惯性的把IO口的maximum output speed设置成了very high
降低速率就解决问题了   具体原因未知 来日细查
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106746
QQ
 楼主| 发表于 2019-3-31 01:36:08 | 显示全部楼层
oneV 发表于 2019-3-30 19:10
自我解答一下

问题找到了  使用cubemx生成代码的时候习惯性的把IO口的maximum output speed设置成了ve ...

感谢告知原因
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-3 21:36 , Processed in 0.201351 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表