打印

关于CAN总线,是如何编写一套ID以及过滤码呢?

[复制链接]
3608|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
goodluck09876|  楼主 | 2016-6-20 11:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
goodluck09876|  楼主 | 2016-6-20 11:37 | 只看该作者
是不是有一套类似的软件,可以自动生成一系列的规范呢?

使用特权

评论回复
板凳
make8419247| | 2016-6-20 15:24 | 只看该作者
没有,根据你的实际需要来设置

使用特权

评论回复
地板
xiaolong12| | 2016-6-20 17:43 | 只看该作者
应该有现成的协议可以移植的吧

使用特权

评论回复
5
maninman1981| | 2016-6-26 16:39 | 只看该作者
数据手册中已经讲得很详细了,官方还有相应的例程的。

使用特权

评论回复
6
rmbass| | 2016-6-26 22:52 | 只看该作者
在CAN协议里,报文的标识符不代表节点的地址,而是跟报文的内容相关的。因此,发送者以广播的形式把报文发送给所有的接收者。节点在接收报文时,根据标识符(CAN ID)的值决定软件是否需要该报文;如果需要,就拷贝到SRAM里;如果不需要,报文就被丢弃且无需软件的干预。
为满足这一需求,bxCAN为应用程序提供了14个位宽可变的、可配置的过滤器组(13~0),以便只接收那些软件需要的报文。硬件过滤的做法节省了CPU开销,否则就必须由软件过滤从而占用一定的CPU开销。每个过滤器组x由2个32位寄存器,CAN_FxR0和CAN_FxR1组成。

使用特权

评论回复
7
yysforever| | 2016-6-27 14:43 | 只看该作者
CAN总线传送到数据是基于消息而不是地址的,每个消息用不同的编号表达(2.0A用11位、2.0B用29位)。在CAN上进行简单传送而自定义传送协议时,要把所有需要传送的命令列出,然后根据传送的紧急程度(优先级)从高到低进行排序,然后把最高优先级的设定一个最低的编号、以此类推...最低优先级的设定最高的编号。因为CAN物理上是不分主从,所以当有几个站点同时发送而发生碰撞时,编号最低的将优先传送。 从总线上接收消息:每个站点可能只对所有协议中的几个消息感兴趣,CAN初始化时,在过滤器中设置本站点需要接收的消息编号,这样一旦总线上有需要的消息将会自动接收,并产生中断,通知CPU收到新消息,CPU在中断程序中接收、处理。 发送消息到总线上:CAN初始化时设置本站点将来需要发送的消息编号。

使用特权

评论回复
8
冰是睡着的冰| | 2016-6-27 16:09 | 只看该作者
现场总线CAN原理与应用,你可以找这本书看看,里面有很详细的介绍的

使用特权

