STM32 hal库Can发送数据时第一包会发送两次

3 篇文章 0 订阅
2 篇文章 0 订阅
该问题在发送can数据时,采用查询方式
那么就会进行一个等待超时:
    while(!(__HAL_CAN_TRANSMIT_STATUS(hcan, transmitmailbox)))
    {
      /* Check for the Timeout */
      if(Timeout != HAL_MAX_DELAY)
      {
       if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
       {
         hcan->State = HAL_CAN_STATE_TIMEOUT;

         __HAL_CAN_CANCEL_TRANSMIT(hcan, transmitmailbox);

         /* Process unlocked */
         __HAL_UNLOCK(hcan);
         return HAL_TIMEOUT;
        }
      }
    }
产生等待超时,返回hal_timeout;但是此时却发送成功了;
此时那么应该考虑是不是该标志在检测之间已经被清除了,那么还会有什么东西可能这检查之前就去清标志呢?
  答案中有一个:进入中断了。

那又是什么中断呢? can发送中断

好那我们看一下发送中断里边会清除这些标志吗?
void HAL_CAN_IRQHandler(CAN_HandleTypeDef* hcan)
.........
if(__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_TME))
.........
 /* Clear transmission status flags (RQCPx and TXOKx) */
      SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP0  | CAN_TSR_RQCP1  | CAN_TSR_RQCP2 | \
                                   CAN_FLAG_TXOK0 | CAN_FLAG_TXOK1 | CAN_FLAG_TXOK2);
......
我们可以看到,在邮箱都为空时会清除,我们由于采用查询方式自然只会占一个邮箱,那么它发送ok了自然会产生邮箱为空的中断请求。
此时can发送中断函数如果没有编写中断函数或者 中断函数没有相应的HAL_CAN_Transmit_IT()来开启相应中断, ,那么can发送中断相关中断的标志位不会再打开了,也就相当于关闭了can发送中断

好,到这儿应该也明白了为什么会出现标题所说的现象:
在调用HAL_CAN_Transmit()后,can将该消息发送出去了,产生中断清除了标志,然后我们还在那儿傻等标志变化为发送成功,等不到自然就会增生timeout,然后我们判断发送没成功,进行下一次发送,can发送中断此时相当于关闭状态,本次发送数据时不会再有人来清除发送标志了,所以can发送成功,不会再有timeout了。

解决方案: 要用中断发送就用中断发送就好,不用中断发送的话关闭/不开启can发送中断就好。

另外多说一嘴: 采用查询发送时,发送成功后应清除相应标志,否则那儿永远都是发送成功。
    		while( HAL_CAN_Transmit(&hcan1, 0x1) != HAL_OK) {
			if(retry++ > 5) {
				iSysDebug(0, "send can data failed\r\n");
				SET_BIT(hcan1.Instance->TSR, CAN_TSR_RQCP0  | CAN_TSR_RQCP1  | CAN_TSR_RQCP2 | \
				        CAN_FLAG_TXOK0 | CAN_FLAG_TXOK1 | CAN_FLAG_TXOK2);
				return HAL_ERROR;
			}
		}
		/* Clear transmission status flags (RQCPx and TXOKx) */
		SET_BIT(hcan1.Instance->TSR, CAN_TSR_RQCP0  | CAN_TSR_RQCP1  | CAN_TSR_RQCP2 | \
		        CAN_FLAG_TXOK0 | CAN_FLAG_TXOK1 | CAN_FLAG_TXOK2);


  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在使用STM32 HAL进行CAN发送,你可以按照以下步骤进行配置和编写代码: 1. 首先,包含所需的头文件和文件。引用中的代码片段中包含了一些常见的头文件,比如"main.h"和"can.h"。确保你的工程中已经包含了这些文件。 2. 然后,你需要定义一个CAN_RXTX_FLAG结构体,用于标记CAN是否接收到数据。 3. 然后,你可以编写CANx_SendMessage函数,该函数用于发送CAN消息。函数的参数包括CAN_HandleTypeDef结构体指针hcan,表示CAN总线的句柄;ID,表示消息的标识符;Data,表示要发送数据;Len,表示数据的长度。 4. 如果需要发送扩展数据帧,你可以使用CANx_SendExtData函数。该函数的参数和功能与CANx_SendMessage函数类似。 5. 最后,你可以使用CAN_Start函数来启动CAN总线。 请注意,以上是一种使用STM32 HAL进行CAN发送的示例。具体的配置和代码可能会因为不同的设备和需求而有所不同。你可以参考引用中提到的文章或视频来获取更详细的信息,并根据你的具体情况进行配置和编写代码。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [stm32HAL学习应用笔记之CAN通讯](https://blog.csdn.net/qq_33954661/article/details/124883658)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [Can 总线资料和STM32HAL配制说明](https://download.csdn.net/download/cos12a/20008535)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值