打印
[STM32F4]

F407 CAN仲裁失败

[复制链接]
1244|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
aple0807|  楼主 | 2021-5-21 14:19 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
测试 CAN1,CAN2互相发送数据,分时发的情况,两者接收都正常。

CAN1发送ID=0x550330的报文
CAN2发送ID=0x330330的报文
同时发,不论先调用CAN1发送还是先调用CAN2发送,CAN1接收正常,CAN2接收不到。监控可以看到CAN1仲裁失败。

ID值交换发送,变成CAN2仲裁失败,CAN1接收不到数据。

根据CAN标准,仲裁失败的节点会自动重发报文,但这个似乎没有重发。
测试的报文发送间隔为1S,寄存器MCR的NART位是0(自动重发模式)。


if(CAN1->TSR & CAN_TSR_TME)
        HAL_CAN_Transmit(&hcan1, 0);
       
if(CAN2->TSR & CAN_TSR_TME)
        HAL_CAN_Transmit(&hcan2, 0);

这个问题原因在哪里? 求大神指点。

使用特权

评论回复
沙发
aple0807|  楼主 | 2021-5-21 17:09 | 只看该作者
问题补充,在发送结束中断中发送下一个报文,该报文会丢失,这又是什么原因?

使用特权

评论回复
板凳
lvyunzeng| | 2021-5-22 09:18 | 只看该作者
F407的双路CAN没有使用过,F105的双路CAN调试时也出现你的问题。解决的方案是详细查看寄存器配置,是CAN配置寄存器没有搞懂。

使用特权

