打印

请教香主,stm32里面的CAN设置问题

[复制链接]
3834|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tiger84|  楼主 | 2010-6-3 15:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
文档里面有这样一段话:

不需要在初始化模式下进行过滤器初值的设置,但必须在它处在非激活状态下完成(相应的FACT位为0)。而过滤器的位宽和模式的设置,则必须在初始化模式中进入正常模式前完成

而我使用的官方例子,初始化程序部分如下:

/* CAN cell init */  // 36M 100k速率
  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;
  CAN_InitStructure.CAN_TXFP=DISABLE;
  CAN_InitStructure.CAN_Mode=CAN_Mode_LoopBack;
  CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;
  CAN_InitStructure.CAN_BS1=CAN_BS1_12tq;
  CAN_InitStructure.CAN_BS2=CAN_BS2_3tq;
  CAN_InitStructure.CAN_Prescaler=22;
  CAN_Init(CAN1, &CAN_InitStructure);
/* CAN filter init */
  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=0;
  CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
  CAN_FilterInit(&CAN_FilterInitStructure);


据我对这段程序的理解,这个过滤器的位宽和模式的设置,应该是在正常模式完成的,与文档的叙述貌似不一致。

不过在环回模式下程序跑的很正常,香主指点下,看我哪里理解错了。
沙发
tiger84|  楼主 | 2010-6-3 15:24 | 只看该作者
还有,图207里面关于仲裁域的位数,应该是写错了吧,或者stm32里面的表达不一样?

使用特权

评论回复
板凳
yunqian09| | 2010-6-3 15:37 | 只看该作者
CAN_FilterInit(&CAN_FilterInitStructure);
这个函数里面 ,是不是有进入初始化模式的代码?

使用特权

评论回复
地板
tiger84|  楼主 | 2010-6-3 15:43 | 只看该作者
CAN_FilterInit的原型如下
/**
  * @brief  Initializes the CAN peripheral according to the specified
  *   parameters in the CAN_FilterInitStruct.
  * @param CAN_FilterInitStruct: pointer to a CAN_FilterInitTypeDef
  *   structure that contains the configuration information.
  * @retval : None.
  */
void CAN_FilterInit(CAN_FilterInitTypeDef* CAN_FilterInitStruct)
{
  uint32_t filter_number_bit_pos = 0;
  /* Check the parameters */
  assert_param(IS_CAN_FILTER_NUMBER(CAN_FilterInitStruct->CAN_FilterNumber));
  assert_param(IS_CAN_FILTER_MODE(CAN_FilterInitStruct->CAN_FilterMode));
  assert_param(IS_CAN_FILTER_SCALE(CAN_FilterInitStruct->CAN_FilterScale));
  assert_param(IS_CAN_FILTER_FIFO(CAN_FilterInitStruct->CAN_FilterFIFOAssignment));
  assert_param(IS_FUNCTIONAL_STATE(CAN_FilterInitStruct->CAN_FilterActivation));
  filter_number_bit_pos =
  (uint32_t)(((uint32_t)0x00000001) << ((uint32_t)CAN_FilterInitStruct->CAN_FilterNumber));
  /* Initialisation mode for the filter */
  CAN1->FMR |= FMR_FINIT;
  /* Filter Deactivation */
  CAN1->FA1R &= ~(uint32_t)filter_number_bit_pos;
  /* Filter Scale */
  if (CAN_FilterInitStruct->CAN_FilterScale == CAN_FilterScale_16bit)
  {
    /* 16-bit scale for the filter */
    CAN1->FS1R &= ~(uint32_t)filter_number_bit_pos;
    /* First 16-bit identifier and First 16-bit mask */
    /* Or First 16-bit identifier and Second 16-bit identifier */
    CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR1 =
    ((uint32_t)((uint32_t)0x0000FFFF & CAN_FilterInitStruct->CAN_FilterMaskIdLow) << 16) |
        ((uint32_t)0x0000FFFF & CAN_FilterInitStruct->CAN_FilterIdLow);
    /* Second 16-bit identifier and Second 16-bit mask */
    /* Or Third 16-bit identifier and Fourth 16-bit identifier */
    CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR2 =
    ((uint32_t)((uint32_t)0x0000FFFF & CAN_FilterInitStruct->CAN_FilterMaskIdHigh) << 16) |
        ((uint32_t)0x0000FFFF & CAN_FilterInitStruct->CAN_FilterIdHigh);
  }
  if (CAN_FilterInitStruct->CAN_FilterScale == CAN_FilterScale_32bit)
  {
    /* 32-bit scale for the filter */
    CAN1->FS1R |= filter_number_bit_pos;
    /* 32-bit identifier or First 32-bit identifier */
    CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR1 =
    ((uint32_t)((uint32_t)0x0000FFFF & CAN_FilterInitStruct->CAN_FilterIdHigh) << 16) |
        ((uint32_t)0x0000FFFF & CAN_FilterInitStruct->CAN_FilterIdLow);
    /* 32-bit mask or Second 32-bit identifier */
    CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR2 =
    ((uint32_t)((uint32_t)0x0000FFFF & CAN_FilterInitStruct->CAN_FilterMaskIdHigh) << 16) |
        ((uint32_t)0x0000FFFF & CAN_FilterInitStruct->CAN_FilterMaskIdLow);
  }
  /* Filter Mode */
  if (CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdMask)
  {
    /*Id/Mask mode for the filter*/
    CAN1->FM1R &= ~(uint32_t)filter_number_bit_pos;
  }
  else /* CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdList */
  {
    /*Identifier list mode for the filter*/
    CAN1->FM1R |= (uint32_t)filter_number_bit_pos;
  }
  /* Filter FIFO assignment */
  if (CAN_FilterInitStruct->CAN_FilterFIFOAssignment == CAN_FilterFIFO0)
  {
    /* FIFO 0 assignation for the filter */
    CAN1->FFA1R &= ~(uint32_t)filter_number_bit_pos;
  }
  if (CAN_FilterInitStruct->CAN_FilterFIFOAssignment == CAN_FilterFIFO1)
  {
    /* FIFO 1 assignation for the filter */
    CAN1->FFA1R |= (uint32_t)filter_number_bit_pos;
  }
  
  /* Filter activation */
  if (CAN_FilterInitStruct->CAN_FilterActivation == ENABLE)
  {
    CAN1->FA1R |= filter_number_bit_pos;
  }
  /* Leave the initialisation mode for the filter */
  CAN1->FMR &= ~FMR_FINIT;
}

