本帖最后由 wang12zhe 于 2014-9-5 16:05 编辑
使用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,仿真的时候怎么查看相关的寄存器?
|
|