|
|
View previous topic :: View next topic |
Author |
Message |
girichavana
Joined: 21 Oct 2008 Posts: 17
|
CAN Node with PIC16F877A and MCP2515 |
Posted: Thu Aug 06, 2009 8:35 am |
|
|
Hi,
I am designing the two CAN nodes with PIC16F877A and MCP2515.
I am using the CCS C libraries:
Code: |
#include <can-mcp251x.h>
#include <can-mcp251x.c>
|
But I am not getting the proper output.
Please verify my code.
Here is my code:
For NODE1:
Code: |
#include <16F877A.h>
#fuses HS,NOPROTECT,NOLVP,NOWDT
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#define CAN_DO_DEBUG TRUE
#define EXT_CAN_CS PIN_D1
#define EXT_CAN_SI PIN_C4
#define EXT_CAN_SO PIN_C5
#define EXT_CAN_SCK PIN_C3
#include <can-mcp251x.h>
#include <can-mcp251x.c>
#define PIN_LED1 PIN_A1
#define PIN_LED2 PIN_A2
#define PIN_LED3 PIN_A3
#define LED1_HIGH output_low(PIN_LED1)
#define LED1_LOW output_high(PIN_LED1)
#define LED2_HIGH output_low(PIN_LED2)
#define LED2_LOW output_high(PIN_LED2)
#define LED3_HIGH output_low(PIN_LED3)
#define LED3_LOW output_high(PIN_LED3)
int16 ms;
#int_timer2
void isr_timer2(void) {
ms++; //keep a running timer that increments every milli-second
}
#define RESPOND_TO_ID_AD 0x201
#define RESPOND_TO_ID_LED 0x202
void main()
{
struct rx_stat rxstat;
int32 rx_id;
int buffer[8];
int rx_len;
int i;
setup_port_a(RA0_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
for(i=0;i<8;i++) {
buffer[i]=0;
}
LED1_HIGH;
LED2_HIGH;
LED3_HIGH;
printf("\r\n\r\nCCS CAN EXAMPLE\r\n");
delay_ms(1000);
LED1_LOW;
LED2_LOW;
LED3_LOW;
setup_timer_2(T2_DIV_BY_4,53,3);
can_init();
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, &buffer[0], rx_len, rxstat)) //...then get data from buffer
{
if (rx_id == RESPOND_TO_ID_LED)
{
printf("Chaning LEDs\r\n\r\n");
if (bit_test(buffer[0],0)) {LED1_HIGH;} else {LED1_LOW;}
if (bit_test(buffer[0],1)) {LED2_HIGH;} else {LED2_LOW;}
if (bit_test(buffer[0],2)) {LED3_HIGH;} else {LED3_LOW;}
}
if (rx_id == RESPOND_TO_ID_AD)
{
i=read_adc();
printf("Sending AD reading: %X\r\n\r\n",i);
can_putd(RESPOND_TO_ID_AD, &i, 1,1,1,0); //put data on transmit buffer
}
}
}
}
}
|
For NODE2:
Code: |
#include <16F877A.h>
#fuses HS,NOPROTECT,NOLVP,NOWDT
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#define CAN_DO_DEBUG TRUE
#define EXT_CAN_CS PIN_D1
#define EXT_CAN_SI PIN_C4
#define EXT_CAN_SO PIN_C5
#define EXT_CAN_SCK PIN_C3
#include <can-mcp251x.H>
#include <can-mcp251x.c>
#define BUTTON PIN_A4
#define BUTTON_PRESSED !input(BUTTON)
#define PIN_LED1 PIN_A1
#define PIN_LED2 PIN_A2
#define PIN_LED3 PIN_A3
#define LED1_HIGH output_low(PIN_LED1)
#define LED1_LOW output_high(PIN_LED1)
#define LED2_HIGH output_low(PIN_LED2)
#define LED2_LOW output_high(PIN_LED2)
#define LED3_HIGH output_low(PIN_LED3)
#define LED3_LOW output_high(PIN_LED3)
int16 ms;
#int_timer2
void isr_timer2(void) {
ms++; //keep a running timer that increments every milli-second
}
#define ASK_FOR_ID_AD_B 0x201 //ask for AD info from CAN port B
#define SET_LED_ID_B 0x202 //set LEDs for CAN port B
void main()
{
int b_leds=0;
struct rx_stat rxstat;
int32 rx_id;
int buffer[8];
int rx_len;
int i;
setup_port_a(RA0_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
for(i=0;i<8;i++) {
buffer[i]=0;
}
LED1_HIGH;
LED2_HIGH;
LED3_HIGH;
printf("\r\n\r\nCCS CAN EXAMPLE\r\n");
delay_ms(1000);
LED1_LOW;
LED2_LOW;
LED3_LOW;
setup_timer_2(T2_DIV_BY_4,53,3);
can_init();
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() )
{
printf("\r\n");
if(can_getd(rx_id, &buffer[0], rx_len, rxstat)) {
if (rx_id == ASK_FOR_ID_AD_B) {
printf("Channel B AD: %X\r\n",buffer[0]);
}
}
}
if ( can_tbe() && (ms > 2000)) //every two seconds, send new data if transmit buffer is empty
{
ms=0;
//change leds on port b
printf("\r\n\r\nSet LEDs on Port B to %U",b_leds);
can_putd(SET_LED_ID_B, &b_leds, 1, 1, 1, 0);
b_leds++;
if (b_leds > 7) {b_leds=0;}
}
}
}
|
Thanks and regards. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
girichavana
Joined: 21 Oct 2008 Posts: 17
|
|
Posted: Thu Aug 06, 2009 10:14 pm |
|
|
Hi,
Thanks for the reply
How to set my hardware to the LOOPBACK mode.
Its not mentioned in the forum
Thanks and regards |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Aug 06, 2009 11:11 pm |
|
|
There's a link to the loopback code, in the link that I posted above.
All you have to do, is to change the #include file for your PIC,
and for the CAN driver. I can't test this in hardware at the moment,
but it will probably work. Change the #define statements for the
pin connections to your MCP2515 chip if they are different than the
connections given below.
Code: |
#include <16F877A.h>
#fuses HS, NOWDT, BROWNOUT, PUT, NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
// *** Change these pins to match your connections ***
#define EXT_CAN_CS PIN_B1
#define EXT_CAN_SI PIN_C1
#define EXT_CAN_SO PIN_C0
#define EXT_CAN_SCK PIN_C3
#include <can-mcp251x.c>
void main(void)
{
int32 can_id;
int can_data[8];
int can_length, counter;
struct rx_stat rxstat;
can_init();
can_set_mode(CAN_OP_LOOPBACK);
counter = 0;
puts("Starting");
can_data[0] = 0x55;
while(1)
{
if(kbhit())
{
getch();
if(can_putd(42, can_data, 1, 3, TRUE, FALSE))
puts("tx ok");
while(!can_kbhit());
if(can_getd(can_id, &can_data[0], can_length, rxstat))
puts("rx ok");
counter++;
}
}
}
|
|
|
|
girichavana
Joined: 21 Oct 2008 Posts: 17
|
|
Posted: Fri Aug 07, 2009 2:20 am |
|
|
Hi,
I am getting the output as follows for the above code
rx ok
Starting
tx ok
rx ok
rx ok
Starting
rx ok
tx ok
rx ok
rx ok
rx ok
rx ok
rx ok
rx ok
rx ok
rx ok
rx ok
rx ok
rx ok
tx ok
rx ok
tx ok
it is getting "rxok" continuously but not the "txok"
I am using the 4MHz for my PIC and 16MHz for my MCP2515
Thanks and regards |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Aug 07, 2009 1:05 pm |
|
|
1. Post a list of connections between your PIC and the MCP2515.
Post the actual pin numbers, not just the signal names.
2. Did you build this board yourself, or did you buy the board ?
If bought the board, post the manufacturer and model number.
3. Did you modify the code that I posted ? If so, post the actual code
that you are using for the test.
4. Post your compiler version. |
|
|
girichavana
Joined: 21 Oct 2008 Posts: 17
|
|
Posted: Thu Aug 20, 2009 1:05 am |
|
|
Hi,
I don't know how to post the .jpg file.
The board is designed by myself.
I modified the code as follows:
Code: |
#include <16F877A.h>
#fuses HS,NOPROTECT,NOLVP,NOWDT
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
// *** Change these pins to match your connections ***
#define EXT_CAN_CS PIN_D1
#define EXT_CAN_SI PIN_C4
#define EXT_CAN_SO PIN_C5
#define EXT_CAN_SCK PIN_C3
#include <can-mcp251x.c>
void main(void)
{
int32 can_id;
int can_data[8];
int can_length, counter;
struct rx_stat rxstat;
puts("Can Sample");
can_init();
can_set_mode(CAN_OP_LOOPBACK);
counter = 0;
puts("Starting");
can_data[0] = 0x55;
while(1)
{
if(kbhit())
{
getch();
if(can_putd(42, can_data, 1, 3, TRUE, FALSE))
puts("tx ok");
while(!can_kbhit());
if(can_getd(can_id, &can_data[0], can_length, rxstat))
puts("rx ok");
counter++;
}
}
} |
I am using the PCM version 4.068. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Aug 20, 2009 1:17 am |
|
|
Post the output that you get from that program, during a recent test. |
|
|
girichavana
Joined: 21 Oct 2008 Posts: 17
|
|
Posted: Thu Aug 20, 2009 2:58 am |
|
|
Hi,
The following is the output
Can Sample
Starting
tx ok
rx ok
rx ok
tx ok
rx ok
rx ok
tx ok
rx ok
rx ok
rx ok
tx ok
rx ok
tx ok
rx ok
tx ok
rx ok
tx ok
rx ok
rx ok |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Aug 21, 2009 2:23 pm |
|
|
It worked for me. Here's the output. I added some printf statements
at the start of the program to trace the program flow.
Quote: |
Can Sample
Can init done
Loopback mode set
Starting
tx ok
rx ok
tx ok
rx ok
tx ok
rx ok
tx ok
rx ok
tx ok
rx ok
tx ok
rx ok
tx ok
rx ok
tx ok
rx ok
tx ok
rx ok
tx ok
rx ok
tx ok
rx ok
tx ok
rx ok
|
I installed vs. 4.068 of the compiler. I modified a Microchip MCP2510
Development kit board to use a 4 MHz external oscillator for the PIC
(but keeping the 16 MHz oscillator for the MCP2510).
Also, I didn't have a MCP2515 so I had to use an MCP2510. In the
mode that we are using in this program, I think they are compatible.
But still, there could possibly be a difference that is causing a problem.
Code: |
#include <16F877A.h>
#fuses HS,NOPROTECT,NOLVP,NOWDT
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
// These connections are for the Microchip MCP2510 Dev. board
#define EXT_CAN_CS PIN_C2
#define EXT_CAN_SO PIN_C4
#define EXT_CAN_SI PIN_C5
#define EXT_CAN_SCK PIN_C3
#include <can-mcp251x.c>
void main(void)
{
int32 can_id;
int can_data[8];
int can_length, counter;
struct rx_stat rxstat;
puts("Can Sample");
can_init();
puts("Can init done");
can_set_mode(CAN_OP_LOOPBACK);
puts("Loopback mode set");
counter = 0;
puts("Starting");
can_data[0] = 0x55;
while(1)
{
if(kbhit())
{
getch();
if(can_putd(42, can_data, 1, 3, TRUE, FALSE))
puts("tx ok");
while(!can_kbhit());
if(can_getd(can_id, &can_data[0], can_length, rxstat))
puts("rx ok");
counter++;
}
}
} |
|
|
|
girichavana
Joined: 21 Oct 2008 Posts: 17
|
|
Posted: Fri Oct 16, 2009 7:34 am |
|
|
After a long time again I started to fight with the CAN.
My board is not answering properly for the loopback mode.
Is it needs any pullups for the IO lines b/w the PIC and the MCP2551?
Thanks |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Oct 16, 2009 12:42 pm |
|
|
Quote: | Is it needs any pullups for the IO lines b/w the PIC and the MCP2551? |
The PIC doesn't connect to the MCP2551 transceiver. The PIC connects
to the MCP2515 controller. The connections look like this:
Code: | PIC <---> MCP2515 <---> MCP2551 <---> CAN bus cable |
Also, in LOOPBACK mode, the MCP2515 controller doesn't use any
external components. The MCP2551 transceiver is not required.
See the MCP2515 data sheet:
http://ww1.microchip.com/downloads/en/DeviceDoc/21801e.pdf
Quote: | 10.4 Loopback Mode
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 be in a recessive state.
|
|
|
|
girichavana
Joined: 21 Oct 2008 Posts: 17
|
|
Posted: Sat Oct 17, 2009 11:26 pm |
|
|
Sry,
I connected PIC to MCP2515 only. By mistake I entered MCP2551 instead of MCP2515.
With the above program I am not getting the CAN Initializing properly.
It is giving the output as follows.
Can Sample
<here it is waiting for a long time, if I touch the soldering side of the board at the MCP2515 then it is giving the below sentence>
Can init done
Loopback mode set
Starting
<Now I am pressing the keys in my PC, for the each key press it is not giving the txok and rxok strings, it is giving randomly as follows >
txok
rxok
txok
rxok
txok
rxok
rxok
txok
rxok
txok
rxok
rxok
like it is giving only rxok for a key press.
Thanks |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Oct 18, 2009 3:21 pm |
|
|
Quote: |
If I touch the soldering side of the board at the MCP2515 then it is giving
the below sentence.
|
1. What is connected to the \RESET pin on the MCP2515 ? Describe
the circuit.
2. Describe the connections to the OSC1 and OSC2 pins on the MCP2515.
What components are connected to those pins ? What are their values ?
Or, post a link to the schematic for your board. |
|
|
girichavana
Joined: 21 Oct 2008 Posts: 17
|
|
|
|
|
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
|