打印
[STM32F2]

江湖救急: 关于CAN接收的问题

[复制链接]
4057|19
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
CAN, pi, gp, GPIO, ni
      小弟刚接触CAN总线,用的STM32F207ZGT6,目前CAN的发送和过滤基本上算搞懂点了,但是在调试过程中遇到个问题,读取FIFO输出邮箱时,不能读取最新送入FIFO的数据,只能读取进入FIFO最早的一帧数据,我是的ST的固件库的接收程序,接收程序里加入了RFOM置位(清邮箱)。调试的时候感觉RFOM置位和CAN_FIFORelease(CAN1, CAN_FIFO0);没用。下面是CAN部分代码。
void CAN_Config(void)//CAN口设置
{
  GPIO_InitTypeDef  GPIO_InitStructure;         //初始化结构体 GPIO_InitStructure

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

  GPIO_PinAFConfig(GPIOA, GPIO_PinSource11,GPIO_AF_CAN1);
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource12,GPIO_AF_CAN1);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;               
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;  
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;   
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;            
  GPIO_Init(GPIOA, &GPIO_InitStructure);      
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);

   CAN_DeInit(CAN1);
  CAN_StructInit(&CAN_InitStructure);

  /* CAN cell init */
  CAN_InitStructure.CAN_TTCM = DISABLE;         //禁止时间触发通信模式
  CAN_InitStructure.CAN_ABOM = DISABLE;         //离线模式管理
  CAN_InitStructure.CAN_AWUM = DISABLE;         //软件唤醒模式
  CAN_InitStructure.CAN_NART = DISABLE;         //发送失败自动重传直到发送成功
  CAN_InitStructure.CAN_RFLM = DISABLE;         //溢出时FIFO不锁定,自动覆盖
  CAN_InitStructure.CAN_TXFP = DISABLE;         //报文优先级由报文的标识符决定
  CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;        //CAN工作在正常模式下
  CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;            //重新同步跳跃时宽、tsjw=tcan*(sjw+1),此处为1个报文位的时间
  CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;      //CAN_BS1 = 6
  CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;      //CAN_BS2 = 8
  CAN_InitStructure.CAN_Prescaler = 16;         //Prescaler =16 ,so CAN_Baudarate = 30M/16/(1+6+8)=125kbps
  CAN_Init(CAN1, &CAN_InitStructure);
          
  CAN_FilterInitStructure.CAN_FilterNumber = 0;                   
  CAN_FilterInitStructure.CAN_FilterMode =  CAN_FilterMode_IdList;
  CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;          
  CAN_FilterInitStructure.CAN_FilterIdHigh =((unsigned short int) CAN_RX_ID)<<5;
  CAN_FilterInitStructure.CAN_FilterIdLow  = 0x0000|CAN_ID_STD|CAN_RTR_DATA;  //要过滤的ID低位
  CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFE0;                 //过滤器高16位每位必须匹配
  CAN_FilterInitStructure.CAN_FilterMaskIdLow  = 0x0000;                 //过滤器低16位每位必须匹配
  CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0 ;         //关联到FIFO0
  CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;                 //使能过滤器
  CAN_FilterInit(&CAN_FilterInitStructure);                         

  /* Enable FIFO 0 message pending Interrupt */          
  CAN_ITConfig(CAN1, CAN_IT_FMP0|CAN_IT_FF0|CAN_IT_FOV0 , ENABLE);             
}       


void NVIC_Config(void)//开CAN接收中断
{
  NVIC_InitTypeDef  NVIC_InitStructure;
  NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;     //CAN1接收中断向量
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}


void CAN_ReceivedData(void)   
{
unsigned char i;
  if(1 == CAN_GetITStatus(CAN1,CAN_IT_FF0))         //接收邮箱满
   {
    CAN_ClearITPendingBit(CAN1,CAN_IT_FF0);
   }
  else if(1 == CAN_GetITStatus(CAN1,CAN_IT_FOV0))
   {
    CAN_ClearITPendingBit(CAN1,CAN_IT_FOV0);
   }
  else
   {
   CAN_Receive(CAN1, CAN_Filter_FIFO0, &RxMessage);
   ID_STD_Receive = RxMessage.StdId;
   ID_ExtId_Receive = RxMessage.ExtId;
   IDE_Recevie = RxMessage.IDE;
   RTR_Recevie = RxMessage.RTR;
   DLC_Recevie = RxMessage.DLC;
   for(i=0;i<DLC_Recevie;i++)
    {
    CAN_RX_DATA = RxMessage.Data;       
    }
   FMI_Recevie = RxMessage.FMI;                                 
   }
}

下面是调试截图:
左边是电脑发送的数据场最后一位从1开始每发送一次加一,共发送三次,右边是仿真的数据,MCU接收到的数据都存在CAN_RX_DATA里

公司没人搞过CAN,完全靠自学的小弟实在是没辙了:'(,请大神指点下。



沙发
mmuuss586| | 2015-4-8 12:08 | 只看该作者
可以弄2块板子;
板子之间CAN总线通讯先测试下;

使用特权

