Minmin Zhengzheng

problem of CAN transmit

Discussion created by Minmin Zhengzheng on Oct 22, 2017
Latest reply on Nov 5, 2017 by Minmin Zhengzheng

I am learning CAN module for TWR-K60F120. For the CAN Loop-Back mode, the program can be debugged successfully,and it can transmit and receive data for Loop-Back mode.But when I don't use Loop-Back mode,the register about the  Loop-Back is removed In CAN program initialization,because I just only want to transmit data for CAN module.Can_high and Can_low are connected to the CAN card which is made by myself.

 

 

I want to know whether some registers need to be configured,which is different from the Loop-Back mode?

 

the program of CAN initialization:

uint8 CANInit(uint8 CANChannel,uint32 baudrateKHz,uint8 selfLoop,uint8 idMask)
{
int8 i;
CAN_MemMapPtr CANBaseAdd;

//使能FlexCAN外部时钟
OSC0_CR |= OSC_CR_ERCLKEN_MASK | OSC_CR_EREFSTEN_MASK;//*晶振提供外部时钟

//通过模块号选择模块基地址
if(CANChannel == 0)
CANBaseAdd = CAN0_BASE_PTR;
else if(CANChannel == 1)
CANBaseAdd = CAN1_BASE_PTR;

//使能CAN模块时钟
if(CANBaseAdd == CAN0_BASE_PTR)
SIM_SCGC6 |= SIM_SCGC6_FLEXCAN0_MASK;//使能CAN0的时钟模块
else
SIM_SCGC3 |= SIM_SCGC3_FLEXCAN1_MASK;//使能CAN1的时钟模块

//使能CAN中断
if(CANChannel == 0)//使能CAN0的中断
{
NVICICPR0 = (NVICICPR0 & ~(0x07<<29)) | (0x07<<29);//清除挂载在FlexCAN0的中断
NVICISER0 = (NVICISER0 & ~(0x07<<29)) | (0x07<<29);//使能FlexCAN0中断

NVICICPR1 = (NVICICPR1 & ~(0x1F<<0)) | (0x1F);//清除挂载在FlexCAN0的中断
NVICISER1 = (NVICISER1 & ~(0x1F<<0)) | (0x1F);//使能FlexCAN0中断
}
else //使能CAN1的中断
{
NVICICPR1 = (NVICICPR1 & ~(0xFF<<5)) | (0xFF<<5);//清除挂载在FlexCAN1的中断
NVICISER1 = (NVICISER1 & ~(0xFF<<5)) | (0xFF<<5);//使能FlexCAN1中断
}

//配置CAN_RX/TX复用引脚功能
if(CANChannel == 0)
{
PORTE_PCR24 = PORT_PCR_MUX(2) | PORT_PCR_PE_MASK | PORT_PCR_PS_MASK; //上拉 *PORT PCR寄存器的设置
PORTE_PCR25 = PORT_PCR_MUX(2) | PORT_PCR_PE_MASK | PORT_PCR_PS_MASK; //上拉
}
else
{
PORTC_PCR17 = PORT_PCR_MUX(2) | PORT_PCR_PE_MASK | PORT_PCR_PS_MASK; //Tx上拉
PORTC_PCR16 = PORT_PCR_MUX(2) | PORT_PCR_PE_MASK | PORT_PCR_PS_MASK; //Rx上拉
}
//选择时钟源,外设时钟48MHz,内部时钟:12MHz
CAN_CTRL1_REG(CANBaseAdd) |= CAN_CTRL1_CLKSRC_MASK;//选择内部时钟(是错的) //Source --> bus clock //应该是外部时钟源吧?

CAN_MCR_REG(CANBaseAdd) |= CAN_MCR_FRZ_MASK; //使能冻结模式
CAN_MCR_REG(CANBaseAdd) &= ~CAN_MCR_MDIS_MASK;//使能CAN模块
//确认已退出冻结模式
while((CAN_MCR_LPMACK_MASK & CAN_MCR_REG(CANBaseAdd)));
//软件复位
CAN_MCR_REG(CANBaseAdd) ^= CAN_MCR_SOFTRST_MASK;
//等待复位完成
while(CAN_MCR_SOFTRST_MASK & CAN_MCR_REG(CANBaseAdd));
//等待进入冻结模式
while(!(CAN_MCR_FRZACK_MASK & CAN_MCR_REG(CANBaseAdd)));

// enable self-reception
//CAN_MCR_REG(CANBaseAdd) &=~CAN_MCR_SRXDIS_MASK;

// Enable individual masking and queue
CAN_MCR_REG(CANBaseAdd) |= CAN_MCR_IRMQ_MASK;

// Set local priority
CAN_MCR_REG(CANBaseAdd)|=CAN_MCR_LPRIOEN_MASK;

//将16个邮箱缓冲区内容清0
for(i=0;i<16;i++)
{
CANBaseAdd->MB[i].CS = 0x00000000;
CANBaseAdd->MB[i].ID = 0x00000000;
CANBaseAdd->MB[i].WORD0 = 0x00000000;
CANBaseAdd->MB[i].WORD1 = 0x00000000;
}
//接收邮箱过滤IDE比较,RTR不比较
CAN_CTRL2_REG(CANBaseAdd) &= ~CAN_CTRL2_EACEN_MASK;//EACEN:Entire Frame Arbitration Field Comparison Enable For Rx Mailboxes
//0 Rx Mailbox filter’s IDE bit is always compared and RTR is never compared despite mask bits.
//远程请求帧产生
CAN_CTRL2_REG(CANBaseAdd) &= ~CAN_CTRL2_RRS_MASK; //0 Remote Response Frame is generated.
//邮箱首先从接收FIFO队列匹配然后再在邮箱中匹配
CAN_CTRL2_REG(CANBaseAdd) &= ~CAN_CTRL2_MRP_MASK;//0 Matching starts from Rx FIFO and continues on Mailboxes
//使用一个32位过滤器
CAN_MCR_REG(CANBaseAdd) |= (CAN_MCR_REG(CANBaseAdd) & ~CAN_MCR_IDAM_MASK) | CAN_MCR_IDAM(0);
//设置波特率
if(SetCANBand(CANChannel,baudrateKHz) == 1)//若设置错误
return 1;
//模式选择:回环模式或正常模式
//采用正常模式,即注释以下程序
if(1==selfLoop)
CAN_CTRL1_REG(CANBaseAdd) |= CAN_CTRL1_LPB_MASK;//使用回环模式
//初始化掩码寄存器
if(1==idMask)//屏蔽ID
{
CAN_RXMGMASK_REG(CANBaseAdd) = 0x1FFFFFFF;
CAN_RX14MASK_REG(CANBaseAdd) = 0x1FFFFFFF;
CAN_RX15MASK_REG(CANBaseAdd) = 0x1FFFFFFF;
}
else//不屏蔽ID
{
CAN_RXMGMASK_REG(CANBaseAdd) = 0x0;
CAN_RX14MASK_REG(CANBaseAdd) = 0x0;
CAN_RX15MASK_REG(CANBaseAdd) = 0x0;
}

//如果单独掩码功能使能,为每个队列初始化单独的掩码寄存器
if(CAN_MCR_REG(CANBaseAdd) & CAN_MCR_IRMQ_MASK)
{
for(i = 0; i < NUMBER_OF_MB ; i++)
{
CANBaseAdd->RXIMR[i] = 0x1FFFFFFFL;
}
}
//只有在冻结模式下才能配置,配置完退出冻结模式
CAN_MCR_REG(CANBaseAdd) &= ~(CAN_MCR_HALT_MASK);
//等待直到退出冻结模式
while( CAN_MCR_REG(CANBaseAdd) & CAN_MCR_FRZACK_MASK);
//等到不在冻结模式,休眠模式或者停止模式
while((CAN_MCR_REG(CANBaseAdd) & CAN_MCR_NOTRDY_MASK));
return 0;
}

Outcomes