你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

hal库,如果can定时发送,则无法进入can接收中断。

[复制链接]
any012 提问时间:2019-1-16 10:23 /
10ST金币
大家好,请教个问题。stm32f103,用的hal库。
一开始编程时,只让can中断接收,可以正常运行。后来打算定时读取其它设备信息,于是加了一部分,每秒发送5帧信息,也会收到对应的返回信息。

结果加了发送部分后,can接收中断好像只能进入一次了,然后就再也进不到接收中断了。屏蔽掉发送语句,则接收正常。
发送用的阻塞发送。
HAL_CAN_Transmit(&hcan, 10);

请大家帮分析下,可能哪里出了问题。
也试过将发送改为中断发送,问题依旧。

最佳答案

查看完整内容

我使用的时候,会做错误纠正。当检测到错误标志位时,重新初始化对应的模块。
收藏 评论14 发布时间:2019-1-16 10:23

举报

14个回答
any012 最优答案 回答时间:2019-1-16 16:36:42
本帖最后由 any012 于 2019-1-16 16:38 编辑
安 发表于 2019-1-16 15:29
楼主是不是加了断点以后出现的这种情况,如果是。发生异常以后,重新初始化CAN。尽量不要在CAN接收中断时, ...

不是加断点时出现的。
是因为出现问题了才加断点调试的。

我的理解是CAN的接收中断,打断了CAN的发送函数,此时可能hcan->Lock处于Lock状态。我的CAN接收中断函数的回调函数里又开启了下一次的中断接收,但是在HAL_CAN_Receive_IT()函数里,会判断hcan->Lock的状态,如果是Lock状态,直接就返回了HAL_BUSY.结果就是下一次的中断接收函数没有启动成功。

用的时候觉得传输挺快的,忘了CAN其实还是半双工,不可能同时发送和接收的。
废鱼 回答时间:2019-1-16 10:23:59
我使用的时候,会做错误纠正。当检测到错误标志位时,重新初始化对应的模块。
any012 回答时间:2019-1-16 10:44:30
网上搜了下,搜到这么一篇文章,但是没看明白。
http://blog.csdn.net/ytdsf/article/details/80142899


我理解的是,如果调用中断函数,如果返回的是hal_busy状态,则会跳过中断使能部分。所以不会再触发中断了。
作者,加了一句判断,如果返回的是HAL_BUSY状态,仍旧使能CAN中断。

那么,问题是,为何会出现返回HAL_BUSY?
STM1024 回答时间:2019-1-16 11:32:18
你用一个CAN卡接收发送数据,好像103的数据如果发出去没有接收似乎会在mailbox中堵塞。
此外,检查一下中断后是否清除了中断标志

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

any012 回答时间:2019-1-16 12:02:34
本帖最后由 any012 于 2019-1-16 12:04 编辑

我在刚进入HAL_CAN_Receive_IT()函数里加了个中断,发现,正常情况下,hcan->Lock状态是UnLock,然后出错的那次,状态是Lock。

猜测程序本来运行到CAN发送函数这里,还没结束就被CAN接收函数中断了。
而中断接收回调函数里再调用HAL_CAN_Receive_IT()时,此时hcan->Lock状态是Lock,于是就直接然会HAL_BUSY了。

zccdyfw 回答时间:2019-1-16 13:41:31
废鱼 回答时间:2019-1-16 15:29:09
楼主是不是加了断点以后出现的这种情况,如果是。发生异常以后,重新初始化CAN。尽量不要在CAN接收中断时,加断点,经常会出现这种情况。

评分

参与人数 1蝴蝶豆 +3 收起 理由
STMCU + 3

查看全部评分

废鱼 回答时间:2019-1-16 17:11:48
这个是问题,我也不知道如何解决。在数据发送过程中,加断点会出现这种问题。我用串口的时候,就特别容易出现。
any012 回答时间:2019-1-17 09:07:02
安 发表于 2019-1-16 17:11
这个是问题,我也不知道如何解决。在数据发送过程中,加断点会出现这种问题。我用串口的时候,就特别容易出 ...

暂时是这么解决的,出了在CAN中断回调函数里再调用CAN中断接收函数外,在每次CAN发送函数后面,再调用依次CAN中断接收函数。
群里的朋友,有的建议是在CAN中断函数里,再加一句打开中断。我在2楼发的那个链接里,博客的主人也是这么做的。
any012 回答时间:2019-1-17 10:23:53
本帖最后由 any012 于 2019-1-17 10:34 编辑
安 发表于 2019-1-17 09:36
我使用的时候,会做错误纠正。当检测到错误标志位时,重新初始化对应的模块。 ...
  1. if (HAL_CAN_Receive_IT(hcan, FIFO0) != HAL_OK)
  2. {
  3.     Error_Handler();
  4. }

  5. static void Error_Handler(void)
  6. {
  7.     while(1)
  8.     {
  9.     }
  10. }
复制代码
像这样?
废鱼 回答时间:2019-1-17 10:46:55
不是。比如下面的代码:
                if(Systimeout==0 || Systimeout > HAL_GetTick() || HAL_GetTick() - Systimeout >= 60000)
                {
                        MX_USART1_UART_Init();
                        HAL_UART_Receive_IT(&huart1,RxBuffer,sizeof(RxBuffer));
                        Systimeout = HAL_GetTick() ;
                }
any012 回答时间:2019-1-17 10:52:56
谢谢,受教了。
liyang05 回答时间:2019-3-29 20:48:53
您好:我在使用can发送接受数据时,也遇到了相似问题,向请问一下
我用can调试电机pid;使能了can中断接受电机返回数据,在定时器中断里计算pid,然后使用can发送函数把数据发下去,但是程序会一直卡死在can发送函数中,但是我把can发送函数写在主函数中,就不会有问题,想请问一下大概是什么原因造成的,该从哪方面下手解决?
any012 回答时间:2019-4-1 08:45:00
尽量减少中断函数的处理时间,我是在中断函数里只接收数据,然后置个标志位,主循环里读取这个标志位然后进行数据处理。

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版