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 node implementation using PIC18F2585

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
kansusid



Joined: 12 Jun 2006
Posts: 9
Location: INDIA

View user's profile Send private message

CAN node implementation using PIC18F2585
PostPosted: Tue Aug 04, 2009 11:43 pm     Reply with quote

Could anyone help in implementation of a CAN node using PIC18F2585?
It is planned to test the node in Loop-back mode. What CCS program to use? Ex.CAN.c or EX.can_ccs_a.c or Ex.can_ccs_b.c ?? header file?? is it possible to have step_step explanations? the micro is working fine with RS232 as of now.
_________________
kansusid
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Aug 04, 2009 11:50 pm     Reply with quote

Use the forum's search page to find sample code and helpful hints:
http://www.ccsinfo.com/forum/search.php
Search for this:
Quote:
can bus loopback

Select the tickbox for: Search for all Terms

You will get 16 hits.
kansusid



Joined: 12 Jun 2006
Posts: 9
Location: INDIA

View user's profile Send private message

entering Loopback problem
PostPosted: Wed Aug 12, 2009 12:03 am     Reply with quote

We have implemented a CAN node using PIC18F2585 and MCP2551. Baud rate:125kbps@4MHz frequency. We have used the following code to test.
Code:

#include <18F2585.h>
#fuses XT,NOPROTECT,NOLVP,NOWDT,NOLVP,PUT,BROWNOUT
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, parity=N, bits=8)

#include <can-18xxx8.c>
 
#define CAN_ENABLE_DRIVE_HIGH  1

#define CAN_BRG_PRESCALER 1
#define CAN_BRG_SYNC_JUMP_WIDTH 0
#define CAN_BRG_PROPAGATION_TIME 0
#define CAN_BRG_PHASE_SEGMENT 3
#define CAN_BRG_SAM 0
#define CAN_BRG_SEG_2_PHASE_TS 1
#define CAN_BRG_PHASE_SEGMENT_2 1
#define CAN_BRG_WAKE_FILTER 0


void main() {
int32 can_id;
int can_data[8];
int can_length, counter;
struct rx_stat rxstat;

can_init();
printf("can example");
//can_set_mode(CAN_OP_LOOPBACK);
counter=0;

printf(" starting");
can_data[0]=0x55;

while(1)
{
 if( kbhit())
 {
  getch();
 
  if (can_putd(42,can_data,1,3,TRUE,FALSE))
     printf(" tx ok ");
 
  while(!can_kbhit());
  if (can_getd(can_id,&can_data[0],can_length,rxstat))
     printf("rx ok");
 
  counter++;
 }
}
}


The changes we did in can 18xxx8.c are given below:
Code:

void can_set_mode(CAN_OP_MODE mode) {
   CANCON.reqop=mode;
   printf("\r\nI am in mode change...");
   while( (CANSTAT.opmode) != mode );
}

void can_set_baud(void) {
BRGCON1=0x01;  //  for 4MHz,125kbps
BRGCON2=0x98;
BRGCON3=0x01;
/*// default code of CCS code segment now disabled
   BRGCON1.brp=CAN_BRG_PRESCALAR;
   BRGCON1.sjw=CAN_BRG_SYNCH_JUMP_WIDTH;

   BRGCON2.prseg=CAN_BRG_PROPAGATION_TIME;
   BRGCON2.seg1ph=CAN_BRG_PHASE_SEGMENT_1;
   BRGCON2.sam=CAN_BRG_SAM;
   BRGCON2.seg2phts=CAN_BRG_SEG_2_PHASE_TS;

   BRGCON3.seg2ph=CAN_BRG_PHASE_SEGMENT_2;
   BRGCON3.wakfil=CAN_BRG_WAKE_FILTER;*/
}

1. It seems that in normal mode it is able to transmit a data but we could not read the data. Why it happens?? Is there any problem with the code?

2. It doesn't enter into loopback mode at all. To enter into loopback mode, the modifications done are given below.
Code:
can_init();
printf("can example");
can_set_mode(CAN_OP_LOOPBACK); // uncommented this line for  //Loopback


3. To implement Loopback what more to be done in the code?? At the hardware side, we have MCP2551 and the connections are as follows
Code:

PIC18F2585---------------------MCP2551
pin 23(CANTX)-----------------> pin1
pin24(CANRX)------------------> pin4
--------------------------------pin 3---->+5V
--------------------------------pin 8---->47Kohms-->gnd
--------------------------------pin2----->gnd
--------------------------------pin7 and pin6 --- a 100 ohm between

