problem of CAN transmit

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

problem of CAN transmit

5,065 Views
minminzhengzhen
Contributor I

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.

 

1.jpg2.jpg

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;
}

Labels (1)
0 Kudos
20 Replies

4,226 Views
kt1003
Contributor II

Two classic mistakes with CAN:

1. Bus not terminated properly. This problem often manifests by causing the controller to go into error passive where the same frame is sent repeatedly.

2. No active receiver on the bus. If there's no other end to pull the ACK to dominant the controller will never see the frame as sent and will re-send it repeatedly.

A bus analyzer often is configured to be listen-only and not participate in the protocol and so will not generate the ACK.

The best way to check for the above is to put a logic analyzer on the bus (e.g. the Saleae, which includes a CAN protocol decoder) and see if the frame is coming out once only, or nothing is coming out, or if the frame is being transmitted continuously with no delay between frames.

4,226 Views
egoodii
Senior Contributor III

Last I heard, NOTHING was showing on the CAN bus wires because the transmitter chip was in undervoltage lockout.  The path to get 5V on the elevators was the latest difficulty....

0 Kudos

4,225 Views
minminzhengzhen
Contributor I

yes,I have sovled the problem of 5V. After I changed a USB cable power supply, the voltage reached about 4.6V.

Thanks.

0 Kudos

4,226 Views
egoodii
Senior Contributor III

I don't see any resistors in your wire-pair to the 'other' CAN device.  We need to see 60ohms (or so) across that pair.

In one sense the 'ideal bus' is 120ohms-twisted-pair, terminated at both ends with such 120ohms, as a 'true transmission line'.  BUT more importantly for CAN, the drivers are 'open collector/emitter' and can only create a + differential voltage in what is called the 'dominant' state, and the RETURN to 'near 0V differential' for the 'recessive state' is supplied ENTIRELY by said resistors.  The net resistance MUST be there, although for a 'short collection of wires' (<2m overall for 250Kb/s) it can just be one 50 to 70 ohm resistance 'anywhere'.

You might also look into other CAN-not-working posts, like:

Problem for FlexCAN 

CAN Interrupts not being tripped K64F 

0 Kudos

4,226 Views
minminzhengzhen
Contributor I

hello:

this is my program of can transmit:

uint8 CANSendData(uint8 CANChannel,uint16 iMB, uint32 id,uint8 length,uint8 Data[])

