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't Communicate Using CAN MCP2515

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








Can't Communicate Using CAN MCP2515
PostPosted: Fri Jan 26, 2007 3:04 pm     Reply with quote

Hello, I'm trying to make two 16F876A communicate using a MCP2515.

I'm using the can-mcp2510.c library, but I can't transmit anything.

I've already tested to see if the SPI is working, and it is.

Apparently the program is not transmitting, because it tries first in the Buffer 0, then 1 and 2 and then I can't try anymore.

I'd appreciate if anyone could point if I am doing some mistake.

Here are the program for the node A:
Quote:

#include <16F876A.h>
#device ICD=TRUE
#device adc=8


#FUSES HS,NOWDT,PUT,NOLVP
#use delay(clock=16000000,RESTART_WDT)
#define Audio PIN_A0
#define LED2 PIN_A2
#define DPCBUSOUT PIN_A4
#define DPCBUSIN PIN_A5
#define CANINT PIN_B0
#define CANRESET PIN_B1
#define AUXOUT1 PIN_B2
#define SOSP PIN_B6
#define CANCS PIN_C0
#define CANSCK PIN_C1
#define CANDIO PIN_C2
#define CANTX0RTS PIN_C5
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#use i2c(Master,Fast,sda=PIN_C4,scl=PIN_C3,restart_wdt)


#define CAN_BRG_PRESCALAR 0 //baud rate generator prescalar (def: 4) ( Tq = (2 x (PRE + 1))/Fosc )
#define CAN_BRG_PROPAGATION_TIME 0 //propagation time select (def: 3 x Tq)
#define CAN_BRG_PHASE_SEGMENT_1 4 //phase segment 1 (def: 6 x Tq)
#define CAN_BRG_PHASE_SEGMENT_2 2 //phase segment 2 time select (def: 6 x Tq)
#define CAN_BRG_SYNCH_JUMP_WIDTH 0 //synchronized jump width (def: 1 x Tq)

#define CAN_DO_DEBUG TRUE // Precisa ligar a UART para funcionar
#include "can-mcp2510.c"


int16 ms;


#int_EXT
EXT_isr()
{
delay_ms(1);
}


#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 buffer[8];
int rx_len;

int32 tx_id;

long int i;

setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
setup_timer_0(RTCC_INTERNAL);setup_wdt(WDT_1152MS);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_16,16,16);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);

output_high(CANTX0RTS);

for(i=0;i<8;i++) {
buffer[i]=0;
}

#ifdef CAN_DO_DEBUG
printf ("System Initialized\r");
putc(0x0A);
#endif


can_init();

enable_interrupts(INT_EXT);
enable_interrupts(INT_TIMER2); //enable timer2 interrupt
enable_interrupts(GLOBAL); //enable all interrupts (else timer2 wont happen)

#ifdef CAN_DO_DEBUG
printf ("CAN Initialized\r");
putc(0x0A); //line feed
#endif


output_low(AUXOUT1);
delay_ms(50);
output_high(AUXOUT1);

/*
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);



while ( !can_tbe() ) //Wait Tx Buffer Ready
{}
tx_id = 0x202;
i = 90;
can_putd(tx_id, &i, 1,1,1,0); //put data on transmit buffer
output_low(CANTX0RTS);
delay_us(100);
output_high(CANTX0RTS);

*/

while(TRUE)
{
restart_wdt();

if ( can_tbe() && (ms > 2000)) //every two seconds, send new data if transmit buffer is empty
{
ms=0;
can_putd(0x201, 0, 1, 1, 1, 1);
}

if ( can_kbhit() )
{
printf("\r\n");
if(can_getd(rx_id, &buffer[0], rx_len, rxstat)) {
if (rx_id == 0x201) {
printf("Channel B AD: %X\r\n",buffer[0]);
}
}
}

}//end while
}


And This is node B


Quote:

#include <16F874.h>
#device ICD=TRUE
#device adc=8

#FUSES HS,NOWDT,PUT,NOLVP
#use delay(clock=16000000,RESTART_WDT)
#define CANCS PIN_C0
#define CANSCK PIN_C1
#define CANDIO PIN_C2
#define CANTX0RTS PIN_C5
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#use i2c(Master,Fast,sda=PIN_C4,scl=PIN_C3,restart_wdt)


#define CAN_BRG_PRESCALAR 0 //baud rate generator prescalar (def: 4) ( Tq = (2 x (PRE + 1))/Fosc )
#define CAN_BRG_PROPAGATION_TIME 0 //propagation time select (def: 3 x Tq)
#define CAN_BRG_PHASE_SEGMENT_1 4 //phase segment 1 (def: 6 x Tq)
#define CAN_BRG_PHASE_SEGMENT_2 2 //phase segment 2 time select (def: 6 x Tq)
#define CAN_BRG_SYNCH_JUMP_WIDTH 0 //synchronized jump width (def: 1 x Tq)
#define CAN_DO_DEBUG TRUE // Precisa ligar a UART para funcionar
#include "can-mcp2510.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 buffer[8];
int rx_len;
int32 tx_id;

