关于HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)的研究

HAL_UART_Receive_IT(UART_HandleTypeDef huart, uint8_t pData, uint16_t Size)
从它的函数内容考看,其实就是初始化了下uart端口,定义了下接收到的数据的缓存器名,还有定义了接收尺寸,然后开启了UART_IT_RXNE,即接收非空中断,然后静等中断发生。
2楼继续。

中断发生后。
进入
void USART1_IRQHandler(void)
{
HAL_NVIC_ClearPendingIRQ(USART1_IRQn);
HAL_UART_IRQHandler(&huart1);
// cont_uart++;
}
先清除等待标志,后进入中断处理
进入
tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE);
tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE);
/ UART in mode Receiver ---------------------------------------------------/
if((tmp1 != RESET) && (tmp2 != RESET))
{
UART_Receive_IT(huart);
}
判断接收到非空数据,并且RXEN中断开启了,则执行数据接收UART_Receive_IT(huart);
8位,none,所以执行
if(huart->Init.Parity == UART_PARITY_NONE)
{
*huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
}
得到数据,存到pRxBuffPtr的指向地址缓存器里
3楼继续

接上面
if(--huart->RxXferCount == 0)
{
__HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);

/ Check if a transmit process is ongoing or not /
if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
{
huart->State = HAL_UART_STATE_BUSY_TX;
}
else
{
/ Disable the UART Parity Error Interrupt /
__HAL_UART_DISABLE_IT(huart, UART_IT_PE);

/ Disable the UART Error Interrupt: (Frame error, noise error, overrun error) /
__HAL_UART_DISABLE_IT(huart, UART_IT_ERR);

huart->State = HAL_UART_STATE_READY;
}
HAL_UART_RxCpltCallback(huart);

return HAL_OK;
}
计数自减1,判断是否是0,不是0则说明还么接收完
则程序返回,再次接收到一个字节,产生中断再次执行。
直到--huart->RxXferCount == 0
__HAL_UART_DISABLE_IT(huart, UART_IT_RXNE); 关闭RXEN接收非空中断
再判断是否在传送,没有则关闭UART Parity Error Interrupt
关闭UART Error Interrupt: (Frame error, noise error, overrun error)
并且 调用接收完成回调函数,HAL_UART_RxCpltCallback(huart);
继续接4楼

接楼上
说明每次接收完数据,只要没发送状态
uart的接收中断全部关闭了,要想连续的接收数据,则需要在
HAL_UART_RxCpltCallback(huart);函数中开启RXEN中断

/ Enable the UART Parity Error Interrupt /
__HAL_UART_ENABLE_IT(huart, UART_IT_PE);

/ Enable the UART Error Interrupt: (Frame error, noise error, overrun error) /
__HAL_UART_ENABLE_IT(huart, UART_IT_ERR);

/ Process Unlocked /
__HAL_UNLOCK(huart);

/ Enable the UART Data Register not empty Interrupt /
__HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);

即需要再次调用HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer, 8);函数,。
下面测试:
在main中添加
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
/* NOTE: This function Should not be modified, when the callback is needed,
the HAL_UART_TxCpltCallback could be implemented in the user file
*/
HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer, 8);

}
测试失败,第一次能接收到,第二次数据接收不到。
将 HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer, 8);写入到
void USART1_IRQHandler(void)
{
HAL_NVIC_ClearPendingIRQ(USART1_IRQn);
HAL_UART_IRQHandler(&huart1);
HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer, 8);
cont_uart++;
}
测试成功,可以接收到8位数据。
不过,如果数据超过8位,则超过部分会覆盖掉以前的数据
如:8位数据是,1、2、3、4、5、6、7、8
发送的10位数据:则接收到的会把前两位覆盖,最终接收的数据是
10、9、3、4、5、6、7、8
测试代码是接收8位,要改成10位同样道理,反正超过了接收的就是不对的数据

分析上面的
void USART1_IRQHandler(void)
{
HAL_NVIC_ClearPendingIRQ(USART1_IRQn);
HAL_UART_IRQHandler(&huart1);
HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer, 8);
cont_uart++;
}
接收到小于设定的长度值无所谓,能正常获取
大于之后覆盖
因为接收完8个数据,清除中断,然后Hal_ready = ok,等到第九个数据过来产生中断

10 个评论

有完整的工程文件么?
目前CUBE的函数库实现了定长数据的接收功能,也就是发送方的数据格式长度不能改变。
请问,如果接收到的数据不是定长的,是以结束符表示一帧数据的结束,那么应该如何实现接收功能?
Cube使用最大的问题是官方使用说明资料太少,例子也不丰富。所以有时要自己分析库函数源代码,并进行试错。
上位机发送数据时,我的完全进不去USART1_IRQHandler中断是什么原因呢?
基本配置流程为:
1. MX_USART1_UART_Init 初始化串口;
2. MX_USART1_UART_Enable_Irq 使能串口中断;
3. HAL_UART_Receive_IT 设置串口接收缓冲区并使能接收中断
4. 通过上位机发送串口数据
结果不能进USART1_IRQHandler中断处理函数,这个原因有知道的大神吗?

测试成功,可以接收到8位数据。
不过,如果数据超过8位,则超过部分会覆盖掉以前的数据
如:8位数据是,1、2、3、4、5、6、7、8
发送的10位数据:则接收到的会把前两位覆盖,最终接收的数据是
10、9、3、4、5、6、7、8
测试代码是接收8位,要改成10位同样道理,反正超过了接收的就是不对的数据



这里的发送十位数据,出来的结果应该是9、10、3、4、5、6、7、8

void USART1_IRQHandler(void)
{
HAL_NVIC_ClearPendingIRQ(USART1_IRQn);
HAL_UART_IRQHandler(&huart1);
HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer, 8);
cont_uart++;
}



请问这个函数是我们新建的函数吧?


已找到,在stm32Fxxx_it.c文件里面,中断处理函数里

如果要接收不同字节长度的呢?比如有8个字节,7个字节,6个字节,如果通过计数自减1的方式,只能设定指定字节长度,变化长度的字节就没法操作了……

变化长度的字节也是可以处理的,只不过不能在callback函数里处理数据包了。可以在USART1_IRQHandler()这个函数里填写自己的代码,对包头、包尾进行判断就可以了。

要回复文章请先登录注册