STM32 CAN 配置、收发结构定义 留存...

分布式系统项目需要,这次弄个CAN总线来布局,仅见CAN的冰山一角。
本次使用扩展帧模式。


STM32 对CAN的定义–库 CAN结构体定义 说明:

寄存器映射:

typedef struct  
{  
  vu32 MCR;  
  vu32 MSR;  
  vu32 TSR;  
  vu32 RF0R;  
  vu32 RF1R;  
  vu32 IER;  
  vu32 ESR;  
  vu32 BTR;  
  u32  RESERVED0[88];  
  CAN_TxMailBox_TypeDef sTxMailBox[3];  
  CAN_FIFOMailBox_TypeDef sFIFOMailBox[2];  
  u32  RESERVED1[12];  
  vu32 FMR;  
  vu32 FM1R;  
  u32  RESERVED2;  
  vu32 FS1R;  
  u32  RESERVED3;  
  vu32 FFA1R;  
  u32  RESERVED4;  
  vu32 FA1R;  
  u32  RESERVED5[8];  
  CAN_FilterRegister_TypeDef sFilterRegister[14];  
} CAN_TypeDef;

CAN消息发送:

/* CAN Tx message structure definition */  
typedef struct  
{  
  u32 StdId;  
  u32 ExtId;  
  u8 IDE;  
  u8 RTR;  
  u8 DLC;  
  u8 Data[8];  
} CanTxMsg;  

CAN消息接收:

/* CAN Rx message structure definition */  
typedef struct  
{  
  u32 StdId;  
  u32 ExtId;  
  u8 IDE;  
  u8 RTR;  
  u8 DLC;  
  u8 Data[8];  
  u8 FMI;  
} CanRxMsg; 

关于库函数相关结构体的定义,详情对照手册瞅瞅,,,不多说,也说不清。
滤波器设置:基于stm32的can总线彻底研究
对扩展数据帧过滤:
CAN_FilterInitStructure.CAN_FilterNumber = 0;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = (((u32)CAN_ID<<3)&0xFFFF0000)>>16;
CAN_FilterInitStructure.CAN_FilterIdLow= (((u32)CAN_ID<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = ~((u32)CAN_ID <<16); –
CAN_FilterInitStructure.CAN_FilterMaskIdLow = ~((u32)CAN_ID );
对标准数据帧过滤:—没试过,不做说明
CAN_FilterInitStructure.CAN_FilterIdHigh= (((u32)CAN_ID0<<21)&0xFFFF0000)>>16;
CAN_FilterInitStructure.CAN_FilterIdLow=(((u32)CAN_ID0<<21)|CAN_ID_STD|CAN_RTR_DATA)&0xFFFF;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFFF;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xFFFF;


数据收发:—解析

先上我们的协议说明:这里写图片描述
这里只关心红线标注的….
不一一说明啦,上结构

/*定制协议版 扩展帧摘过来的帧头包 */  
typedef struct ExtIdPack{  
  u32 Frame_Sn:4;//帧ID  
  u32 Valid_NB:5;//有效帧个数  
  u32 Echo_Flag_T:1;//发送类型--应答表示,1代表应答回复,0代表主动发送  
  u32 Commond:8;//功能码,命令字。从0x01开始,0x00暂时保留。  
  u32 DeviceID:11;//设备地址  
  //struct ExtIdPack *pNext;  
}ExtIdPackage,*pExtIdPackage;  
extern ExtIdPackage parsing;  
extern pExtIdPackage pParsing;  

typedef struct  
{  
  ExtIdPackage ExtId;  
  u8 IDE;  
  u8 RTR;  
  u8 DLC;  
  u8 Data[8];  
  //u8 FMI;  
} MyCanRxMsg;  

extern MyCanRxMsg myCanRxMsg;  

这样子定义,使用方便很多。
使用eg:

switch(myCanRxMsg.ExtId.Commond)  
  {  
  case 0x01:{   //查询 读取固件版本信息("01")  
    //协议填充...  
    if(myCanRxMsg.DLC){FRAME_RESET();break;} //数据不合规矩,pass  
    myCanRxMsg.DLC=sizeof(GetVersion)/sizeof(u8);  
    memcpy(&myCanRxMsg.Data[0],&GetVersion[0],myCanRxMsg.DLC);  
    memcpy(&TxMessage.ExtId,&myCanRxMsg,sizeof(MyCanRxMsg));//数据拷贝  
    CAN_Transmit(&TxMessage);  
    FRAME_RESET();  
    break;  
  }  
。。。。  

以上,有点乱,,,看着烦躁,赶紧切换页面————别砸电脑@


问:

本打算说说滤波器这块的设置来着–详细的
结果翻手册也没太弄明白 32-bit identifier 32-bit mask 为啥子要<<移动三位,如下。

/* 
 * 函数名:CAN_Filter_Config 
 * 描述  :CAN的过滤器 配置 
 * 输入  :无 
 * 输出  : 无 
 * 调用  :内部调用 
 */  
static void CAN_Filter_Config(void)  
{  
    CAN_FilterInitTypeDef  CAN_FilterInitStructure;  

    /*CAN过滤器初始化*/  
    CAN_FilterInitStructure.CAN_FilterNumber=0;                     //过滤器组0  
    CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;   //工作在标识符屏蔽位模式  
    CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;  //过滤器位宽为单个32位。  

    CAN_FilterInitStructure.CAN_FilterIdHigh= ((u32)0x00140000<<3)>>16;     //要过滤的ID高位     
    CAN_FilterInitStructure.CAN_FilterIdLow= (((u32) 0x00140000<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF; //要过滤的ID低位   
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFEB;          //过滤器高16位每位必须匹配  
    CAN_FilterInitStructure.CAN_FilterMaskIdLow =  0xFFFF;          //过滤器低16位每位必须匹配  

    CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FilterFIFO0;       //过滤器被关联到FIFO0  
    CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;            //使能过滤器  
    CAN_FilterInit(&CAN_FilterInitStructure);  
    /*CAN通信中断使能*/  
    CAN_ITConfig(CAN_IT_FMP0 /*| CAN_IT_FF0 | CAN_IT_FOV0*/, ENABLE);  //  
    CAN_ITConfig(CAN_IT_TME, DISABLE);                // 发送中断  
}  

这里

等待 神 前来说明,叩谢…..
留存…………………

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值