{

int16 i,wno,bno;

uint32 word[2] = {0};

CAN_MemMapPtr CANBaseAdd;

if(CANChannel == 0)

CANBaseAdd = CAN0_BASE_PTR;

else if(CANChannel == 1)

CANBaseAdd = CAN1_BASE_PTR;

//缓冲区和数据长度设置错误

if(iMB >= NUMBER_OF_MB || length >8)

return 1; //超出范围

//CANBaseAdd->IFLAG1 = (1<<iMB);

//转换8个字节转换成32位的word存储

wno = (length-1)>>2;//是否超过4字节

bno = (length-1)%4; //

if(wno > 0) //长度大于4(即发送数据超过4字节)

{

word[0] = (

(Data[0]<<24)

(Data[1]<<16)

(Data[2]<< 8)

Data[3]

);

}

for(i=0;i<=bno;i++)

word[wno]

= Data[(wno<<2)+i] << (24-(i<<3));

///////////////////////////////////////////////////////

// ID 格式

// B31 30 29 28 27 26 ... 11 10 9 8 7 6 5 4 3 2 1 0

//

// | | |

0 Kudos

4,226 Views
egoodii
Senior Contributor III

Given that your 'loopback' mode works, I am making an assumption here that the code is 'good enough' for true transmit, and I am trying to get you to focus on the hardware.  I am ALSO assuming you have connected the CAN transceiver functions of the TWR-SER correctly, AND that you are clocking the CAN subsystem from a crystal-based source, AND you can confirm that the rate is correct.  IF you get some terminations resistors in the link, can you see waveforms on the CAN wires?

0 Kudos

4,226 Views
minminzhengzhen
Contributor I

hello:

I have connected the CAN transceiver functions of the TWR-SER2 correctly, I connect the Can_high and Can_low to the CAN card which is made by my team. For the clocking the CAN subsystem,The CAN engine clock source is the peripheral clock.The program is:

#define CAN_CTRL1_CLKSRC_MASK 0x2000u

CAN_CTRL1_REG(CANBaseAdd) |= CAN_CTRL1_CLKSRC_MASK;

and I can finish the loopback test successfully, so I think the clocking ought to be correct. When I don't use "loopback", I can't see waveforms by Oscilloscope,and the Can_high and Can_low are no Electricity level change.

I don't know why, and I have thought for several weeks.please help me.

0 Kudos

4,226 Views
egoodii
Senior Contributor III

You keep not answering anything about the termination resistors.

But loopback-mode can clock its own bits at ANY rate or jitter, however real transfers require an exact match between bus members.  We should want to know the original source (and freq) of the selected peripheral clock.

0 Kudos

4,226 Views
minminzhengzhen
Contributor I

There should be the termination resistors,I buy the TWR-k60F120M in NXP.The hardware have no problem.

0 Kudos

4,226 Views
egoodii
Senior Contributor III

TWR-SER does NOT build-in termination, and MOST CAN nodes do not, as you ideally only want 120 all the way 'at the ends' of a bus.  What does an ohm-meter measure between the lines (powered off, of course!)?

Can your 'other node' send a message (getting an ACK from Kinetis!)?

0 Kudos

4,226 Views
minminzhengzhen
Contributor I

Is this termination what you said?

0 Kudos

4,226 Views
egoodii
Senior Contributor III

OK, so in TWR-SER2 the 120.8 ohms supplied by R502+R509 will be the termination for ONE end of the wire-pair.  What resistance can you measure across your connected pair?   By the way, it is also necessary for all the nodes of a CAN bus to share a 'generally common' ground reference (within a few volts of each other) as a DC-connected bus.  While you have your ohm-meter out, check for a direct tie between the appropriate CAN_TX in of the K60(also accessible at one end of R130) to the TX pin of the transceiver chip.  I assume all jumpers of J4 are installed on TWR-SER2.  Have you pulled R91 and R130 from the TWR-K60F120 board to isolate PTC16&17, AND is this the module(CAN1)/pin-selection you are making when you call the init routine?

So, if your CAN_H and CAN_L wires just 'sit' constantly at about 2V when you think you should be sending a message, we need to look further upstream for a disconnect.  Now, starting at the processor, do you see TX activity (after a 'send message' action) on the appropriate CAN_TX pin of the processor?

0 Kudos

4,225 Views
minminzhengzhen
Contributor I

hello:

the hardware have the terminating resistance including the R502+R509.I think the hardware has no problem. when the can transmits,the Oscilloscope can Collect the square signal according to the pin of CAN_TX .

And I also connect the port 3 and 4(CAN_TX and CAN_TX1) of CAN_ISO according to the Jumper.

But the CAN_H and CAN_L have no signal. Do you know why?

0 Kudos

4,224 Views
egoodii
Senior Contributor III

ONE set of 120-ohm termination is NOT enough to 'properly' load the CAN pair, there needs to be a SECOND 120, to net 60ohms.  However, even just that should show SOMETHING on the pair, just not 'clean' enough.  Do you measure 5V+/-0.5V on U501 pin 3?  For CAN you must also tie-across CAN_RX and CAN_RX_I, as full CAN message transmit REQUIRES that the sender see their OWN bits, AND 'ack/nak' responses from ALL other bus slaves.  Are you tying across CAN_S and CAN_S_IN?  CAN_S_IN must be 'low' to enable TX functions in the TJA1051T/3, so I would NOT tie them, just let R503 pull it down.

So you are saying you DO see a continuous stream waveform on CAN_TX?

0 Kudos

4,224 Views
minminzhengzhen
Contributor I

this is the waveform.

I measure the voltage on U501 pin 3,but the voltage is about 3V rather than 5V+/-0.5V.

0 Kudos

4,224 Views
egoodii
Senior Contributor III

Your scope-shot gives me no indication of 'time scale', but it looks like it might be a reasonable TX-response/retry for 'no feedback on RX', which we will not get until we see something on the bus lines.  And for that, 3V on U501 is DEFINITELY a problem, as if you read the TJA1051 datasheet you will see it has an 'undervoltage lockout' that triggers 'somewhere just less than 4.5V' which will PREVENT any transmissions!  You need to track down how TWR-SER2 is supposed to get 5V, and you may need to supply some external DC to elevator regulators to get that --- 'nearly 5V' from USB will probably NOT be a reliable source to guarantee >4.5V at U501.

And PLEASE confirm you now have a net 60 ohms of resistance across the wire pair, AND some 'common ground' between your K60-tower and the other CAN box.

Unfortunately, it is 'going on Midnight' here in Eastern (US) Daylight Time, so our conversations here are limited!  Until tomorrow.....

0 Kudos

4,224 Views
egoodii
Senior Contributor III

Any update on this?  How are things going with 5V on U501?

0 Kudos

4,224 Views
minminzhengzhen
Contributor I

I don't get method about how TWR-SER2 is supposed to get 5V. I am trying to do.I did not reply to you so as not to disturb you yesterday.

0 Kudos

4,224 Views
egoodii
Senior Contributor III

https://cache.nxp.com/docs/en/application-note/AN4649.pdf?fsrch=1&sr=2&pageNum=1

Figure 5 makes it look like you need J7, and supply 5.2V on J10 with SW1 set to 'external'.

0 Kudos

4,224 Views
minminzhengzhen
Contributor I

Ok, I will see.

0 Kudos