CAN总线结构示意图:
说明: 1:CAN收发器(示意图中的单元)根据两总线CAN_H和CAN_L的电位差来判断总线电平;
2:实际中CAN_H与CAN_L由双绞线组成;
3:数据传递终端的电阻器,是为了避免数据传输反射回来,使数据遭到破坏;
4:电阻阻值为120Ω;
5:CAN通信实际上为单元之间的数据传输
CAN通信单元的组成:
每个通信单元软件部分由数据帧、遥控帧、错误帧、过载帧、帧间隔组成;但不是上述5种帧都包含,具体看软件怎样编写
1 数据帧的发送
1) 数据帧的组成(遥控帧与数据帧的组成类似,只是不包含数据帧的数据段)
2)STM32软件编写发送数据帧及解释(遥控帧与数据帧的组成类似,只是不包含数据帧的数据段)
u8 CAN_Send_Msg(u8* msg,u8 len)
{
u8 mbox;
u16 i=0;
CanTxMsg TxMessage; //结构体的具体元素可查找STM32数据库手册
TxMessage.StdId=0x12; //报文的11位标准标识符,范围0x000~0x7FF (设置数据帧的仲裁段的标准表示符)
//TxMessage.ExtId=0x12; //报文的29位扩展标识符,范围0x00000000~0x1FFFFFFF,由于IDE选择为0,此元素可以不设置 (设置数据帧的仲裁段的扩展标识符)
TxMessage.IDE=0; // IDE 0:选择使用标准标识符 1:选择使用扩展标识符 (设置数据帧的仲裁段的选择)
TxMessage.RTR=0; // RTR 0:选择发送数据帧 1:选择发送遥控帧 (设置数据帧的控制段)
TxMessage.DLC=len; //DLC的大小为发送数据的长度,len最大为8,因为一个报文包含0~8个字节数据 (设置数据帧的控制段)
for(i=0;i<len;i++)
TxMessage.Data[i]=msg[i]; // 给数据帧的数据赋值
mbox= CAN_Transmit(CAN1, &TxMessage);
i=0;
while((CAN_TransmitStatus(CAN1, mbox)==CAN_TxStatus_Failed)&&(i<0XFFF)) //检测数据的发送状态。如果失败,等到i加到0xFFF退出循环,并返回"1";成功则返回"0".
i++;
if(i>=0XFFF)
return 1;
return 0;
}
2 过滤器
在CAN协议里,报文的标识符不代表节点的地址,而是跟报文的内容相关的。因此,发送者以广播的形式把报文发送给所有接受者。节点在接收报文时,根据标识符的值,决定软件
是否需要该报文;如果需要,就拷贝到SRAM里;如果不需要,报文就被丢弃且无需软件的干预。
比如示意图中: 单元1要发送报文,它会将报文发送给单元2、单元3、单元4、单元5,而单元2、单元3、单元4、单元5会根据标识符的值,决定是否接收改报文。
为了知道哪些报文需要接收,哪些需要放弃,所以在此过程中,引入过滤器。通过过滤器来接