arels 发表于 2017-1-7 11:43:55

斜阳__ 发表于 2017-1-6 15:14
使用CubeMX配置一下调用HAL_UART_Receive_IT(),接收完成之后就会调用回调函数;
如果不定长数据接收建议使 ...

空闲中断和超时中断还没用过
现在确实也遇到了 要接收不定长数据的问题

wjandsq 发表于 2017-1-7 13:50:06

本帖最后由 wjandsq 于 2017-1-7 14:06 编辑

1 重写中断函数(改动较大,不推荐)。
2 定义较大的接收缓冲,定时查询缓冲使用情况(常规处理)。
3 重写回调函数,接收一个字符立即在回调函数中处理(即时处理)。


海迹天涯 发表于 2017-1-8 13:48:33


帮顶。。。。

wjandsq 发表于 2017-1-10 11:59:38

本帖最后由 wjandsq 于 2017-1-13 20:09 编辑

HAL库串口中断函数使用说明(For STM32F4xxx)
UART_HandleTypeDef结构类型,串口句柄
.InstanceUSART_TypeDef 结构指针类型,串口硬件寄存器数据结构
. Init      UART_InitTypeDef结构类型,串口通讯参数
. gState    HAL_UART_StateTypeDef 枚举类型,串口状态信息,和发送操作有关联
.RxState    HAL_UART_StateTypeDef枚举类型,串口状态信息,和接收操作有关联
.pTxBuffPtr   uint8_t指针类型,串口发送buffer指针
.TxXferSize    uint16_t类型,串口发送 buffer size
.TxXferCountuint16_t类型,串口发送计数
.pRxBuffPtr   uint8_t指针类型,串口接收指针
.pRxBuffPtr   uint8_t指针类型,串口接收buffer指针
.RxXferSize    uint16_t类型,串口接收 buffer size
.RxXferCountuint16_t类型,串口接收计数
HAL_UART_Init         串口初始化
HAL_UART_Receive_IT   串口中断接收API,BSP层调用
HAL_UART_Transmit_IT串口中断发送API,BSP层调用
HAL_UART_IRQHandler串口中断处理函数,所有硬件串口共用
UART_Receive_IT    串口中断接收处理函数,所有硬件串口共用
UART_Transmit_IT    串口中断发送处理函数,所有硬件串口共用
UART_EndRxTransfer串口终止接收处理函数,所有硬件串口共用
UART_EndTransmit_IT串口终止发送处理函数,所有硬件串口共用
HAL_UART_ErrorCallback 串口错误处理函数,所有硬件串口共用
HAL_UART_TxCpltCallback 串口发送回调函数,所有硬件串口共用
HAL_UART_RxCpltCallback 串口数据接收完成回调,所有硬件串口共用
串口中断处理函数(HAL_UART_IRQHandler)工作流程:
(1)当接收中断打开且接收寄存器非空,进行数据接收,该代码处理和标准外设驱动库一致。
(2)当出现校验位、噪声、溢出错误时,清除错误标志(代码非常完善),调用串口错误处理回掉函数(空函数)。
(3)当使能DMA发送或接收时,进行DMA发送或接收处理,DMA发送或接收的回调函数也可以重写。
(4)当串口接收到预先设置的个数时,调用串口接收回调函数,进行接收完毕的处理。
(5)当发送中断打开,并且发送寄存器为空,进行数据发送,该代码处理和标准外设驱动库一致。
(6)当串口发送完预先设置的个数时,启用发送完成中断,随后调用串口发送回调函数,进行发送完毕的处理。
串口中断bsp层代码设计参考:
可以利用HAL_UART_Receive_IT接收固定长度的串口数据包,但由于串口数据包长度往往不确定,而且需要实时处理(被用户程序实时取走),那么可以在自动生成的HAL串口初始化代码后添加:HAL_UART_Receive_IT(huart, (uint8_t *)USART1_RxBuffer, 1);
如果串口收到一个字符,就会调用HAL_UART_RxCpltCallback,可以在这个函数中实时取走字符,这个串口回调函数也相当于串口接收中断。可以重写这个__weak函数,而不必重写串口中断函数。为保证串口数据的连续接收,HAL_UART_RxCpltCallback函数应增加如下代码:
HAL_UART_Receive_IT(huart, (uint8_t *)USART1_RxBuffer, 1);

参考ST官方USB CDC例程的代码,一个重写的HAL_UART_RxCpltCallback示例代码如下(通过实际调试,可以连续接收):
/**
* @briefRx Transfer completed callback
* @paramhuart: UART handle
* @note   2016-12-11 wjandsq@163.com
*            This function is eque to HAL_UARTx_Rx_IRQ
*/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if (huart->Instance == USART1){
      /* User Code Begin 1   */
      if(++USART1_RxBufPtrIn == USART1_BuffLength) { USART1_RxBufPtrIn = 0;} /* uart bsp code demo */
      /* User Code End 1*/
      HAL_UART_Receive_IT(huart, (uint8_t *)(USART1_RxBuffer + USART1_RxBufPtrIn), 1);
    }
}
对于串口发送,同样可以重写TxCpltCallback函数,在这个函数里进行RS485的换向IO控制,不需要延时一个字节。



wjandsq 发表于 2017-1-10 13:21:46

参考代码

C:\Users\Administrator\STM32Cube\Repository\STM32Cube_FW_F4_V1.14.0\Projects\STM324xG_EVAL\Applications\USB_Device\CDC_Standalone\Src\usbd_cdc_interface.c

/**
* @briefRx Transfer completed callback
* @paramhuart: UART handle
* @retval None
*/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
/* Increment Index for buffer writing */
UserTxBufPtrIn++;

/* To avoid buffer overflow */
if(UserTxBufPtrIn == APP_RX_DATA_SIZE)
{
    UserTxBufPtrIn = 0;
}

/* Start another reception: provide the buffer pointer with offset and the buffer size */
HAL_UART_Receive_IT(huart, (uint8_t *)(UserTxBuffer + UserTxBufPtrIn), 1);
}

arels 发表于 2017-1-13 11:41:33

wjandsq 发表于 2017-1-10 13:21
C:\Users\Administrator\STM32Cube\Repository\STM32Cube_FW_F4_V1.14.0\Projects\STM324xG_EVAL\Applicati ...

谢谢先看看

五哥1 发表于 2017-1-23 01:01:29

我说过,问题自己提,自己解决,因为别人都是在猜

五哥1 发表于 2017-2-6 11:32:15

HAL库的学习大家都在摸索

三十不惑 发表于 2017-4-25 08:55:28

学习了,谢谢楼主!
页: 1 2 [3]
查看完整版本: 有用过HAL库的串口中断接收的朋友吗