OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2675|回复: 1

CAN 接收出现神奇问题,救救孩子吧。

[复制链接]

1

主题

3

帖子

0

精华

新手入门

积分
14
金钱
14
注册时间
2019-4-27
在线时间
5 小时
发表于 2020-6-3 18:34:23 | 显示全部楼层 |阅读模式
本帖最后由 Clutch 于 2020-6-3 18:35 编辑

STM32f405RG,外加TJA1050模块。
CAN接收中断出现了一个神奇的问题。
假设现在有另一个模块向CAN总线上发布一个计数值,计数值累加,0、1、2这样。
接收的这块单片机收到数据后发送到串口。
那么串口收到的计数值如下:
0
1
2
0
3
1
4
2
5
数据在三个之后出现交叉重复。假设此时按下reset并恢复,设此时CAN总线上的计数值计到了50,那么接下来的数据为:
50
3
51
4
52
50
53
51




接收是使用了中断方式,也释放了FIFO,配置如下:
GPIO_InitTypeDef GPIO_InitStructure;
   CAN_InitTypeDef        CAN_InitStructure;
   CAN_FilterInitTypeDef  CAN_FilterInitStructure;

    NVIC_InitTypeDef  NVIC_InitStructure;
    //ʹÄÜÏà¹ØÊ±ÖÓ
   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);                           
   RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);

    //³õʼ»¯GPIO
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8| GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;­
    GPIO_Init(GPIOB, &GPIO_InitStructure);

   //Òý½Å¸´ÓÃÓ³ÉäÅäÖÃ
   GPIO_PinAFConfig(GPIOB,GPIO_PinSource8,GPIO_AF_CAN1);
   GPIO_PinAFConfig(GPIOB,GPIO_PinSource9,GPIO_AF_CAN1);
   
   //CANµ¥ÔªÉèÖÃ
    CAN_InitStructure.CAN_TTCM=DISABLE;  
   CAN_InitStructure.CAN_ABOM=DISABLE;
   CAN_InitStructure.CAN_AWUM=DISABLE;
   CAN_InitStructure.CAN_NART=ENABLE;
   CAN_InitStructure.CAN_RFLM=DISABLE;
   CAN_InitStructure.CAN_TXFP=DISABLE;
   CAN_InitStructure.CAN_Mode= mode;
   CAN_InitStructure.CAN_SJW=tsjw;
   CAN_InitStructure.CAN_BS1=tbs1;
   CAN_InitStructure.CAN_BS2=tbs2;
   CAN_InitStructure.CAN_Prescaler=brp;  
   CAN_Init(CAN1, &CAN_InitStructure);   
   

    CAN_FilterInitStructure.CAN_FilterNumber=0;
   CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
   CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
   CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;
   CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
   CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;
   CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;
   CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
   CAN_FilterInit(&CAN_FilterInitStructure);
  

   CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);     
  
   NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;     
   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;      
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
   NVIC_Init(&NVIC_InitStructure);



接收中断:
void CAN1_RX0_IRQHandler(void)
{
  
u32 id;
u32 count;


id=(uint32_t)0x000007FF & (CAN1->sFIFOMailBox[0].RIR >> 21);
  count=(CAN1->sFIFOMailBox[0].RDLR)&((u32)0xffffff);
  printf("%03x\t%d\r\n",id,count);

CAN1->RF0R |= CAN_RF0R_RFOM0;
}


想破脑袋都没想明白,救救孩子吧。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

3

帖子

0

精华

新手入门

积分
14
金钱
14
注册时间
2019-4-27
在线时间
5 小时
 楼主| 发表于 2020-6-3 21:21:56 | 显示全部楼层
找到解决方法了,只需在中断服务函数中,释放FIFO之后加一个延时即可,1us就行。
之前使用103系列的芯片就不必。
猜测是因主频较高,软件再次进入中断的速度高于了硬件释放FIFO的速度。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-19 20:35

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表