打印
[CAN/LIN/FlexRay收发器]

使用LPC11C14FBD48/301的CAN与STM32的CAN通信的问题

[复制链接]
1387|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wang12zhe|  楼主 | 2014-9-5 15:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 wang12zhe 于 2014-9-5 16:02 编辑

使用LPC11C14FBD48/301的CAN与STM32的CAN通信的问题

使用LPC11C14FBD48/301的CAN与STM32的CAN通信,

我首先使用两块STM32试验,完成两块STM32在500k通信速率下的正常通信

然后设置LPC11C14FBD48/301的CAN,由于对LPC单片机不是特别熟悉,
一直没能实现LPC11C14FBD48/301与STM32的正常通信。

LPC11C14FBD48/301的CAN初始化过程如下



#define USE_DEFAULT_BIT_TIMING  1

#define TRANSMIT_ONLY           0
#define POLLING                 0
#define LOOPBACK_MODE           0               
#define BASIC_MODE              1


/*****************************************************************************
** Function name:                CAN_Init
**
** Descriptions:                CAN clock, port initialization
**                                
** parameters:                        None
** Returned value:                None
**
*****************************************************************************/
void CAN_Init( uint32_t CANBitClk )
{
  LPC_SYSCON->PRESETCTRL |= (0x1<<3);  //C_CAN 复位无效
  LPC_SYSCON->SYSAHBCLKCTRL |= (1<<17);  //允许C_CAN的时钟

  /* The USB D- and CAN RX share the dedicated pin. The USB D+
  and CAN TX share the dedicated pin. so, no IO configuration is
  needed for CAN. */
  if ( !(LPC_CAN->CNTL & CTRL_INIT) )
  {
        /* If it's in normal operation already, stop it, reconfigure
          everything first, then restart. */
          LPC_CAN->CNTL |= CTRL_INIT;                /* Default state */
  }

#if USE_DEFAULT_BIT_TIMING
  /* AHB clock is 48Mhz. The CAN clock divider is within CAN block,
  set it to 8Mhz for now. Thus, default bit timing doesn't need to
  be touched. */
  LPC_CAN->CLKDIV = 0x05;                        /* Divided by 6 */
   /* Start configuring bit timing */
  LPC_CAN->CNTL |= CTRL_CCE; //配置更改允许  ---允许更改
  LPC_CAN->BT = 0x2301;
  LPC_CAN->BRPE = 0x0000;    // 波特率预分频器扩展
  /* Stop configuring bit timing */
  LPC_CAN->CNTL &= ~CTRL_CCE; //配置结束  --禁止更改
#else
  /* Be very careful with this setting because it's related to
  the input bitclock setting value in CANBitClk. */
  /* popular CAN clock setting assuming AHB clock is 48Mhz:
  CLKDIV = 1, CAN clock is 48Mhz/2 = 24Mhz
  CLKDIV = 2, CAN clock is 48Mhz/3 = 16Mhz
  CLKDIV = 3, CAN clock is 48Mhz/4 = 12Mhz
  CLKDIV = 5, CAN clock is 48Mhz/6 = 8Mhz */

  /* AHB clock is 48Mhz, the CAN clock is 1/6 AHB clock = 8Mhz */
  LPC_CAN->CLKDIV = 0x05;                        /* Divided by 6 */

  /* Start configuring bit timing */
  LPC_CAN->CNTL |= CTRL_CCE;
  LPC_CAN->BT = CANBitClk;  //0x00000103
  LPC_CAN->BRPE = 0x0000;
  /* Stop configuring bit timing */
  LPC_CAN->CNTL &= ~CTRL_CCE;
#endif

  /* Initialization finishes, normal operation now. */
  LPC_CAN->CNTL &= ~CTRL_INIT; //退出初始化模式。恢复正常模式
  while ( LPC_CAN->CNTL & CTRL_INIT );

#if (LOOPBACK_MODE | BASIC_MODE)
  //  LPC_CAN->CNTL  &= ~ CTRL_TEST;   //正常模式。
    LPC_CAN->CNTL |= CTRL_TEST;
    LPC_CAN->TEST &= ~((0x1<<2)|(0x1<<3)|(0x1<<4));
               
#if LOOPBACK_MODE
  LPC_CAN->TEST |= (0x1<<4);
#endif
#if BASIC_MODE
  LPC_CAN->TEST |= (0x01<<2);
  LPC_CAN->TEST &= ~ (0x01<<3)|(0x01<<4);
#endif
#endif  

#if !BASIC_MODE
  /* Below is a critical module to configure all the messages */
  /* It's organized in such a way that:
            obj(x+1)        standard        receive
            obj(x+2)        standard        transmit
            obj(x+3)        extended        receive
            obj(x+4)        extended        transmit        where x is 0 to 7
            obj31 is not used.
                obj32 is for remote date request test only */
  CAN_ConfigureMessages();
#endif

#if !POLLING
  /* Enable the CAN Interrupt */
  NVIC_EnableIRQ(CAN_IRQn);
        
  /* By default, auto TX is enabled, enable all related interrupts */
  LPC_CAN->CNTL |= (CTRL_IE|CTRL_SIE|CTRL_EIE);
#endif
  return;
}


