微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 关于STM32F107 CAN总线问题的请教

关于STM32F107 CAN总线问题的请教

时间:10-02 整理:3721RD 点击:

你好,我想请教下STM32F107 里面CAN总线问题,这个问题困扰了我好久。
项目里面有3个CAN节点,其中2个节点(假如标识符为0和1)需要同时向第三个节点(标识符701)发送数据,但是第三个节点只能接收到标识符为0的节点数据,1的数据接收不到。  但是如果两个节点分别向第三个节点发送数据是没有问题的。 第三块板的功能是将CAN收到的数据通过USB传给上位机,我是通过BUS-HOUND软件来抓包的。

CAN总线不是有总线仲裁吗?先接收优先级较高节点的数据,然后接收优先级低节点的数据。均已设置为自动重发。   为什么会接收不到标识符为1节点的数据呢?


程序如下:
节点1程序如下:
void CAN_Config(void)
{
  /* CAN register init */
  CAN_DeInit(CAN1);
  CAN_StructInit(&CAN_InitStructure);
  /* CAN1 cell init */
  CAN_InitStructure.CAN_TTCM = DISABLE;  //禁止时间触发
  CAN_InitStructure.CAN_ABOM = DISABLE;  
  CAN_InitStructure.CAN_AWUM = DISABLE;
  CAN_InitStructure.CAN_NART = DISABLE;   //自动重传
  CAN_InitStructure.CAN_RFLM = DISABLE;    //失能FIFO锁定模式
  CAN_InitStructure.CAN_TXFP = DISABLE;
  CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
  CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;   //500k波特率
  CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;
  CAN_InitStructure.CAN_BS2 = CAN_BS2_1tq;
  CAN_InitStructure.CAN_Prescaler = 9;
  CAN_Init(CAN1, &CAN_InitStructure);
  /* CAN1 filter init */
  CAN_FilterInitStructure.CAN_FilterNumber = 0;
  CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
  CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
  CAN_FilterInitStructure.CAN_FilterIdHigh = 0xe020;      //通讯板11位标准标准符0x701
  CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;  
  CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFFF;
  CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xFFFF;
  CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
  CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
  CAN_FilterInit(&CAN_FilterInitStructure);
  CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);//使能指定的CAN中断
   /*CAN发送数据格式配置*/
  TxMessage.StdId =0;   
  TxMessage.ExtId = 0;
  TxMessage.RTR = CAN_RTR_DATA;
  TxMessage.IDE = CAN_ID_STD;
  TxMessage.DLC = 8;
}

——————————————————————————————————————————————————————————
节点2程序如下:
和节点1的相同,只是  TxMessage.StdId =1;
——————————————————————————————————————————————————————————

节点3程序如下:
void CAN_Config(void)
{
  /* CAN register init */
  CAN_DeInit(CAN2);
  CAN_StructInit(&CAN_InitStructure);
  /* CAN1 cell init */
  CAN_InitStructure.CAN_TTCM = DISABLE;
  CAN_InitStructure.CAN_ABOM = DISABLE;
  CAN_InitStructure.CAN_AWUM = DISABLE;
  CAN_InitStructure.CAN_NART = DISABLE;   //自动重传
  CAN_InitStructure.CAN_RFLM = DISABLE;
  CAN_InitStructure.CAN_TXFP = DISABLE;
  CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;        
  CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;           //500K 波特率
  CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;
  CAN_InitStructure.CAN_BS2 = CAN_BS2_1tq;
  CAN_InitStructure.CAN_Prescaler = 9;
  CAN_Init(CAN2, &CAN_InitStructure);
  /* CAN2 filter init */
  CAN_FilterInitStructure.CAN_FilterNumber = 14;
  CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;              //过滤一组标识符出来
  CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
  CAN_FilterInitStructure.CAN_FilterIdHigh =(((u32)0x0<<21)&0xffff0000)>>16;                //过滤标准数据帧
  CAN_FilterInitStructure.CAN_FilterIdLow = (((u32)0x0<<21)|CAN_ID_STD|CAN_RTR_DATA)&0xffff;
  CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xffdf;  
  CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xffff;  
  CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
  CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
  CAN_FilterInit(&CAN_FilterInitStructure);
  CAN_ITConfig(CAN2, CAN_IT_FMP0, ENABLE);
  TxMessage.StdId =0x701;
  TxMessage.ExtId = 0;
  TxMessage.RTR = CAN_RTR_DATA;
  TxMessage.IDE = CAN_ID_STD;
  TxMessage.DLC = 8;
}

节点3CAN中断接收程序如下:
void CAN2_RX0_IRQHandler(void)     //CAN中断处理函数
{
  //清空can接收缓存
  CanRxMsg RxMessage;
  RxMessage.StdId=0x00;
  RxMessage.ExtId=0x00;
  RxMessage.IDE=0;
  RxMessage.DLC=0;
  RxMessage.FMI=0;
  CAN_Receive(CAN2, CAN_FIFO0, &RxMessage);
if ((RxMessage.Data[0] =='F')&&(RxMessage.IDE == CAN_ID_STD))
  {
  Send_Buffer[0]=RxMessage.Data[0];
  Send_Buffer[1]=RxMessage.Data[1];
  Send_Buffer[2]=RxMessage.Data[2];
  Send_Buffer[3]=RxMessage.Data[3];
  Send_Buffer[4]=RxMessage.Data[4];
  Send_Buffer[5]=RxMessage.Data[5];
  Send_Buffer[6]=RxMessage.Data[6];
  Send_Buffer[7]=RxMessage.Data[7];
  USB_SIL_Write(EP1_IN, (uint8_t*)Send_Buffer, 8);   // 向USB写入数据
  #ifndef STM32F10X_CL
  SetEPTxValid(ENDP1);
  #endif
  Send_Update = 1;
  }
}

网上大多是2个CAN节点的,很简单。很少有3个以及以上的。查看了几天,即使有3个也是主从机才有轮询方法,并不是同时发数据。 多从机冲突怎么解决?

大神们,你们都不会吗?
假设两个节点同时发送数据,A节点发送的前3个位是100,B节点为101,在前2个位发送完毕的时候,两个节点都会认为自己发送成功,但是当发送到第三个位的时候,B节点会失去仲裁,因为0的优先级高于1的优先级,B节点监听到总线上不是1,因此失去仲裁,等待重新发送数据。
问题就是低优先级节点没有重发数据?是因为高优先级节点一直占用着总线吗?

好吧,遇到了同样的问题,小编问题解决了没?

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top