评论回复
板凳
wangdefeng9|  楼主 | 2015-4-8 16:11 | 只看该作者
本帖最后由 wangdefeng9 于 2015-4-8 16:13 编辑
mmuuss586 发表于 2015-4-8 12:08
可以弄2块板子;
板子之间CAN总线通讯先测试下;

      没用两块板子,用的USBCAN分析器进行的调试,这样比较直观,发送和接受的数据都在电脑上看见,附图左边就是调试的界面。
       又确认了下,调用库函数CAN_Recevie()读输出邮箱,程序能进清RFOM位的程序段,读度报文数返回的数据也是0x00,但是问题依旧。。。。在回环模式下也存在这个问题

使用特权

评论回复
地板
lyn3210| | 2015-4-8 16:25 | 只看该作者
正在作相同的开发,一切正常。和你的程序差不多,看不出问题出在那?

使用特权

评论回复
5
wangdefeng9|  楼主 | 2015-4-8 16:30 | 只看该作者
本帖最后由 wangdefeng9 于 2015-4-8 16:33 编辑
lyn3210 发表于 2015-4-8 16:25
正在作相同的开发,一切正常。和你的程序差不多,看不出问题出在那?

  指点下噻,我是新手,STM32的芯片也是第一次使用。。。公司以前用的AVR的片子。
  还是没好,过滤器工作正常,也有数据进入接收FIFO,但是就是接收不到实时数据,CAN_Recevie()接收到的还是以往的数据。。。你的还能接收到实时数据?

使用特权

评论回复
6
wangdefeng9|  楼主 | 2015-4-8 20:45 | 只看该作者
没人 遇到过这问题吗?

使用特权

评论回复
7
FAQ| | 2015-4-9 00:06 | 只看该作者
wangdefeng9 发表于 2015-4-8 20:45
没人 遇到过这问题吗?

什么意思?只能接收到一次数据,后面的数据接收不到吗?

使用特权

评论回复
8
wangdefeng9|  楼主 | 2015-4-9 09:46 | 只看该作者
FAQ 发表于 2015-4-9 00:06
什么意思?只能接收到一次数据,后面的数据接收不到吗?

不是。
我在线调试是发现释放后并不为空,而是显示最先收到的报文,这样正常吗?这种现象导致3个邮箱满后不能实时接收之后报文,程序总是显示FIFO中最先收到的报文,就好像软件释放输出邮箱不起作用似的。
CAN_Recevie();这个库函数里最后有清FIFO,释放邮箱的代码。

使用特权

评论回复
9
wangdefeng9|  楼主 | 2015-4-9 10:31 | 只看该作者
本帖最后由 wangdefeng9 于 2015-4-9 10:39 编辑

搞定了,我去,低级错误。定义了2个中断接收函数

使用特权

评论回复
10
peoplesen| | 2015-4-10 15:40 | 只看该作者
CAN的难度比较大

使用特权

评论回复
11
jiaduo| | 2015-4-10 18:03 | 只看该作者
你好好查看下fifo的设置吧。有很多模式的。。。。还有就是可能你数据接收发送过快,程序处理不当,导致丢包

使用特权

评论回复
12
jiaduo| | 2015-4-10 18:04 | 只看该作者
还有过滤器。。。尤其是过滤器号,好好看datasheet,有时候不是你想的那样

使用特权

评论回复
13
wangdefeng9|  楼主 | 2015-4-10 22:30 | 只看该作者
jiaduo 发表于 2015-4-10 18:04
还有过滤器。。。尤其是过滤器号,好好看datasheet,有时候不是你想的那样

应经好了,谢谢哈

使用特权

评论回复
14
wangdefeng9|  楼主 | 2015-4-10 22:30 | 只看该作者
jiaduo 发表于 2015-4-10 18:03
你好好查看下fifo的设置吧。有很多模式的。。。。还有就是可能你数据接收发送过快,程序处理不当,导致丢包 ...

应经好了:$

使用特权

评论回复
15
小米111| | 2015-4-11 22:30 | 只看该作者
提示: 该帖被管理员或版主屏蔽
16
搞IT的| | 2015-4-12 11:12 | 只看该作者
好资料,正研究这块呢

使用特权

评论回复
17
langziyexin| | 2015-5-6 20:08 | 只看该作者
大哥 我也在学习CAN 方便加一下QQ么 问你几个问题 不胜感谢~462421430@qq.com

使用特权

评论回复
18
zh113214| | 2015-5-6 20:48 | 只看该作者
问题解决就好:lol

使用特权

评论回复
19
wangdefeng9|  楼主 | 2015-5-27 09:24 | 只看该作者
总结下吧,CAN的初始化、发送、过滤都没问题(扩展帧根据手册调整下 CAN_FilterInitStructure.CAN_FilterIdHigh 和
  CAN_FilterInitStructure.CAN_FilterIdLow 的设置就行),问题根本症结在于所有接收中断处理函数一定要放在stm32f2xx_it.c里面,不然就会造成我的情况,我在主函数里又调用了接收函数。。。。。

使用特权

评论回复
20
FYLCANLIN| | 2015-6-3 14:15 | 只看该作者
你好!我们是深圳市富裕龙电子有限公司,专门开发CAN.LIN,J1939协议栈的专业公司,有基于STM32等主流芯片的协议栈软件开发。
欢迎咨询,联系方式:18520827970 (汪生);qq论坛:前装汽车电子CAN&LIN 98397061

使用特权

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

本版积分规则

1

主题

10

帖子

1

粉丝