发送函数如下

/*****************************************************************************
** Function name:                CAN_Send
**
** Descriptions:                Send a block of data to the CAN port, the
**                                                first parameter is the message number, the 2nd
**                                                parameter is the received_flag whether it sends received
**                                                data as the TX data field, the third is the pointer to
**                                                the mgs field. When receive_flag is TRUE, the TX msg# is
**                                                RX msg#+1, the TX msg ID is twice of the RX msg ID,
**                                                when received_flag is FALSE, no change in msg#.
**
** parameters:                        msg #, received_flag, msg buffer pointer
** Returned value:                None
**
*****************************************************************************/
void CAN_Send( uint8_t msg_no, uint8_t received_flag, uint32_t *msg_ptr )
{
  uint32_t msg_id, tx_id, Length;   

  if ( msg_ptr == NULL )
  {
        while( 1 );
  }

  /* first is the ID, second is length, the next four are data */
  msg_id = *msg_ptr++;
  if ( received_flag )
  {
        /* Mask off MsgVal, Xtd, and Dir, then make the TX msg ID twice the RX msg ID. */
        /* the msg id should be no large than half the max. extended ID allowed. */
        tx_id = (msg_id & 0x1FFFFFFF) << 1;
  }
  else
  {
        tx_id = msg_id;        
  }
  Length = *msg_ptr++;

  if ( Length > DLC_MAX )
  {
        Length = DLC_MAX;        
  }

  if ( !(msg_id & (0x1<<30)) )                /* bit 30 is 0, standard frame */
  {
        /* MsgVal: 1, Mtd: 0, Dir: 1, ID = 0x200 */
        LPC_CAN->IF1_ARB2 = ID_MVAL | ID_DIR | (tx_id << 2);
        LPC_CAN->IF1_ARB1 = 0x0000;

        /* Mxtd: 0, Mdir: 1, Mask is 0x7FF */
        LPC_CAN->IF1_MSK2 = MASK_MDIR | (ID_STD_MASK << 2);
        LPC_CAN->IF1_MSK1 = 0x0000;
  }
  else
  {
        /* MsgVal: 1, Mtd: 1, Dir: 1, ID = 0x200000 */
        LPC_CAN->IF1_ARB2 = ID_MVAL | ID_MTD | ID_DIR | (tx_id >> 16);
        LPC_CAN->IF1_ARB1 = tx_id & 0x0000FFFF;

        /* Mxtd: 1, Mdir: 1, Mask is 0x7FF */
        LPC_CAN->IF1_MSK2 = MASK_MXTD | MASK_MDIR | (ID_EXT_MASK >> 16);
        LPC_CAN->IF1_MSK1 = ID_EXT_MASK & 0x0000FFFF;
  }
  LPC_CAN->IF1_MCTRL = UMSK|TXRQ|EOB|(Length & DLC_MASK);

  LPC_CAN->IF1_DA1 = *msg_ptr++;
  LPC_CAN->IF1_DA2 = *msg_ptr++;
  LPC_CAN->IF1_DB1 = *msg_ptr++;
  LPC_CAN->IF1_DB2 = *msg_ptr;

  LPC_CAN->IF1_CMDMSK = WR|MASK|ARB|CTRL|TREQ|DATAA|DATAB;
#if BASIC_MODE
  LPC_CAN->IF1_CMDREQ = IFCREQ_BUSY;
#else
  /* if receive_flag is FALSE, the TX uses the normal message object (msg_no+1)
  for transmit. When received_flag is TRUE, msg_no+1 is the message object for RX,
  TX uses the message object next to RX(msg_no+2) for transmit. */
  if ( received_flag )
  {
        LPC_CAN->IF1_CMDREQ = msg_no+2;
  }
  else
  {
        LPC_CAN->IF1_CMDREQ = msg_no+1;
  }
  while( LPC_CAN->IF1_CMDREQ & IFCREQ_BUSY );   /* Could spin here forever */
#endif
  return;
}


但是一直没有实现通信,求大侠帮助

下面是LPC的源码,

程序V2.0_20140904_1CAN.zip (567.19 KB)

我已经进入正常模式了,但是发送后自己受到,感觉还是在回环模式。

还有个问题,LPC程序使用的是MDK,仿真的时候怎么查看相关的寄存器?



CAN.zip

555.62 KB

相关帖子

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

本版积分规则

101

主题

205

帖子

1

粉丝