评论回复
地板
lvyunzeng| | 2021-5-22 09:20 | 只看该作者
void MX_CAN1_filter_Init(void)
{
        CAN_FilterConfTypeDef  sFilterConfig;  
  //======CAN1过滤器 0 初始化======
  sFilterConfig.FilterNumber = 0;                    //过滤器组0
  sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;  //工作在标识符屏蔽位模式
  sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; //过滤器位宽为单个32位。
  //===使能报文标示符过滤器按照标示符的内容进行比对过滤,扩展ID不是如下的就抛弃掉,是的话,会存入FIFO0。
  sFilterConfig.FilterIdHigh         = (((uint32_t)(0x0A490000 + chouti_ID )<<3)&0xFFFF0000)>>16;                                //要过滤的ID高位
  sFilterConfig.FilterIdLow          = (((uint32_t)(0x0A490000 + chouti_ID )<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF; //要过滤的ID低位
  sFilterConfig.FilterMaskIdHigh     = 0x0000;                        //过滤器高16位每位必须匹配
  sFilterConfig.FilterMaskIdLow      = 0x0000;                        //过滤器低16位每位必须匹配
  sFilterConfig.FilterFIFOAssignment = 0;           //过滤器被关联到FIFO 0  
  sFilterConfig.FilterActivation = ENABLE;          //使能过滤器
  sFilterConfig.BankNumber = 10;
  HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig);
       
//          //======CAN1过滤器 1 初始化======
//  sFilterConfig.FilterNumber = 1;                    //过滤器组0
//  sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;  //工作在标识符屏蔽位模式
//  sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; //过滤器位宽为单个32位。
//  //===使能报文标示符过滤器按照标示符的内容进行比对过滤,扩展ID不是如下的就抛弃掉,是的话,会存入FIFO0。
//  sFilterConfig.FilterIdHigh         = (((uint32_t)(0x08C90000 + chouti_ID )<<3)&0xFFFF0000)>>16;                                //要过滤的ID高位
//  sFilterConfig.FilterIdLow          = (((uint32_t)(0x08C90000 + chouti_ID )<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF; //要过滤的ID低位
//  sFilterConfig.FilterMaskIdHigh     = 0xFFFF;                        //过滤器高16位每位必须匹配
//  sFilterConfig.FilterMaskIdLow      = 0x8000;                        //过滤器低16位每位必须匹配
//  sFilterConfig.FilterFIFOAssignment = 0;           //过滤器被关联到FIFO 0  
//  sFilterConfig.FilterActivation = ENABLE;          //使能过滤器
//  sFilterConfig.BankNumber = 10;
//  HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig);
//       
//          //======CAN1过滤器 2 初始化======
//  sFilterConfig.FilterNumber = 2;                    //过滤器组0
//  sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;  //工作在标识符屏蔽位模式
//  sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; //过滤器位宽为单个32位。
//  //===使能报文标示符过滤器按照标示符的内容进行比对过滤,扩展ID不是如下的就抛弃掉,是的话,会存入FIFO0。
//  sFilterConfig.FilterIdHigh         = (((uint32_t)(0x02490000 + chouti_ID )<<3)&0xFFFF0000)>>16;                                //要过滤的ID高位
//  sFilterConfig.FilterIdLow          = (((uint32_t)(0x02490000 + chouti_ID )<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF; //要过滤的ID低位
//  sFilterConfig.FilterMaskIdHigh     = 0xFFFF;                        //过滤器高16位每位必须匹配
//  sFilterConfig.FilterMaskIdLow      = 0x8000;                        //过滤器低16位每位必须匹配
//  sFilterConfig.FilterFIFOAssignment = 0;           //过滤器被关联到FIFO 0  
//  sFilterConfig.FilterActivation = ENABLE;          //使能过滤器
//  sFilterConfig.BankNumber = 10;
//  HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig);
//       
//          //======CAN1过滤器 3 初始化======
//  sFilterConfig.FilterNumber = 3;                    //过滤器组0
//  sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;  //工作在标识符屏蔽位模式
//  sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; //过滤器位宽为单个32位。
//  //===使能报文标示符过滤器按照标示符的内容进行比对过滤,扩展ID不是如下的就抛弃掉,是的话,会存入FIFO0。
//  sFilterConfig.FilterIdHigh         = (((uint32_t)(0X00C90000 + chouti_ID )<<3)&0xFFFF0000)>>16;                                //要过滤的ID高位
//  sFilterConfig.FilterIdLow          = (((uint32_t)(0X00C90000 + chouti_ID )<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF; //要过滤的ID低位
//  sFilterConfig.FilterMaskIdHigh     = 0xFFFF;                        //过滤器高16位每位必须匹配
//  sFilterConfig.FilterMaskIdLow      = 0x8000;                        //过滤器低16位每位必须匹配
//  sFilterConfig.FilterFIFOAssignment = 0;           //过滤器被关联到FIFO 0  
//  sFilterConfig.FilterActivation = ENABLE;          //使能过滤器
//  sFilterConfig.BankNumber = 10;
//  HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig);
//       
//       
//       
       
       


       

}       

//=============================================================================
//函 数 名: void MX_CAN2_filter_Init(void);
//功 能   : //------   CAN1 滤波程序段 ------
//入口参数: MX_CAN1_filter_Init( ); //------   CAN1 滤波程序段 ------
//出口参数: 无
//返 回 值: 无
//=============================================================================
void MX_CAN2_filter_Init(void)
{
        CAN_FilterConfTypeDef  sFilterConfig;  
       
   //======CAN2过滤器 0 初始化======
  sFilterConfig.FilterNumber = 11;                    //过滤器组0
  sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;  //工作在标识符屏蔽位模式
  sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; //过滤器位宽为单个32位。
  //===使能报文标示符过滤器按照标示符的内容进行比对过滤,扩展ID不是如下的就抛弃掉,是的话,会存入FIFO0。
  sFilterConfig.FilterIdHigh         = (((uint32_t)(0x0A490000 + chouti_ID )<<3)&0xFFFF0000)>>16;                                //要过滤的ID高位
  sFilterConfig.FilterIdLow          = (((uint32_t)(0x0A490000 + chouti_ID )<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF; //要过滤的ID低位
  sFilterConfig.FilterMaskIdHigh     = 0xFFFF;                        //过滤器高16位每位必须匹配
  sFilterConfig.FilterMaskIdLow      = 0x8000;                        //过滤器低16位每位必须匹配
  sFilterConfig.FilterFIFOAssignment = 0;           //过滤器被关联到FIFO 0  
  sFilterConfig.FilterActivation = ENABLE;          //使能过滤器
  sFilterConfig.BankNumber = 10;
  HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig);
       
          //======CAN2过滤器 1 初始化======
  sFilterConfig.FilterNumber = 12;                    //过滤器组0
  sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;  //工作在标识符屏蔽位模式
  sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; //过滤器位宽为单个32位。
  //===使能报文标示符过滤器按照标示符的内容进行比对过滤,扩展ID不是如下的就抛弃掉,是的话,会存入FIFO0。
  sFilterConfig.FilterIdHigh         = (((uint32_t)(0x08C90000 + chouti_ID )<<3)&0xFFFF0000)>>16;                                //要过滤的ID高位
  sFilterConfig.FilterIdLow          = (((uint32_t)(0x08C90000 + chouti_ID )<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF; //要过滤的ID低位
  sFilterConfig.FilterMaskIdHigh     = 0xFFFF;                        //过滤器高16位每位必须匹配
  sFilterConfig.FilterMaskIdLow      = 0x8000;                        //过滤器低16位每位必须匹配
  sFilterConfig.FilterFIFOAssignment = 0;           //过滤器被关联到FIFO 0  
  sFilterConfig.FilterActivation = ENABLE;          //使能过滤器
  sFilterConfig.BankNumber = 10;
  HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig);
       
          //======CAN2过滤器 2 初始化======
  sFilterConfig.FilterNumber = 13;                    //过滤器组0
  sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;  //工作在标识符屏蔽位模式
  sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; //过滤器位宽为单个32位。
  //===使能报文标示符过滤器按照标示符的内容进行比对过滤,扩展ID不是如下的就抛弃掉,是的话,会存入FIFO0。
  sFilterConfig.FilterIdHigh         = (((uint32_t)(0x02490000 + chouti_ID )<<3)&0xFFFF0000)>>16;                                //要过滤的ID高位
  sFilterConfig.FilterIdLow          = (((uint32_t)(0x02490000 + chouti_ID )<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF; //要过滤的ID低位
  sFilterConfig.FilterMaskIdHigh     = 0xFFFF;                        //过滤器高16位每位必须匹配
  sFilterConfig.FilterMaskIdLow      = 0x8000;                        //过滤器低16位每位必须匹配
  sFilterConfig.FilterFIFOAssignment = 0;           //过滤器被关联到FIFO 0  
  sFilterConfig.FilterActivation = ENABLE;          //使能过滤器
  sFilterConfig.BankNumber = 10;
  HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig);
       
          //======CAN2过滤器 3 初始化======
  sFilterConfig.FilterNumber = 14;                    //过滤器组0
  sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;  //工作在标识符屏蔽位模式
  sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; //过滤器位宽为单个32位。
  //===使能报文标示符过滤器按照标示符的内容进行比对过滤,扩展ID不是如下的就抛弃掉,是的话,会存入FIFO0。
  sFilterConfig.FilterIdHigh         = (((uint32_t)(0X00C90000 + chouti_ID )<<3)&0xFFFF0000)>>16;                                //要过滤的ID高位
  sFilterConfig.FilterIdLow          = (((uint32_t)(0X00C90000 + chouti_ID )<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF; //要过滤的ID低位
  sFilterConfig.FilterMaskIdHigh     = 0xFFFF;                        //过滤器高16位每位必须匹配
  sFilterConfig.FilterMaskIdLow      = 0x8000;                        //过滤器低16位每位必须匹配
  sFilterConfig.FilterFIFOAssignment = 0;           //过滤器被关联到FIFO 0  
  sFilterConfig.FilterActivation = ENABLE;          //使能过滤器
  sFilterConfig.BankNumber = 10;
  HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig);
       
       
}       


使用特权

评论回复
5
lvyunzeng| | 2021-5-22 09:21 | 只看该作者
当时CAN的滤波配置

使用特权

评论回复
6
zchong| | 2021-5-22 09:32 | 只看该作者
看看总线有没有啥错误,TEC有没有增加

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

77

主题

328

帖子

2

粉丝