关于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,因此失去仲裁,等待重新发送数据。
问题就是低优先级节点没有重发数据?是因为高优先级节点一直占用着总线吗?
好吧,遇到了同样的问题,小编问题解决了没?