long int i;

setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
setup_timer_0(RTCC_INTERNAL);setup_wdt(WDT_1152MS);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_16,16,16);
//setup_comparator(NC_NC_NC_NC);
//setup_vref(FALSE);

output_high(CANTX0RTS);

for(i=0;i<8;i++) {
buffer[i]=0;
}

#ifdef CAN_DO_DEBUG
printf ("System Initiated\r");
putc(0x0A);
#endif


can_init();


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


#ifdef CAN_DO_DEBUG
printf ("CAN Initiated\r");
putc(0x0A);
#endif


while(TRUE)
{
restart_wdt();
if ( can_kbhit() ) //if data is waiting in buffer...
{
if(can_getd(rx_id, &buffer[0], rx_len, rxstat)) //...then get data from buffer
{
printf ("Algo Recebido");
if (rx_id == 0x201)
{
printf ("SUCESS!!!");
i = 0x01;
can_putd(0x201, &i, 1,1,1,0); //put data on transmit buffer
}
}
}

}
}


I tried to do a program just like the CCS example, but it is not working...
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Jan 26, 2007 3:25 pm     Reply with quote

Quote:
#include <16F876A.h>
#device ICD=TRUE
#device adc=8

#FUSES HS,NOWDT,PUT,NOLVP
#use delay(clock=16000000,RESTART_WDT)
#define Audio PIN_A0
#define LED2 PIN_A2
#define DPCBUSOUT PIN_A4
#define DPCBUSIN PIN_A5
#define CANINT PIN_B0
#define CANRESET PIN_B1
#define AUXOUT1 PIN_B2
#define SOSP PIN_B6

You're using the ICD debugger, which uses pins B6 and B7, but you
have pin B6 assigned as an i/o pin. This could be a problem.

Also, are you using pin A4 as an output ? If so, you need to have
a pull-up resistor on it, because the pin A4 driver is open-drain.

You have a 1 ms delay inside the int_ext isr. Whenever an external
interrupt occurs, it's going to shut down other program operation for 1 ms.

I didn't really look closely at anything else.
supertorresmo
Guest







PostPosted: Mon Jan 29, 2007 4:22 am     Reply with quote

Well, I know the chosen Pins are not the problem because the PIC is communicating easily in SPI with the MCP2515. But the MCP can't communicate with the other node.

The 1ms interrupt is there just because it was in the program example "ex_can_ccs_b.c" and a tought that the CAN needed it. (It really does?)

Can someone help me plese?
sjbaxter



Joined: 26 Jan 2006
Posts: 141
Location: Cheshire, UK

View user's profile Send private message Visit poster's website

PostPosted: Mon Jan 29, 2007 6:06 am     Reply with quote

If you can put 3 mesages into the tx buffer and then nothing else happens, then it sounds like the messages are not actually been sent (physically) to the other device and they are filling up the available tx buffers.

A message will only leave the tx buffer if another node (device) receives the message without causing any errors on the bus. If the transmitting node sends a CAN message and either does not get an ACK from another device, or it causes a bus error due to the wrong bit speed, etc, then it holds onto it and tries again and again till it does.

I suggest putting the CAN controller into LOOPBACK mode and put the TX and RX code into a single node. Get this one node transmitting and receiveing (with the controller ACKing) its own message. That will ensure that you get your code bug free and doing the right thing.

When the code is right for a single node, connect a second node (with the same code) and run the controllers in NORMAL mode. Then you can debug the bus timings, wiring, termination, etc of the physical CAN layer.

Hope this helps.
_________________
Regards,
Simon.
Supertorresmo
Guest







PostPosted: Mon Jan 29, 2007 7:13 am     Reply with quote

sjbaxter, I did what you ssaid and I managed to make the CAN work.

For reference, I'll put here the code that worked:

Tx Node:
Quote:

#include <16F876A.h>
#device ICD=TRUE
#device adc=8


#FUSES HS,NOWDT,PUT,NOLVP
#use delay(clock=16000000,RESTART_WDT)
#define Audio PIN_A0
#define LED2 PIN_A2
#define DPCBUSOUT PIN_A4
#define DPCBUSIN PIN_A5
#define CANINT PIN_B0
#define CANRESET PIN_B1
#define AUXOUT1 PIN_B2
#define SOSP PIN_B6
#define CANCS PIN_C0
#define CANSCK PIN_C1
#define CANDIO PIN_C2
#define CANTX0RTS PIN_C5
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#use i2c(Master,Fast,sda=PIN_C4,scl=PIN_C3,restart_wdt)