For loop back, what connections need to be made? Simply short pin7 and pin 6 of MCP2551? Should we have the 100 ohm resistor connected?

Even in normal mode, if we want to send the data out from CANTX and receive it back through CANRX, what kind of connection needs to be done?
_________________
kansusid
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Aug 12, 2009 1:02 pm     Reply with quote

Quote:
void can_set_baud(void) {
BRGCON1=0x01; // for 4MHz,125kbps
BRGCON2=0x98;
BRGCON3=0x01;

Post how you got these parameters. If you used the MBTime program,
then post a detailed description of the settings at each step in that
program, so that I can duplicate the steps and check if you did it correctly.
kansusid



Joined: 12 Jun 2006
Posts: 9
Location: INDIA

View user's profile Send private message

PostPosted: Wed Aug 12, 2009 11:01 pm     Reply with quote

The settings were based on MBTime program only. Settings were basically obtained for 4MHz, 125 kbps
No. of time quanta for 1 bit time=8, propagation delay=1 Tq, Phase segment 1 and 2 = 3 Tq each, synchro jump width=1 Tq.

Correspondingly, the register settings are calculated as
Code:
BRGCON1=0x01;  //  for 4MHz,125kbps
BRGCON2=0x98;
BRGCON3=0x01;

After a long struggle, We got the following code working in the Loop back mode.

Code:
#include <18F2585.h>
#fuses XT,NOPROTECT,NOLVP,NOWDT
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#define CAN_ENABLE_DRIVE_HIGH  1

#define CAN_BRG_PRESCALER 1
#define CAN_BRG_SYNC_JUMP_WIDTH 0
#define CAN_BRG_PROPAGATION_TIME 0
#define CAN_BRG_PHASE_SEGMENT 3
#define CAN_BRG_SAM 0
#define CAN_BRG_SEG_2_PHASE_TS 1
#define CAN_BRG_PHASE_SEGMENT_2 1
#define CAN_BRG_WAKE_FILTER 0

#include <can-18xxx8.c>

int16 ms;

#int_timer2
void isr_timer2(void) {
   ms++; //keep a running timer that increments every milli-second
}

void main() {
   struct rx_stat rxstat;
   int32 rx_id;
   int in_data[8];
   int rx_len;

//send a request (tx_rtr=1) for 8 bytes of data (tx_len=8) from id 24 (tx_id=24)
   int out_data[8];
   int32 tx_id=24;
   int1 tx_rtr=0;
   int1 tx_ext=1;
   int tx_len=8;
   int tx_pri=3;

   int i;

   for (i=0;i<8;i++) {
      out_data[i]=0xFC;
      in_data[i]=0;
   }

   printf("\r\n\r\nCCS CAN EXAMPLE\r\n");

   setup_timer_2(T2_DIV_BY_4,79,16);   //setup up timer2 to interrupt every 1ms if using 20Mhz clock

   can_init();
  can_set_mode(CAN_OP_loopback);
   enable_interrupts(INT_TIMER2);   //enable timer2 interrupt
   enable_interrupts(GLOBAL);       //enable all interrupts (else timer2 wont happen)

   printf("\r\nRunning...");

   while(TRUE)
   {

      if ( can_kbhit() )   //if data is waiting in buffer...
      {
         if(can_getd(rx_id, &in_data[0], rx_len, rxstat)) { //...then get data from buffer
            printf("\r\nGOT: BUFF=%U ID=%LU LEN=%U OVF=%U ", rxstat.buffer, rx_id, rx_len, rxstat.err_ovfl);
            printf("FILT=%U RTR=%U EXT=%U INV=%U", rxstat.filthit, rxstat.rtr, rxstat.ext, rxstat.inv);
            printf("\r\n    DATA = ");
            for (i=0;i<rx_len;i++) {
               printf("%X ",in_data[i]);
            }
            printf("\r\n");
         }
         else {
            printf("\r\nFAIL on GETD\r\n");
         }

      }

      //every two seconds, send new data if transmit buffer is empty
      if ( can_tbe() && (ms > 2000))
      {
         ms=0;
         i=can_putd(tx_id, out_data, tx_len,tx_pri,tx_ext,tx_rtr); //put data on transmit buffer
         if (i != 0xFF) { //success, a transmit buffer was open
            printf("\r\nPUT %U: ID=%LU LEN=%U ", i, tx_id, tx_len);
            printf("PRI=%U EXT=%U RTR=%U\r\n   DATA = ", tx_pri, tx_ext, tx_rtr);
            for (i=0;i<tx_len;i++) {
               printf("%X ",out_data[i]);
            }
            printf("\r\n");
         }
         else { //fail, no transmit buffer was open
            printf("\r\nFAIL on PUTD\r\n");
         }
      }
   }
}

However the following things need some explanations:

a) Problems observed in Loopback mode:

