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

施敏

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

HAL库函数串口中断接收只能收到第一个字节

首先介绍一下实验环境:单片机STM32f415
调试器:st-link

硬件初始化:
*串口波特率为614400
*采用定时器每隔500us触发一次串口中断发送
*发送完成后进入中断接收模式

定时器中断回调函数如下:

void HAL_tiM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
        if(htim==&htim14)
        {
                GYRO_Handle.cmd_GYRO=GYRO_CMD;               
                HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET);                                  使能发送
                HAL_UART_Transmit_IT(&huart3, &GYRO_Handle.cmd_GYRO, 1);                         开启中断发送,然后进入发送模式
        }
}




发送完成后进入发送中断完成回调函数:
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
        if(huart==&huart3)
        {
                HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET);                                使能接收
                HAL_UART_Receive_IT(&huart3, GYRO_Handle.frame_GYRO, 7);                        开启中断接收,然后进入接收模式
        }
}


接收中断完成回调函数:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
        if(huart==&huart3)
        {
                 用户函数区域
        }
}


实验结果:

发送没有问题,可成功发送。
接收只能收到第一个字节。
接收服务函数老是进入错误服务函数,错误号为数据溢出

已经分析两天了,还是没有找到问题,求大师分析。

回帖(40)

李刚

2018-11-26 08:44:14

根据现像,乱码一般是时钟配置问题。楼主检查下时钟配置。
举报

李刚

2018-11-26 08:49:17
HAL_UART_Receive_IT 不要放在HAL_UART_TxCpltCallback 里,放在主函数里,在初始化的时候调用,总之要在HAL_UART_Transmit_IT之前。
举报

施敏

2018-11-26 09:05:31
引用: 你我然后 发表于 2018-11-26 15:14
HAL_UART_Receive_IT 不要放在HAL_UART_TxCpltCallback 里,放在主函数里,在初始化的时候调用,总之要在HAL_UART_Transmit_IT之前。

改后如下
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
        if(htim==&htim14)
        {
                GYRO_Handle.cmd_GYRO=GYRO_CMD;               
                HAL_UART_Receive_IT(&huart3, GYRO_Handle.frame_GYRO, 7);       
                HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET);       
                HAL_UART_Transmit_IT(&huart3, &GYRO_Handle.cmd_GYRO, 1);       
        }

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
        if(huart==&huart3)
        {
                HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET);                       
        }
}

还是进入错误中断,无法进入接收完成中断
举报

张鑫

2018-11-26 09:23:46
关注!
波特率降低测试
举报

施敏

2018-11-26 09:40:10
引用: yisen282 发表于 2018-11-26 15:48
关注!
波特率降低测试

9600木有问题!
举报

张鑫

2018-11-26 10:00:07
通信距离有多远?用max3232?
举报

李刚

2018-11-26 10:09:46
本帖最后由 党国特派员 于 2015-1-16 11:40 编辑

HAL_UART_Receive_IT 只需要调用一次。
还有就是你的接收函数里都干了些什么,会不会时间超长了。
举报

李刚

2018-11-26 10:19:46
如果 是还出现数据溢出的话,那你就用HAL_UART_Receive_DMA吧,最好是双缓冲的。
举报

杨杜昼

2018-11-26 10:36:52
用户函数区处理时间太长
举报

黄晔华

2018-11-26 10:43:56
本帖最后由 damiaa 于 2015-1-16 13:37 编辑

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET);                                使能接收
                这个IO和时间搭配问题吧。
用232试试。或者只接收。IO搞个低 死的     ?
举报

施敏

2018-11-26 10:55:10
我把原有中断服务函数的标志位处理函数的顺序改了一下。
现在可以收到数据了,但是第一个数据经常出现跟帧头不匹配的现象,我感觉是第一个字节丢掉。

求分析!

举报

施敏

2018-11-26 11:10:13
引用: yisen282 发表于 2018-11-26 16:25
通信距离有多远?用max3232?

50cm通信距离
举报

施敏

2018-11-26 11:19:51
引用: yisen282 发表于 2018-11-26 16:25
通信距离有多远?用max3232?

max422. 硬件没有问题,poll模式可以正常接收
举报

施敏

2018-11-26 11:36:56
引用: 你我然后 发表于 2018-11-26 16:34
本帖最后由 党国特派员 于 2015-1-16 11:40 编辑

HAL_UART_Receive_IT 只需要调用一次。

接收回调只是加了一个标志位,没干别的
举报

施敏

2018-11-26 11:49:32
引用: tianyou15 发表于 2018-11-26 17:01
用户函数区处理时间太长

用户函数的也就回调中的控制函数,没别的了
举报

施敏

2018-11-26 11:55:48
引用: ke3978 发表于 2018-11-26 17:09
本帖最后由 damiaa 于 2015-1-16 13:37 编辑

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET);                                使能接收

设备在收到我的指令50us后才会发数据的。我感觉不是因为使能脚的问题
举报

刘超

2018-11-26 12:03:40
接收中断未处理完整;
中断+查询:第一个接收中断来了后改为查询方式接收;
是否使用FIFO?
举报

周羽姿

2018-11-26 12:23:15
我想是:在规定时间里中断里发送肯定正常发送,之后到接受中断里,由于你的发送时间太短,中断有优先级,建议可惜在发送中断时间放大点和接受程序减少放中断里。个人意见,仅供参考。
举报

冯超

2018-11-26 12:29:29
LZ在调陀螺仪么~~~
举报

更多回帖

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