|
|
View previous topic :: View next topic |
Author |
Message |
kansusid
Joined: 12 Jun 2006 Posts: 9 Location: INDIA
|
CAN node implementation using PIC18F2585 |
Posted: Tue Aug 04, 2009 11:43 pm |
|
|
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
|
|
Posted: Tue Aug 04, 2009 11:50 pm |
|
|
Use the forum's search page to find sample code and helpful hints:
http://www.ccsinfo.com/forum/search.php
Search for this:
Select the tickbox for: Search for all Terms
You will get 16 hits. |
|
|
kansusid
Joined: 12 Jun 2006 Posts: 9 Location: INDIA
|
entering Loopback problem |
Posted: Wed Aug 12, 2009 12:03 am |
|
|
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
|
|
Posted: Wed Aug 12, 2009 1:02 pm |
|
|
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
|
|
Posted: Wed Aug 12, 2009 11:01 pm |
|
|
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
|
|
Posted: Wed Aug 12, 2009 11:55 pm |
|
|
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
|
|
Posted: Thu Aug 13, 2009 12:08 am |
|
|
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
|
|
Posted: Thu Aug 13, 2009 12:53 am |
|
|
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
|
|
Posted: Thu Aug 13, 2009 3:31 am |
|
|
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
|
|
Posted: Thu Aug 13, 2009 11:50 am |
|
|
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. |
|
|
|
|
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
|