|
|
View previous topic :: View next topic |
Author |
Message |
Guest
|
Can't Communicate Using CAN MCP2515 |
Posted: Fri Jan 26, 2007 3:04 pm |
|
|
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
|
|
Posted: Fri Jan 26, 2007 3:25 pm |
|
|
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
|
|
Posted: Mon Jan 29, 2007 4:22 am |
|
|
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
|
|
Posted: Mon Jan 29, 2007 6:06 am |
|
|
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
|
|
Posted: Mon Jan 29, 2007 7:13 am |
|
|
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
|
|
Posted: Mon Jan 29, 2007 11:02 am |
|
|
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
|
|
|
|
|
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
|