评论回复
9
jouney316| | 2016-6-28 07:38 | 只看该作者
//主机这边的过滤器设置
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位。
/* 使能报文标示符过滤器按照标示符的内容进行比对过滤,扩展ID不是如下的就抛弃掉,是的话,会存入FIFO0。 */

    CAN_FilterInitStructure.CAN_FilterIdHigh= (((u32)0x1314<<3)&0xFFFF0000)>>16;        //要过滤的ID高位
    CAN_FilterInitStructure.CAN_FilterIdLow= (((u32)0x1314<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF; //要过滤的ID低位 CAN_ID_EXT=0x00000004;CAN_RTR_DATA=0x00000000;
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh= 0xFFFF;        //过滤器高16位每位必须匹配
    CAN_FilterInitStructure.CAN_FilterMaskIdLow= 0xFFFF;        //过滤器低16位每位必须匹配
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0 ;        //过滤器被关联到FIFO0
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;        //使能过滤器
CAN_FilterInit(&CAN_FilterInitStructure);
/*CAN通信中断使能*/
CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
}
//从机的发送配置
void CAN_SetMsg(void)
{  
  TxMessage.ExtId=0x1314;        //使用的扩展ID
  TxMessage.IDE=CAN_ID_EXT;        //扩展模式
  TxMessage.RTR=CAN_RTR_DATA;        //发送的是数据
  TxMessage.DLC=2;        //数据长度为2字节
  TxMessage.Data[0]=0xDC;
  TxMessage.Data[1]=0xBA;
}

使用特权

评论回复
10
yanyanyan168| | 2016-6-28 17:18 | 只看该作者
本帖最后由 yanyanyan168 于 2016-6-28 17:20 编辑

stm32f10x can过滤器计算工具 .zip (276.64 KB) 不是作者,来源于网络,没有验证过。楼主慎用。

使用特权

评论回复
11
l科科1987| | 2016-6-28 20:40 | 只看该作者
看手册里有关该模式过滤寄存器的每位含义,最低三位是IDE RTR和 0,前面高位是标识符

使用特权

评论回复
12
原味_郭| | 2016-6-29 08:50 | 只看该作者
举个例子吧,过滤器长度为32位,模式为屏蔽模式,假如我要发送的标示符为0x1314;那过滤器设置如下
一、过滤器完全无效 接收到的标示符全部通过
   0x1314 二进制码: 0000 0000 0000 0000 0001 0011 0001 0100
   CAN_Filter        xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
   CAN_FilterMask    0000 0000 0000 0000 0000 0000 0000 0000
因为 CAN_FilterMask屏蔽寄存器所有位都是0 ,对应标示符全为“不关心”,也就是接收到数据的ID(标示符)不用与 CAN_Filter寄存器的任何一位进行匹配。

使用特权

评论回复
13
ahhsyf| | 2016-6-29 15:07 | 只看该作者
在CAN协议里,报文的标识符不代表节点的地址,而是跟报文的内容相关的。因此,发送者以广播的形式把报文发送给所有的接收者。节点在接收报文时,根据标识符(CAN ID)的值决定软件是否需要该报文;如果需要,就拷贝到SRAM里;如果不需要,报文就被丢弃且无需软件的干预。

使用特权

评论回复
14
myidear| | 2016-6-30 09:53 | 只看该作者
stm32的can总线的配置如下:
      CAN_InitStructure.CAN_TTCM=DISABLE;//禁止时间触发通信模式
      CAN_InitStructure.CAN_ABOM=DISABLE;
      CAN_InitStructure.CAN_AWUM=DISABLE;
      CAN_InitStructure.CAN_NART=DISABLE;//CAN报文只被发送1次,不管发送的结果如何(成功、出错或仲裁丢失)
      CAN_InitStructure.CAN_RFLM=DISABLE;
      CAN_InitStructure.CAN_TXFP=DISABLE;
      CAN_InitStructure.CAN_Mode=CAN_Mode_Normal;
      //CAN_Mode_LoopBack
      //CAN_Mode_Normal
      CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;
      CAN_InitStructure.CAN_BS1=CAN_BS1_5tq;//1--16
      CAN_InitStructure.CAN_BS2=CAN_BS2_2tq;//1--8
      CAN_InitStructure.CAN_Prescaler=2;

      CAN_Init(&CAN_InitStructure);
       /* CAN filter init */
      CAN_FilterInitStructure.CAN_FilterNumber=0;//选择过滤器0
      CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;//指定过滤器被设置为标识符屏蔽模式
      CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;//给出过滤器位宽为32位

下面根据设置的参数不同来决定can总线can总线的配置情况:
1、对扩展数据帧进行过滤:(只接收扩展数据帧)
      CAN_FilterInitStructure.CAN_FilterIdHigh   = (((u32)slave_id<<3)&0xFFFF0000)>>16;
      CAN_FilterInitStructure.CAN_FilterIdLow   = (((u32)slave_id<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF;
      CAN_FilterInitStructure.CAN_FilterMaskIdHigh  = 0xFFFF;
      CAN_FilterInitStructure.CAN_FilterMaskIdLow   = 0xFFFF;
(注:标准帧数据帧、标准远程帧和扩展远程帧均被过滤)
2、对扩展远程帧过滤:(只接收扩展远程帧)
      CAN_FilterInitStructure.CAN_FilterIdHigh   = (((u32)slave_id<<3)&0xFFFF0000)>>16;
      CAN_FilterInitStructure.CAN_FilterIdLow   = (((u32)slave_id<<3)|CAN_ID_EXT|CAN_RTR_REMOTE)&0xFFFF;
      CAN_FilterInitStructure.CAN_FilterMaskIdHigh  = 0xFFFF;
      CAN_FilterInitStructure.CAN_FilterMaskIdLow   = 0xFFFF;
3、对标准远程帧过滤:(只接收标准远程帧)
      CAN_FilterInitStructure.CAN_FilterIdHigh   = (((u32)slave_id<<21)&0xffff0000)>>16;
      CAN_FilterInitStructure.CAN_FilterIdLow   = (((u32)slave_id<<21)|CAN_ID_STD|CAN_RTR_REMOTE)&0xffff;
      CAN_FilterInitStructure.CAN_FilterMaskIdHigh  = 0xFFFF;
      CAN_FilterInitStructure.CAN_FilterMaskIdLow   = 0xFFFF;
4、对标准数据帧过滤:(只接收标准数据帧)
      CAN_FilterInitStructure.CAN_FilterIdHigh   = (((u32)slave_id<<21)&0xffff0000)>>16;
      CAN_FilterInitStructure.CAN_FilterIdLow   = (((u32)slave_id<<21)|CAN_ID_STD|CAN_RTR_DATA)&0xffff;
      CAN_FilterInitStructure.CAN_FilterMaskIdHigh  = 0xFFFF;
      CAN_FilterInitStructure.CAN_FilterMaskIdLow   = 0xFFFF;
5、对扩展帧进行过滤:(扩展帧不会被过滤掉)
      CAN_FilterInitStructure.CAN_FilterIdHigh   = (((u32)slave_id<<3)&0xFFFF0000)>>16;
      CAN_FilterInitStructure.CAN_FilterIdLow   = (((u32)slave_id<<3)|CAN_ID_EXT)&0xFFFF;
      CAN_FilterInitStructure.CAN_FilterMaskIdHigh  = 0xFFFF;
      CAN_FilterInitStructure.CAN_FilterMaskIdLow   = 0xFFFC;
6、对标准帧进行过滤:(标准帧不会被过滤掉)
      CAN_FilterInitStructure.CAN_FilterIdHigh   = (((u32)slave_id<<21)&0xffff0000)>>16;
      CAN_FilterInitStructure.CAN_FilterIdLow   = (((u32)slave_id<<21)|CAN_ID_STD)&0xffff;
      CAN_FilterInitStructure.CAN_FilterMaskIdHigh  = 0xFFFF;
      CAN_FilterInitStructure.CAN_FilterMaskIdLow   = 0xFFFC;
注:slave_id为要过滤的id号。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

220

主题

5843

帖子

22

粉丝