CAN problem with PIC18F25K80 and SN65HVD231  - Page 1
Forum section: electronics / general

author: Spekkio
author_rank: Regular Contributor
timestamp: December 07, 2011, 11:03:31 am
content: I have a problem with CAN communication, I have two devices, one of them is sending and the other one is receiving. I get data out on the bus that I can see with an oscilloscope, and I also get data on CANRX on the receiving side so the transceiver is working on both sides. But both the receiving side and the transmitting side is counting up the TXERRCNT and RXERRCNT, never counts down. And the receiving side is not getting any data in the registers. What is the problem ? I have one output RB3 which is connected via an 100k resistor to the transceivers(SN65HVD231) Rs pin. Like it says in the datasheet. It should be low-level when ON, and high level when in sleep mode. I got the receiving side to work one time when I set RB3 and input, but then I restarted the program and it did not work anymore. I don't understand...The receiving side is counting up RXERRCNT, and transmitting side TXERRCNT, I have not mixed up the programs. Also I did not forget 120ohm resistors on the CAN bus.I was thinking, maybe because I run the receiving side in debug mode, with a breakpoint in the receive function to see if the MCU caught a message. Maybe the debug side is slower than the transmitting side witch is running in Release ? Also could it be a problem with the transceiver, because I get TXERRCNT and TXREQ is never cleared, the MCU think the bus is busy ? Do I need pull-ups maybe ?

author: Spekkio
author_rank: Regular Contributor
timestamp: December 08, 2011, 11:21:16 am
content: Problem is not fixed :/ Though I seem to have removed the problem with TXERRCNT and RXERRCNT counting up. They stay on zero.TX side is now transmitting, meaning the program gets out of the while(TXREQ); loop completely. But the receiving side is not getting any data at all, it is like it just ignores what is happening on the CANRX pin.There are too many registers, ID, Filters etc, I can't get a good overview what they all do. The datasheet doesn't really explain what they do, I'm reading a CAN protocol specification, see if I can get a better understanding.Been working on it for a week now. Probably something simple :p

author: Spekkio
author_rank: Regular Contributor
timestamp: December 08, 2011, 02:13:58 pm
content: I got the receiving side to accept messages when running in Error Recognition mode! But I dont want to run in this mode all the time, the program should work in a normal way ofcourse. Maybe I have just configured the filters wrong.QuoteRXB0CONbits.RXM0 = 1; // Error recognition modeRXB0CONbits.RXM1 = 1;RXB1CONbits.RXM0 = 1;RXB1CONbits.RXM1 = 1;

author: peter_mcc
author_rank: Contributor
timestamp: December 09, 2011, 04:02:40 am
content: Do you have a 100 ohm (?) resistor across the CAN-H CAN-L lines? CAN won't work unless the bus is terminated. In theory you need one at either end but I found for quick internal testing one in the middle would work with 2m of cable. For production you'd want to do it properly...peter

author: Spekkio
author_rank: Regular Contributor
timestamp: December 09, 2011, 07:34:41 am
content: Quote from: peter_mcc on December 09, 2011, 04:02:40 amYes, I have 120ohm.It works in error detection mode as I described above. So I think it's probably something with how I configured the filters.

author: Spekkio
author_rank: Regular Contributor
timestamp: December 12, 2011, 10:34:34 am
content: I think I solved it now, it was a problem with the filters/masks. There are alot of filter and mask registers, and settings how they can be used.

author: Spekkio
author_rank: Regular Contributor
timestamp: December 13, 2011, 11:04:54 am
content: Ok i fixed it nowFilter is set with RXFnSIDH, RXFnSIDL. If the mask registers are set to 0xFF the entire filter is used.RXMnSIDH, RXMnSIDL = 0xFF. That means the receive buffers will only accept messages that are directly equal to the filters.So messages that are transmitted with these TX regsTXB0SIDH = 0x56TXB0SIDL = 0x76TXB0DLC = 0x04; // Data length 4 bytes. Bit 6 TXRTR=0.TXB0D0 = t_1;TXB0D1 = t_2;TXB0D2 = h_1;TXB0D3 = h_2;will only be accepted by the CAN receiver that has the filterRXF0SIDH = 0x56RXF0SIDL = 0x76If the mask is 0xFF for that filter.RXM0SIDH = 0xFFRXM0SIDL = 0xFFThe bits in the mask activates wich bits in the filter shall be used. So if you have the mask 0xF0 only the most significant nibble of the filter will be used.Also look at what RXB0CONbits.RXM0, RXB0CONbits.RXM1 are set to.Standard ID or Extended ID. I only use standard ID, but I guess if Extended ID is used also the RXFnEIDH, RXFnEIDL filters are used. Also look at the RXF0SIDLbits.EXIDEN bit, should be zero when using only Standard ID.