1. It works when either momentarily short cantx and canrx of PIC18F2585, remove afterwards or keep them shorted always. It continued to work.

2. It works when MCP2551 is connected.

Do these show any problem regarding pull ups?? will it work if I either enable port b pull ups or connect a pull up resistor at CANTX of PIC18F2585.

b)we tried to change to normal mode with following changes

1.//can_set_mode(CAN_OP_loopback);
2. Connected a 120 ohm resistor across the output of MCP2551(CANHI and CANLOW)

The problem now is

1. The data is output only for three times and nothing works afterwards.

2. No data is received not even once. (Should we short CANHI and CANLO of MCP2551 if we want transmit and receive the same data through MCP2551??)

What could be the problems and possible solution for the above??

If we want to implement two nodes using PIC2585 and MCP2551 and connect them, what kind of connections should be made??
_________________
kansusid
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Aug 12, 2009 11:55 pm     Reply with quote

You shouldn't have to short the external CANTX and CANRX pins on
the PIC. The Loopback is done internally, inside the PIC. The 18F2585
data sheet says:
Quote:

23.3.5 LOOPBACK MODE
This mode will allow internal transmission of messages
from the transmit buffers to the receive buffers without
actually transmitting messages on the CAN bus. This
mode can be used in system development and testing.
In this mode, the ACK bit is ignored and the device will
allow incoming messages from itself, just as if they
were coming from another node. The Loopback mode
is a silent mode, meaning no messages will be
transmitted while in this state, including error flags or
Acknowledge signals. The TXCAN pin will revert to port
I/O while the device is in this mode. The filters and
masks can be used to allow only particular messages
to be loaded into the receive registers. The masks can
be set to all zeros to provide a mode that accepts all
messages. The Loopback mode is activated by setting
the mode request bits in the CANCON register.
kansusid



Joined: 12 Jun 2006
Posts: 9
Location: INDIA

View user's profile Send private message

PostPosted: Thu Aug 13, 2009 12:08 am     Reply with quote

that's fine. I have also gone through it. thanks.

What could be the problem in normal mode operation where it stops after outputting data 3 times and stops( nothing prints on the serial port monitor screen afterwards??).

In connecting 2 nodes using MCP2551, could you pl suggest the hardware connections and simple code to just check handshaking ok?

thanks in advance
_________________
kansusid
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Aug 13, 2009 12:53 am     Reply with quote

This post has a simple test program for two CAN bus boards to
communicate with each other.
http://www.ccsinfo.com/forum/viewtopic.php?t=29627&start=7


I notice you have a 47K resistor for RS on the MCP2551. I think that
value is too large. In the designs at our company, we connect the Rs
pin to Ground. We have pads for a resistor on the board, but we install
a 0-ohm resistor.

To connect the two CAN bus boards together:

1. Put a 120 ohm resistor across the CANH and CANL pins of the MCP2551 on each board. The resistors should be mounted close
to the MCP2551 on each board.

2. Connect CANH on Board #1 to CANH on board #2.

3. Connect CANL on Board #1 to CANL on board #2.

4. Connect a ground wire between both boards.

The two wires for CANH and CANL should be twisted pair.

There is a drawing in this link:
http://www.interfacebus.com/Design_Connector_CAN.html
kansusid



Joined: 12 Jun 2006
Posts: 9
Location: INDIA

View user's profile Send private message

PostPosted: Thu Aug 13, 2009 3:31 am     Reply with quote

Thanks for the details. Is it possible to have some thought over only 3 times output in normal mode? Since few others have had this problem(can be seen in the forum postings), is it a common bug? My compiler version PCWHD 4.0.0.0

Thanks in advance
_________________
kansusid
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Aug 13, 2009 11:50 am     Reply with quote

Quote:

In connecting 2 nodes using MCP2551, could you pl suggest the hardware connections and simple code to just check handshaking ok?

Is it possible to have some thought over only 3 times output in normal mode?

Why don't you try the two board test program (and the connections)
that I posted in response to your request ? See if it works.

Quote:
My compiler version PCWHD 4.0.0.0

That's not the compiler version. You probably got that number
by right-clicking on the CCS icon and going to the Properties box.
The compiler version is given at the top of the .LST file. It's a number
in this format: 4.xxx
The .LST file is in your project directory.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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