硬汉嵌入式论坛

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

STM32V6之串口HAL库的API认识

[复制链接]

5

主题

229

回帖

249

积分

高级会员

积分
249
发表于 2020-11-20 21:05:12 | 显示全部楼层 |阅读模式
本帖最后由 旮旯旭 于 2020-11-20 21:23 编辑

/* IO operation functions *******************************************************/
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
/* Transfer Abort functions */
HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart);
HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart);

void HAL_UART_IRQHandler(UART_HandleTypeDef *huart);
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart);
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart);

UART支持DMA
用户可使用的发送和接收API分阻塞,中断IT和DMA
阻塞:HAL_UART_Transmit、HAL_UART_Receive
中断:HAL_UART_Transmit_IT、HAL_UART_Receive_IT
DMA: HAL_UART_Transmit_DMA、HAL_UART_Receive_DMA
中断处理程序HAL_UART_IRQHandler在stm32f4xx_it.c中断中被调用。如果使用了DMA来发送接收还有HAL_DMA_IRQHandler
callback回调函数是weak定义的:
发送完成:HAL_UART_TxCpltCallback
接收完成:HAL_UART_RxCpltCallback
错误:HAL_UART_ErrorCallback
用户是可以重写这个3个函数来满足对业务的处理。

1605877678(1).jpg


HAL库的串口发送接收由用户开启传输。HAL库对串口发送接收的处理在HAL_UART_IRQHandler进行处理,主要是发送、接收和错误中断的逻辑实现。
IT模式的发送和接收完成是通过计数器XferCount来实现的,
发送时:首先开启的是TXE中断,当UART的DR寄存器为空时触发TXE中断,将发送缓冲区里面的内容放入DR寄存器,同时计数器XferCount递减,当数据传递完成,计数器递减到0时关闭UART_IT_TXE,开启UART_IT_TC发送完成中断,在XferCount不为0时执行的是UART_Transmit_IT。当最后一个数据发送完成,由于在UART_Transmit_IT最后开启了UART_IT_TC,将触发中断进入UART_EndTransmit_IT,这个函数里面关闭了UART_IT_TC,同时有一个用户回调函数HAL_UART_TxCpltCallback。
接收时:开启UART_IT_RXNE,当有数据接收到时,触发中断,执行UART_Receive_IT,在这个函数里面有对不同数据位和校验位处理,用户节省了不少工作量,同时接收到一个XferCount计数器递减,当计数器归零时,提供给用户回调函数HAL_UART_RxCpltCallback。
暂不分析错误中断。
DMA模式的发送接收时通过DMA协处理器完成的
    发生时将发送完成,半传输完成,错误的回调函数传递给DMA函数指针。开启相关中断,在DMA传输完成时如果回调函数非空,会执行一开始传入的回调函数。执行完DMA回调函数会关闭和开启相应的中断来实现发送和接收功能,最后的函数入口也还是HAL_UART_TxCpltCallback、HAL_UART_RxCpltCallback。
传输的具体过程见图了解详情:

串口接收中断.jpg
串口接收DMA.jpg

串口发送中断.jpg

串口发送DMA.jpg

HAL库提供的API由5.3的图例可以知道只有接收到Size个数据才会执行callback函数,如果要实现多字节接收有几种方式选择,如果协议数据包是定长的那么直接定义缓冲区大小,开启传输的时候填入要接收的Size。
例如:只有接收完16个字节才会进入callback,可以自行修改代码验证
HAL_UART_Receive_IT(&huart1, aRxBuffer, 16);
HAL_UART_Receive_DMA(&huart1, aRxBuffer, 16);
如果是不定长的串口接收有2种方式字节接收超时和空闲中断来完成。空闲中断超时时间是1个数据的传输时间,如果数据之间的间隔比较久不能使用空闲中断来操作。具体实现看接收超时和空闲中断代码实现部分。
关于发送启动函数:HAL_UART_Transmit_IT、HAL_UART_Transmit_DMA 传输的缓冲区必须为全局或者静态缓冲区,防止在退出函数执行后栈空间被系统释放导致数据错乱。同时对于IT和DMA完成的数据传输由于是有DMA控制器完成的,如果想要再次发起传输必须等传输完成以后才可以,即使再次调用,IT和DMA发送函数做了优化虽然不会引起数据错位还是数据是发送不成功的 HAL_Status是BUSY状态,所以再次发送需要等到发送完成建立标志位,查询该标志位来或者串口发送所处的状态HAL库提供了 huart->gState 作为状态指示。if (huart->gState == HAL_UART_STATE_READY) 时才可以发送。
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
  /* 检查发送过程是否尚未进行 */
  if (huart->gState == HAL_UART_STATE_READY)
  {
    if ((pData == NULL) || (Size == 0U))
    {
      return HAL_ERROR;
    }
    /* Process Locked */
    __HAL_LOCK(huart);
    huart->pTxBuffPtr = pData;
    huart->TxXferSize = Size;
    huart->TxXferCount = Size;
huart->ErrorCode = HAL_UART_ERROR_NONE;
/* 设置发送状态忙 */   
huart->gState = HAL_UART_STATE_BUSY_TX;
    /* Process Unlocked */
    __HAL_UNLOCK(huart);
    /* Enable the UART Transmit data register empty Interrupt */
    __HAL_UART_ENABLE_IT(huart, UART_IT_TXE);
    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}

评分

参与人数 1金币 +20 收起 理由
eric2013 + 20 很给力!

查看全部评分

回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115667
QQ
发表于 2020-11-21 09:27:29 | 显示全部楼层
非常感谢楼主分享,整理的很棒。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-5-10 18:41 , Processed in 0.242860 second(s), 31 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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