最近在调试stm32f4芯片中,多设备can通信的使用。can通信配置底层程序参考了正点原子can通信相关实验。遇到的问题是,由于can网络上有多个设备,主控芯片在发布命令和接收数据时,需要判断设备的标准数据帧ID。因此改进了正点原子中的can发送及接收函数。具体的代码如下:
//can发送函数,加入了发送数据的标准帧ID
u8 CAN_Send_Msg(u8* msg,u8 len, u32 stdid)
{
u8 mbox;
u16 i=0;
CanTxMsg TxMessage;
TxMessage.StdId=stdid; // 标准标识符为0
TxMessage.ExtId=0; // 设置扩展标示符(29位)
TxMessage.IDE=0; // 使用扩展标识符
TxMessage.RTR=0; // 消息类型为数据帧,一帧8位
TxMessage.DLC=len; // 发送两帧信息
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++; //等待发送结束
if(i>=0XFFF)return 1;
return 0;
}
//can接收函数,加入了判断标准帧ID
u8 CAN_Receive_Msg(u8 *buf, u32 stdid)
{
u32 i;
CanRxMsg RxMessage;
if( CAN_MessagePending(CAN1,CAN_FIFO0)==0)return 0; //没有接收到数据,直接退出
CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);//读取数据
if(RxMessage.StdId!=stdid) return 0;
for(i=0;i<RxMessage.DLC;i++)
buf[i]=RxMessage.Data[i];
return RxMessage.DLC;
}
从实际的测试效果来看,应用改进的can收发函数,可以接收can网络中的各设备数据。包括一直发送数据的can设备及需要命令再有反馈的can设备。另外,在用到stm32f4的CAN2与外部设备进行CAN通信时,初始化配置CAN2,需要使能CAN1和CAN2时钟;且过滤器配置从14开始。