打印

STM32里CAN总线的问题

[复制链接]
5718|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wukon|  楼主 | 2013-8-23 20:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
小弟是一名新手,对CAN里的通信的ID和屏蔽码还有验收码搞不懂,求大大们指导!
发送程序中的stdid是不是只要和接收程序中过滤器的id一样就行了,还是说过滤器的id是经过一定的协议转换以后得到的??


CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterIdLow = 0x01e5;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xffff;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xffff;
沙发
0331631| | 2013-8-24 09:14 | 只看该作者
个人理解有点类似modbus 的站台号!

使用特权

评论回复
板凳
feilusia| | 2013-8-24 16:07 | 只看该作者
本帖最后由 feilusia 于 2013-8-24 16:11 编辑

不是这么简单用的,我几个月前才写STM8的CAN,当时搞了1个星期搞的很清楚,现在又忘了,忒悲剧了……
貌似是酱紫的,看那张图,假设你用的是1个32位的过滤器。
那么,如果你用的是标准格式的,就是11位的ID,那这个ID是存在STID里,也就是图中的最高的那几位。
如果你用的是扩展帧格式的,那么就是29位的ID,那这个ID就是存在EXID,也就是从第3位开始的中间那一段。
而屏蔽码也要跟ID地址对应起来,把不想验证的位数屏蔽掉,一般这个要可由用户来设置。
至于验收码,我已经忘了是什么东西了。

QQ截图20130824155807.jpg (16.93 KB )

QQ截图20130824155807.jpg

使用特权

评论回复
地板
wukon|  楼主 | 2013-8-24 22:48 | 只看该作者
feilusia 发表于 2013-8-24 16:07
不是这么简单用的,我几个月前才写STM8的CAN,当时搞了1个星期搞的很清楚,现在又忘了,忒悲剧了……
貌似 ...

CAN_DeInit(CAN1);
CAN_InitStructure.CAN_TTCM=DISABLE;//禁止时间触发通信模式
CAN_InitStructure.CAN_ABOM=DISABLE;//软件对CAN_MCR寄存器的INRQ位进行置1随后清0后,一旦硬件检测到128次11位连续的隐性位,就退出离线状态。
CAN_InitStructure.CAN_AWUM=DISABLE;//睡眠模式通过清除CAN_MCR寄存器的SLEEP位,由软件唤醒
CAN_InitStructure.CAN_NART=ENABLE;//CAN报文只被发送1次,不管发送的结果如何(成功、出错或仲裁丢失)
CAN_InitStructure.CAN_RFLM=DISABLE;//在接收溢出时FIFO未被锁定,当接收FIFO的报文未被读出,下一个收到的报文会覆盖原有的报文
CAN_InitStructure.CAN_TXFP=DISABLE;//发送FIFO优先级由报文的标识符来决定
   CAN_InitStructure.CAN_Mode=CAN_Mode_Normal; //CAN硬件工作在正常模式
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;//重新同步跳跃宽度1个时间单位
CAN_InitStructure.CAN_BS1=CAN_BS1_8tq;//时间段1为8个时间单位
CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;//时间段2为7个时间单位
CAN_InitStructure.CAN_Prescaler = 9; //(pclk1/((1+8+7)*9)) = 36Mhz/16/9 = 250Kbits设定了一个时间单位的长度9
CAN_Init(CAN1,&CAN_InitStructure);
   RxMessage.StdId=0x05;
  RxMessage.IDE=CAN_ID_STD;
  RxMessage.RTR=CAN_RTR_DATA;
  CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = (0x0005<<5);
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);

这么设置也不行。目标接收到0xff,led灯亮一下。我用CAN_BUS做发送端

使用特权

评论回复
5
vacky| | 2013-8-26 09:35 | 只看该作者
我没记错的话,应该CAN_FilterIdHigh+CAN_FilterIdLow是你要对比的位,CAN_FilterMaskIdHigh+CAN_FilterMaskIdLow是对比位的值,比如你设置的CAN_FilterIdHigh+CAN_FilterIdLow为(0x0005<<5)+0x0000=0x00A00000,那么你的要检测的就是帧ID的第27位和25位,另外设置了CAN_FilterMaskIdHigh+CAN_FilterMaskIdLow为OxFFFFFFFF, 1有效,所以当你发送0x00A00000的帧ID时才能接受到数据。

使用特权

评论回复
6
杨爱林林| | 2013-8-26 10:00 | 只看该作者
这个主要是看你filter的配置了
用库函数  其他的都很好配置
你可以先试着  不设置filter屏蔽什么的
也就是  这样的
CAN_FilterInitTypeDef  CAN_FilterInitStructure;
  
  CAN_FilterInitStructure.CAN_FilterNumber = Num;//0-13
  CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
  CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
  CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;//CAN_FilterIdH(CAN_ID);
  CAN_FilterInitStructure.CAN_FilterIdLow= 0x0000;//CAN_FilterIdL(CAN_ID);
  CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;//0xffff;//((msk<<1)&0xFFFF0000)>>16;
  CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;//0xffff;//(msk<<1)&0xFFFF;
  CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO;
  CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
  CAN_FilterInit(&CAN_FilterInitStructure);