这个函数里面貌似没有进入初始化模式的代码。

使用特权

评论回复
5
txcy| | 2010-6-3 16:29 | 只看该作者
过滤器的设置一般是在初始化里设置的

使用特权

评论回复
6
tiger84|  楼主 | 2010-6-3 16:47 | 只看该作者
问题是官方下载的测试程序貌似并没有这样做,所以搞的我很疑惑,还希望各位帮忙解惑。

使用特权

评论回复
7
IJK| | 2010-6-4 09:47 | 只看该作者
本帖最后由 IJK 于 2010-6-4 09:50 编辑

看了一下中文翻译,它有点自相矛盾:
1)在对bxCAN的过滤器组(模式、位宽、FIFO关联、激活和过滤器值)进行初始化前,软件要对CAN_FMR寄存器的FINIT位设置’1’。对过滤器的初始化可以在非初始化模式下进行。

2)不需要在初始化模式下进行过滤器初值的设置,但必须在它处在非激活状态下完成(相应的FACT位为0)。而过滤器的位宽和模式的设置,则必须在初始化模式中进入正常模式前完成。

再看了一下英文原文,第2)段有点问题,不是“则必须在初始化模式中进入正常模式前完成”,应该改为“则必须在进入正常模式前完成”。
第1)段,改为“对过滤器的初始化可以在非初始化模式(睡眠模式)下进行。”

对应于源代码,一般是:
/* CAN filter init */
  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=0;
  CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
  CAN_FilterInit(&CAN_FilterInitStructure);
//......
  //Enter Normal mode from sleep mode
  CAN_WakeUp();  
即在睡眠模式下初始化CAN过滤器。

使用特权

评论回复
8
tiger84|  楼主 | 2010-6-4 14:49 | 只看该作者
谢谢LS的细心解答。
我用的是3.0.0版本,貌似CAN_WakeUp();  这个函数都没有用到,不过目前初步测试一切正常,并无不妥之处。

使用特权

评论回复
9
halibote523| | 2010-6-4 17:30 | 只看该作者
看清楚寄存器的设置就行

使用特权

评论回复
10
gxgclg| | 2010-6-5 09:20 | 只看该作者
一切正常就说明你的初始化没问题

使用特权

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

本版积分规则

个人签名:专注ARM及linux性能优化

101

主题

862

帖子

0

粉丝