CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Can-bus, 18F2580+MCP2551. Loopback ok, real can not working.
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
halibatsuiba



Joined: 12 Aug 2009
Posts: 30

View user's profile Send private message

Can-bus, 18F2580+MCP2551. Loopback ok, real can not working.
PostPosted: Tue Sep 15, 2009 7:41 pm     Reply with quote

What can possibly be wrong?
I have a very simple connection between two 18F2580s.

Schema(lcd is not included): http://tinyurl.com/mikavikana

I tested the connection with code from another thread in this forum (http://www.ccsinfo.com/forum/viewtopic.php?t=29627&highlight=ifdef+board1+board),

If I set board1 to loopback mode, everything works fine.
When I try to use the actual connection, it is not working.

Does anyone see right away where the problem is? Or if someone has pointers what to check, please tell me. Very Happy

My endless supply of components had run out of 120ohm resistors so I did termination with 121ohms (several resistors in series). Also the Rs resistor value for MCP2551 is 11k.

Any ideas?

edit: I just got my old scope working and there is data going in can-wires.
Looks like same sequence repeats itself.

Here is the code I mentioned above:

Code:

#include <18F2580.H>

#fuses HS, NOPROTECT, PUT, BROWNOUT, NOWDT, NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

#include <can-18xxx8.c>

#define BOARD1_ID  24
#define BOARD2_ID  25

// Uncomment this line to compile code for Board #1.
// Comment it out to compile for Board #2.
//#define BOARD1   1   

//======================================
void main()
{
struct rx_stat rxstat;
int32 rx_id;
int32 tx_id;
int8 rx_len;               
int8 buffer[8];

can_init();
//can_set_mode(CAN_OP_LOOPBACK);

#ifdef BOARD1  // For Board #1
printf("?fOk.");
while(1)
  {
   output_toggle(PIN_C3);
   delay_ms(1000);
   buffer[0] = "x";   // Wait for a character

   // Transmit it to board #2.
   can_putd(BOARD2_ID, buffer, 1, 1, 1, 0);

   buffer[0] = 0;   // Clear the buffer byte

   // Wait for the char to be echoed back.
   while(!can_kbhit());

   if(can_getd(rx_id, buffer, rx_len, rxstat))
     {   
      if(rx_id == BOARD1_ID)  // Is it for this board ?
        {
         printf(buffer[0]);  // If so, display the char
        }
      }
  }
#else  // For Board #2
output_high(PIN_C3);
while(1)
  {
   if(can_kbhit())  // Message available ?
     {
   output_toggle(PIN_C3);
      // If so, get the message.
      if(can_getd(rx_id, buffer, rx_len, rxstat))
        {
         if(rx_id == BOARD2_ID)  // Is it for this board ?
           {
            // If so, echo back the character.
            can_putd(BOARD1_ID, buffer, 1, 1, 1, 0);
           }
         }
      }
  }
#endif
 
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Sep 15, 2009 9:08 pm     Reply with quote

Quote:
#include <18F2580.H>

#fuses HS, NOPROTECT, PUT, BROWNOUT, NOWDT, NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

#include <can-18xxx8.c>

The first thing to do would be to re-compile each board's firmware
with the can-18F4580.c driver, instead of the 18xxx8. driver.

The 18F2580 is part of the 18F4580 family. Here's the file location:
Quote:
c:\program files\picc\drivers\can-18f4580.c


Note: That driver file contains a #use rs232() statement. Since you
have one in your application program, just comment that line out
in the driver file.
halibatsuiba



Joined: 12 Aug 2009
Posts: 30

View user's profile Send private message

PostPosted: Wed Sep 16, 2009 7:41 am     Reply with quote

[quote="PCM programmer"]
Quote:
#include <18F2580.H>
The first thing to do would be to re-compile each board's firmware
with the can-18F4580.c driver, instead of the 18xxx8. driver.


I did that, no difference.
I replaced 2551's with new ones, just in case if they had some problems. No difference.
I also measured Vdd and Vss Nth time and everything seems to be ok.

Pics run ok, I can write to LCD and blink LEDs.

This must be something very simple that I just don't see now.

Last night, with oscilloscope, I found out that Board 1 sends data to CAN-line even if there is nobody in the other end of line.
According to test code, it should wait until it gets reply from board 2, but it transmits same sequence over and over again.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Sep 16, 2009 12:37 pm     Reply with quote

Does your schematic represent real hardware ? Because, there is no
MCLR circuit. There are no 100 nF ceramic caps on the Vdd pins on any
chip. Also, I would jumper the Rs pins on the MCP2551 chips to ground
for the inital tests.

Are you certain that you compiled two versions of the test program,
one for Board #1 and one for Board #2 ? There's a #define statement
that must be in there for the Bd #1 firmware, and then you must
comment it out for Bd #2. Carefully verify that you have done this.
Do a verify on each PIC with your ICD, to confirm that they contain
the correct program.

Also, your method of printing a variable does not work. The test
program shown below, proves this. It displays nothing.
Code:
#include <16F877.H>
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

//======================================
void main(void)
{
int8 buffer[8];


buffer[0] = "x";   

printf(buffer[0]);
 
while(1);
}

Your method of loading the buffer with a single ASCII character is not
correct.

Here's the ASM code where you load the buffer. It's not putting a string
in the buffer. It's just writing a single ASCII byte. It's pure luck that
the buffer RAM happens to come up initialized as 0x00, due to how the
PIC silicon operates. Due to this behavior, the buffer probably does
contain a 0x00 after the 'x' byte, thus creating a string.
Code:

........ buffer[0] = "x";     
MOVLW  78
MOVWF  21

You can initialize a string at runtime with the strcpy() function.
Or, you can init it at compile time, by doing what you did above, except
that 'buffer' must be set equal to "x" in the declaration statement.
Example, showing how it correctly works now:
Code:

...... int8 buffer[8] = "x"; 
MOVLW  78   // 'x'
MOVWF  21 
CLRF   22   // 0x00 string terminator


Quote:
printf(buffer[0]);

This is not the way that a single character is printed. You need to use
a format string, with "%c" to do that. Also, it's not the way that a
string is printed. You can printf a string by just giving it the buffer name:
Code:
printf(buffer);


However, you are just testing the transmission and reception of a single
char, so you shouldn't use a string (as shown above). You should use
only the single char methods.
halibatsuiba



Joined: 12 Aug 2009
Posts: 30

View user's profile Send private message

PostPosted: Wed Sep 16, 2009 1:10 pm     Reply with quote

PCM programmer wrote:
Does your schematic represent real hardware ? Because, there is no
MCLR circuit. There are no 100 nF ceramic caps on the Vdd pins on any
chip. Also, I would jumper the Rs pins on the MCP2551 chips to ground
for the inital tests.

Are you certain that you compiled two versions of the test program,
one for Board #1 and one for Board #2 ?
...
Also, your method of printing a variable does not work. The test
program shown below, proves this. It displays nothing.
...
However, you are just testing the transmission and reception of a single
char, so you shouldn't use a string (as shown above). You should use
only the single char methods.


Schema seems to be missing pull-up resistors of MCLR-pins and 100nF caps.
There are pull-ups and caps in hw.
.
Schema does not have LCD connection either. It is connected to C6.

Yes, I am sure I compiled two different versions. And also verified they were programmed correctly.

Variable printing... what was I thinking... That is corrected now.
With loopback testing it printed some garbage to LCD, but that time I used apostrophes instead of quotation marks.

Code:
buffer[0] = 'x';
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Sep 16, 2009 1:31 pm     Reply with quote

Is it now working ?

Here is how to initialize and display the first character in the buffer:
Code:

#include <16F877.H>
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

//======================================
void main(void)
{
int8 buffer[8];

buffer[0] = 'x';   

printf("%c", buffer[0]);
 
while(1);
}


The problem with this method is that if you get something other than
the expected byte, there's no guarantee that it will be a printable
character. It would be better to use "%x" to show a hex value in
the printf statement.
halibatsuiba



Joined: 12 Aug 2009
Posts: 30

View user's profile Send private message

PostPosted: Wed Sep 16, 2009 7:36 pm     Reply with quote

PCM programmer wrote:
Is it now working ?



Unfortunately no.
Problem is no in printing characters to LCD.

Either Board 1 does not even send any CAN-messages or board 2 does not receive/reply.

Board 1 gets stuck to

Code:
while(!can_kbhit());


after it presumably sends message and board 2 does not go inside the

Code:
if(can_kbhit())  // Message available ?


indicating it does not receive any messages.

Last night I checked CAN-line with oscilloscope and there is something,
some bit sequence that repeats even if I disconnect board 2.
This makes me think that problem is in board 1 sending. If it gets stuck to waiting can_kbhit, the bus should be silent if board 2 does not send anything. Right?

Tomorrow I will hook up the logic analyzer and check what is going on in there.
newguy



Joined: 24 Jun 2004
Posts: 1908

View user's profile Send private message

PostPosted: Thu Sep 17, 2009 10:03 am     Reply with quote

halibatsuiba wrote:
Last night I checked CAN-line with oscilloscope and there is something,
some bit sequence that repeats even if I disconnect board 2.
This makes me think that problem is in board 1 sending. If it gets stuck to waiting can_kbhit, the bus should be silent if board 2 does not send anything. Right?

Tomorrow I will hook up the logic analyzer and check what is going on in there.


The CAN protocol is very robust - it's not as simple as you think in that board 1 sends a message ONCE. The CAN protocol will automatically retry if the message wasn't received. Board 1 is expecting an ACK from board 2 when the message is sent. If the ACK is absent, board 1's CAN circuitry will automatically retransmit the message until it is ACKed.
halibatsuiba



Joined: 12 Aug 2009
Posts: 30

View user's profile Send private message

PostPosted: Thu Sep 17, 2009 10:21 am     Reply with quote

newguy wrote:

The CAN protocol is very robust - it's not as simple as you think in that board 1 sends a message ONCE. The CAN protocol will automatically retry if the message wasn't received. Board 1 is expecting an ACK from board 2 when the message is sent. If the ACK is absent, board 1's CAN circuitry will automatically retransmit the message until it is ACKed.


I have to admit I need to read more CAN specs. I am more familiar with IP-networking and i2c-bus.

Just checked with logic analyzer and yes, board 1 sends (and retransmits) same message several times. Board 2 does not care about the message, can_kbhit does not indicate received message at all.

Both boards work ok in loopback-mode.
Termination resistors are now required 120 ohms and Rs is connected to Vss.
I have replaced MCP2551s but it had no effect at all so I think they are ok.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Sep 17, 2009 11:42 am     Reply with quote

Post your current test program and post your compiler version.
halibatsuiba



Joined: 12 Aug 2009
Posts: 30

View user's profile Send private message

PostPosted: Thu Sep 17, 2009 11:55 am     Reply with quote

PCM programmer wrote:
Post your current test program and post your compiler version.


Compiler version 4.013

Code:
#include <18F2580.H>
#include <can-18F4580.h>

#fuses HS, NOPROTECT, PUT, BROWNOUT, NOWDT, NOLVP
#use delay(clock=20000000)

#include <C:\Program Files\PICC\Drivers\can-18f4580.c>

#define BOARD1_ID  24
#define BOARD2_ID  25

// Uncomment this line to compile code for Board #1.
// Comment it out to compile for Board #2.
#define BOARD1   1   

//======================================
void main()
{
struct rx_stat rxstat;
int32 rx_id;
int32 tx_id;
int8 rx_len;               
int8 buffer[8];

can_init();
printf("?fOk.");
//can_set_mode(CAN_OP_LOOPBACK);

#ifdef BOARD1  // For Board #1

while(1)
  {
   output_toggle(PIN_C3);
   delay_ms(1000);
   buffer[0] = 'x';

   // Transmit it to board #2.
   can_putd(BOARD2_ID, buffer, 1, 1, 1, 0);

   buffer[0] = 0;   // Clear the buffer byte

   // Wait for the char to be echoed back.
   while(!can_kbhit());

   if(can_getd(rx_id, buffer, rx_len, rxstat))
     {   
      if(rx_id == BOARD1_ID)  // Is it for this board ?
        {
         printf("%c",buffer[0]);  // If so, display the char
        }
      }
  }
#else  // For Board #2
output_high(PIN_C3);
while(1)
  {
   buffer[0] = 'x';
   if(can_kbhit())  // Message available ?
     {
   output_toggle(PIN_C3);
      // If so, get the message.
      if(can_getd(rx_id, buffer, rx_len, rxstat))
        {
         if(rx_id == BOARD2_ID)  // Is it for this board ?
           {
            // If so, echo back the character.
            can_putd(BOARD1_ID, buffer, 1, 1, 1, 0);
           }
         }
      }
  }
#endif
 
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Sep 17, 2009 11:56 am     Reply with quote

That's what I thought. That version is known to have bugs.
halibatsuiba



Joined: 12 Aug 2009
Posts: 30

View user's profile Send private message

PostPosted: Thu Sep 17, 2009 12:11 pm     Reply with quote

PCM programmer wrote:
That's what I thought. That version is known to have bugs.


darn.

I borrowed pickit3 + laptop with mplab and ccs-compiler from a friend to evaluate it if it suits my needs.

Looks like it will do what I need, if I can get this CAN working.

I am currently checking CCS website, I suppose "PCH Command-line Compiler for PIC18 MCU parts" would be the solution for me?
I mean I could use it with mplab ide?

If yes, I will buy it right away. Hopefully there is "download" option instead of using snailmail...

edit: Yes! There is a "download"-option. Now if I just would have some coupons...

edit2: but... butbut... PCH-compiler is said to be 16bit supporting PIC18-family. But Pic 18 is an 8-bit MCU. Confusing.

edit3: PCH compiler on its way. Yeah!
halibatsuiba



Joined: 12 Aug 2009
Posts: 30

View user's profile Send private message

PostPosted: Thu Sep 17, 2009 9:23 pm     Reply with quote

halibatsuiba wrote:

edit3: PCH compiler on its way. Yeah!


Allright. Now I have PCH version 4.099 but...

It did not make things magically work like charm.
Did I pay $200 for nothing? Confused

If Pcm Programmer thinks code is ok and this compiler version should have working CAN implementation, the only place where the problem can be is the hardware. Right?

Observations so far:
- Both boards work as expected in loopback mode (using board 1 sw).
- Verified with logic analyzer that there is data between board 1 pic and mcp2551
- Verified with oscilloscope (in board 2 end of line) that board 1 sends data resending it several times.
- Verified with pickit3 ICD that board 2 does not see messages in bus at all

Looks like the problem lies around board 2 mcp2551-chip or between it and pic 2.

Any ideas what to do/check really appreciated.

Thank you.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Sep 17, 2009 9:38 pm     Reply with quote

I'll get a couple of 18F2580's and test it. It should work. I don't know
why it doesn't work for you. I won't have an answer until the middle
of next week.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2, 3  Next
Page 1 of 3

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group