然后在接收程序中自己判断 自己想要的标识符

CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;//0xffff;//((msk<<1)&0xFFFF0000)>>16;
  CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;//0xffff;//(msk<<1)&0xFFFF;
这两句的意思是
不管你接收到什么样的标识符  都接收   也就是  取消了硬件屏蔽

使用特权

评论回复
7
trumpxp| | 2013-8-26 19:15 | 只看该作者
这一块   这种协议   吃的不透   需要花时间   仔细钻研钻研   这一块   感觉自己的差距很大啊

使用特权

评论回复
8
wukon|  楼主 | 2013-8-27 16:21 | 只看该作者
问题解决了,贴一下自己的代码吧
void CAN_Configuration(void)
{                                       
        CAN_DeInit(CAN1);       
        CAN_InitStructure.CAN_TTCM=DISABLE;//禁止时间触发通信模式
        CAN_InitStructure.CAN_ABOM=DISABLE;//软件对CAN_MCR寄存器的INRQ位进行置1随后清0后,一旦硬件检测到128次11位连续的隐性位,就退出离线状态。
        CAN_InitStructure.CAN_AWUM=DISABLE;//睡眠模式通过清除CAN_MCR寄存器的SLEEP位,由软件唤醒
        CAN_InitStructure.CAN_NART=ENABLE;//CAN报文只被发送1次,不管发送的结果如何(成功、出错或仲裁丢失)
        CAN_InitStructure.CAN_RFLM=DISABLE;//在接收溢出时FIFO未被锁定,当接收FIFO的报文未被读出,下一个收到的报文会覆盖原有的报文
        CAN_InitStructure.CAN_TXFP=DISABLE;//发送FIFO优先级由报文的标识符来决定
          CAN_InitStructure.CAN_Mode=CAN_Mode_Normal; //CAN硬件工作在正常模式
        CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;//重新同步跳跃宽度1个时间单位
        CAN_InitStructure.CAN_BS1=CAN_BS1_8tq;//时间段1为8个时间单位
        CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;//时间段2为7个时间单位
        CAN_InitStructure.CAN_Prescaler = 9; //(pclk1/((1+8+7)*9)) = 36Mhz/16/9 = 250Kbits设定了一个时间单位的长度9
        CAN_Init(CAN1,&CAN_InitStructure);



        CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
        CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
        CAN_FilterInitStructure.CAN_FilterIdHigh = ((0x000000aa<<3)&0xffff0000)>>16;
        CAN_FilterInitStructure.CAN_FilterIdLow =((0x000000aa<<3)|(0x00000004))&0xffff;
        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);                  //过滤器初始化,所有报文都接收,邮箱为FIFO0。
}

使用特权

评论回复
9
wukon|  楼主 | 2013-8-27 16:23 | 只看该作者
blog。chinaunix。net/uid-21658993-id-3027673。html
关于过滤器设置看这个,会特别清楚,希望大伙儿以后也少走弯路。解决问题了,神清气爽呀

使用特权

评论回复
10
cjhk| | 2013-8-27 19:00 | 只看该作者
问题解决了就好   谢谢了  楼主   谢谢你将自己的解决方法贴出来   这样以后大家如果遇到同样的问题   就比较方便了

使用特权

评论回复
11
yousi2180| | 2013-11-27 15:47 | 只看该作者
wukon 发表于 2013-8-27 16:23
blog。chinaunix。net/uid-21658993-id-3027673。html
关于过滤器设置看这个,会特别清楚,希望大伙儿以后 ...

恭喜啊。

使用特权

评论回复
12
lz80650904| | 2014-12-26 22:38 | 只看该作者
wukon 发表于 2013-8-27 16:21
问题解决了,贴一下自己的代码吧
void CAN_Configuration(void)
{                                       

你好!我现在在调试CAN也遇到些问题未解决,主要是无法进入接收中断,可以留个联系方式交流么?? 我QQ:19152072 ,邮箱lz80650904@126.com

使用特权

评论回复
13
kfliuyan| | 2014-12-28 19:32 | 只看该作者
支持一下

使用特权

评论回复
14
白丁野老| | 2014-12-30 21:23 | 只看该作者
了解一下

使用特权

评论回复
15
dammon| | 2016-3-4 16:22 | 只看该作者
发送程序中的stdid是不是只要和接收程序中过滤器的id一样。。。我也想请教跟您一样的问题。。。

使用特权

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

本版积分规则

5

主题

11

帖子

0

粉丝