#define CAN_BRG_PRESCALAR 0 //baud rate generator prescalar (def: 4) ( Tq = (2 x (PRE + 1))/Fosc )
#define CAN_BRG_PROPAGATION_TIME 0 //propagation time select (def: 3 x Tq)
#define CAN_BRG_PHASE_SEGMENT_1 4 //phase segment 1 (def: 6 x Tq)
#define CAN_BRG_PHASE_SEGMENT_2 2 //phase segment 2 time select (def: 6 x Tq)
#define CAN_BRG_SYNCH_JUMP_WIDTH 0 //synchronized jump width (def: 1 x Tq)

#define CAN_DO_DEBUG TRUE // Precisa ligar a UART para funcionar
#include "can-mcp2510.c"


int16 ms;


#int_EXT
EXT_isr()
{
delay_ms(1);
}


#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 buffer[8];
int rx_len;

int32 tx_id;

long int i;

setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
setup_timer_0(RTCC_INTERNAL);setup_wdt(WDT_1152MS);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_16,16,16);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);

output_high(CANTX0RTS);

for(i=0;i<8> 2000)) //every two seconds, send new data if transmit buffer is empty
{
ms=0;
i = 0x90;
can_putd(0x201, &i, 1, 1, 1, 0);
}


}//end while
}



Rx Node:
Quote:

#include <16F876A.h>
#device ICD=TRUE
#device adc=8


#FUSES HS,NOWDT,PUT,NOLVP
#use delay(clock=16000000,RESTART_WDT)
#define Audio PIN_A0
#define LED2 PIN_A2
#define DPCBUSOUT PIN_A4
#define DPCBUSIN PIN_A5
#define CANINT PIN_B0
#define CANRESET PIN_B1
#define AUXOUT1 PIN_B2
#define SOSP PIN_B6
#define CANCS PIN_C0
#define CANSCK PIN_C1
#define CANDIO PIN_C2
#define CANTX0RTS PIN_C5
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#use i2c(Master,Fast,sda=PIN_C4,scl=PIN_C3,restart_wdt)


#define CAN_BRG_PRESCALAR 0 //baud rate generator prescalar (def: 4) ( Tq = (2 x (PRE + 1))/Fosc )
#define CAN_BRG_PROPAGATION_TIME 0 //propagation time select (def: 3 x Tq)
#define CAN_BRG_PHASE_SEGMENT_1 4 //phase segment 1 (def: 6 x Tq)
#define CAN_BRG_PHASE_SEGMENT_2 2 //phase segment 2 time select (def: 6 x Tq)
#define CAN_BRG_SYNCH_JUMP_WIDTH 0 //synchronized jump width (def: 1 x Tq)

#define CAN_DO_DEBUG TRUE // Precisa ligar a UART para funcionar
#include "can-mcp2510.c"


int16 ms;


#int_EXT
EXT_isr()
{
delay_ms(1);
}


#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 buffer[8];
int rx_len;

int32 tx_id;

long int i;

setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
setup_timer_0(RTCC_INTERNAL);setup_wdt(WDT_1152MS);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_16,16,16);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);

output_high(CANTX0RTS);

for(i=0;i<8;i++) {
buffer[i]=0;
}

#ifdef CAN_DO_DEBUG
printf ("System Initialized\r");
putc(0x0A);
#endif


can_init();

enable_interrupts(INT_EXT);
enable_interrupts(INT_TIMER2); //enable timer2 interrupt
enable_interrupts(GLOBAL); //enable all interrupts (else timer2 wont happen)

#ifdef CAN_DO_DEBUG
printf ("CAN Initialized\r");
putc(0x0A); //line feed
#endif


//can_set_mode(CAN_OP_LOOPBACK);


while(TRUE)
{
restart_wdt();

if ( can_kbhit() )
{
if(can_getd(rx_id, &buffer[0], rx_len, rxstat)) {
if (rx_id == 0x201) {
printf("The Data Is: %X\r\n",buffer[0]);
}
}
}

}//end while
}


Thanks for the help!!!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jan 29, 2007 11:02 am     Reply with quote

Quote:
for(i=0;i<8> 2000)) //

Your latest post is garbled, because you didn't disable HTML
when you posted it.

You can't edit your post and fix it because you logged in as a guest.
sjbaxter



Joined: 26 Jan 2006
Posts: 141
Location: Cheshire, UK

View user's profile Send private message Visit poster's website

PostPosted: Wed Jan 31, 2007 6:01 am     Reply with quote

Supertorresmo, can you have a look at:

http://www.ccsinfo.com/forum/viewtopic.php?t=29627

and tell quad3 what your fix to you problem was. You may just be able to help someone out Very Happy
_________________
Regards,
Simon.
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