![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
otaggart
Joined: 24 Aug 2012 Posts: 4 Location: Canada
|
Please help: 18F25K80 CAN module not working [Solved] |
Posted: Fri Aug 24, 2012 4:11 pm |
|
|
I am attempting to set up the CAN module on the 18F25K80 so that I can communicate between PICs. My first test was simply to port EX_CAN.C included with the compiler to my chip. My only changes to EX_CAN.C are replacing the #FUSES and #include <18F25K80.h>, adding a blinking LED on A0, and changing the timer2 interrupt frequency to 1s instead of 2s. In one test I added a mode change to CAN_OP_LOOPBACK. I haven't modified can-18xxx8.c at all.
The code runs and claims it is putting data onto a transmit buffer, but viewing B2 (the CANTX pin) with an oscilloscope I cannot see any activity. Also when I try putting the CAN in loopback mode to test reception, the PIC gets stuck waiting for the mode change. I have looked at the register contents using ICD2 and found that while CANCON gets set to 0x40 during the mode switch operation (indicating a request for loopback mode), CANSTAT refuses to change from 0x00 which causes the stall.
Any ideas? Compiler v4.120.
Code: |
#include <18F25K80.h>
#device adc=12
#FUSES NOWDT //No Watch Dog Timer
#FUSES SOSC_DIG //Digital mode, I/O port functionality of RC0 and RC1
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES HSH //High speed Osc, high power 16MHz-25MHz
#FUSES NOPLLEN //4X HW PLL disabled, 4X PLL enabled in software
#FUSES NOBROWNOUT //No brownout reset
#use delay(clock=20000000)
#use rs232(baud=19200,parity=N,UART1,bits=8,stream=PORT1)
#define BLINKER PIN_A0
#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=1;
int1 tx_ext=0;
int tx_len=8;
int tx_pri=3;
int i;
for (i=0;i<8;i++) {
out_data[i]=0;
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();
enable_interrupts(INT_TIMER2); //enable timer2 interrupt
enable_interrupts(GLOBAL); //enable all interrupts (else timer2 wont happen)
can_set_mode(CAN_OP_LOOPBACK);
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 > 1000))
{
output_toggle(BLINKER);
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");
}
}
}
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Sat Aug 25, 2012 4:19 am |
|
|
Funny, two people jumping on the same 'wrong bandwagon' at the same time.
The 25K80, does not have the CAN module, it has the _ECAN_ module.
Drivers for the 18xxx8, are for the former.
Look at the driver for the 4580.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
otaggart
Joined: 24 Aug 2012 Posts: 4 Location: Canada
|
|
Posted: Tue Aug 28, 2012 3:20 pm |
|
|
Ok, I have tried switching to the can-18F4580 driver (I simply changed the include line in my code). There is no change in the results; no activity on CANTX in normal mode and attempting to switch to loopback mode causes the chip to get stuck waiting for the mode change (CANCON=0x40 but CANSTAT=0x00). I even tried adding a can_abort() inside the mode change function in case it was refusing to switch because a transmission was pending. No success. Any further ideas? |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Aug 28, 2012 5:02 pm |
|
|
I made Loopback mode work with a 18F46K80 with compiler vs. 4.120
in hardware (It also works with vs. 4.135). The 18F46K80 is in the same
family as your PIC so it should work for you too. I'm using a 20 MHz
crystal. Here's what I had to do:
1. Make a project for Ex_CAN.c
2. Change the top lines so they look like this:
Code: |
#include <18F46K80.h>
#fuses HSH,NOWDT,BROWNOUT,PUT,NOPLLEN,SOSC_DIG,NOIESO,NOFCMEN
#use delay(clock=20M)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#include <can-18F4580.c>
|
Most of those fuses are absolutely essential.
Note, it also works with the line below for the CAN bus driver, I think
because we're not using any of the ECAN capabilities for the Loopback test:
Code: |
#include <can-18xxx8.c>
|
3. Comment out the two lines shown below, and substitute the new
initialization lines shown after them:
Code: |
// int1 tx_rtr=1;
// int1 tx_ext=0;
int1 tx_rtr=0; // *** Changed to 0
int1 tx_ext=1; // *** Changed to 1
|
4. Add the line for Loopback mode right after the can_init() line, as
shown below:
Code: |
can_init();
can_set_mode(CAN_OP_LOOPBACK); // *** Add this line
|
5. Add a 4.7K pull-up resistor (to the PIC's Vdd voltage) on the CANRX
pin (Pin B3) of the PIC. This is essential for loopback mode. If you
have a CAN bus driver chip such as the MCP2551 connected to the
CANTX and CANRX pins, this will also make it work. In that case, you
don't need the pull-up.
6. I also changed the data to sequential numbers instead of 0's, by
adding the lines shown below to initialize the out_data[] array:
Code: |
if ( can_tbe() && (ms > 2000))
{
ms=0;
out_data[0]= 0; // *** Add these 8 lines
out_data[1]= 1;
out_data[2]= 2;
out_data[3]= 3;
out_data[4]= 4;
out_data[5]= 5;
out_data[6]= 6;
out_data[7]= 7; |
Then I ran the program and got this output on the TeraTerm window
on my PC:
Quote: |
CCS CAN EXAMPLE
Running...
PUT 1: ID=24 LEN=8 PRI=3 EXT=1 RTR=0
DATA = 00 01 02 03 04 05 06 07
GOT: BUFF=0 ID=24 LEN=8 OVF=0 FILT=0 RTR=0 EXT=1 INV=0
DATA = 00 01 02 03 04 05 06 07
PUT 1: ID=24 LEN=8 PRI=3 EXT=1 RTR=0
DATA = 00 01 02 03 04 05 06 07
GOT: BUFF=0 ID=24 LEN=8 OVF=0 FILT=0 RTR=0 EXT=1 INV=0
DATA = 00 01 02 03 04 05 06 07 |
|
|
![](templates/subSilver/images/spacer.gif) |
turhan
Joined: 24 Aug 2012 Posts: 9
|
|
Posted: Wed Aug 29, 2012 2:23 am |
|
|
I have same problem. Can you send your softwares to try it ? I gonna crazy. |
|
![](templates/subSilver/images/spacer.gif) |
Bill24
Joined: 30 Jun 2012 Posts: 45
|
|
Posted: Wed Aug 29, 2012 6:31 am |
|
|
PCM programmer wrote: | I made Loopback mode work with a 18F46K80 with compiler vs. 4.120
in hardware (It also works with vs. 4.135). The 18F46K80 is in the same
family as your PIC so it should work for you too. I'm using a 20 MHz
crystal. |
Did you change anything in the can-18F4580.c file. E.g
can_set_id(RXFILTER0, 0, CAN_USE_EXTENDED_ID); BRGCON registers etc.
Some posts suggest register assignments for newer PIC such as the 18F46K80 are different to those in the CCS driver files.
Can you confirm if this is correct or not. |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Aug 29, 2012 1:57 pm |
|
|
turhan wrote: |
I have same problem. Can you send your softwares to try it ?
|
I posted all required changes to the Ex_Can.c file. The file is in this
CCS compiler directory:
c:\program files\picc\examples\ex_can.c
I am not going to send it to you. It's against the forum rules.
You were asked in another thread, "what is your compiler version" ?
Bill24 wrote: | Did you change anything in the can-18F4580.c file. E.g
can_set_id(RXFILTER0, 0, CAN_USE_EXTENDED_ID); BRGCON registers etc.
|
I didn't change that line. All the changes I did are listed in detail in my post.
Bill24 wrote: |
Some posts suggest register assignments for newer PIC such as the 18F46K80 are different to those in the CCS driver files.
Can you confirm if this is correct or not.
|
In the current version of the compiler, most of the #byte references to
ECAN registers in can-18F4580.h use getenv() to get the register address
from the compiler's database. So in that respect, it should work with the
18F46K80. (Assuming the database is correct in your compiler version).
But there are a few other differences between the 18F46K80 and 18F4580
that may not be handled correctly in can-18F4580.h. I am still checking
on this. But I certainly made Loopback mode work, as shown in my
earlier post. |
|
![](templates/subSilver/images/spacer.gif) |
otaggart
Joined: 24 Aug 2012 Posts: 4 Location: Canada
|
|
Posted: Wed Aug 29, 2012 5:59 pm |
|
|
Hi,
I implemented the changes suggested by PCM Programmer to my version of EX_CAN.C (posted) and immediately had loopback mode working (using the can-18F4580.c driver). A couple more hours' work and I had three PICs communicating with each other via SN65HVD251 CAN transceivers from Texas Instruments. I appreciate your help! Some notes:
If you want to use standard ID instead of extended, set tx_ext=0 and change CAN_USE_EXTENDED_ID in can-18F4580.h to FALSE.
You can move the CAN transceiver pins from (B3RX, B2TX) to (C7RX,C6TX) by setting #FUSES CANC and changing
Code: | set_tris_b((*0xF93 & 0xFB ) | 0x08); |
in can-18F4580.c to
Code: | set_tris_c((*0xF94 & 0xBF ) | 0x80);
|
Wiring of the bus is as follows:
1) Tie all transceiver CANH pins together
2) Tie all transceiver CANL pins together
3) Connect CANH and CANL by a 120 ohm resistor at each end of the bus.
Hopefully that should help sort people out. |
|
![](templates/subSilver/images/spacer.gif) |
Bill24
Joined: 30 Jun 2012 Posts: 45
|
|
Posted: Thu Aug 30, 2012 9:39 am |
|
|
PCM programmer wrote: |
....
In the current version of the compiler, most of the #byte references to
ECAN registers in can-18F4580.h use getenv() to get the register address
from the compiler's database. So in that respect, it should work with the
18F46K80. (Assuming the database is correct in your compiler version).
But there are a few other differences between the 18F46K80 and 18F4580
that may not be handled correctly in can-18F4580.h. I am still checking
on this. But I certainly made Loopback mode work, as shown in my
earlier post. |
Comparing signals on an oscilloscope showed that the transceiver was not working properly.
So using Compiler 4.135 and a 18F46K80 is working and verified on a PIC CAN Analyser with only the modifications listed by PCM programmer above.
Thanks everyone. |
|
![](templates/subSilver/images/spacer.gif) |
turhan
Joined: 24 Aug 2012 Posts: 9
|
|
Posted: Mon Sep 10, 2012 3:39 am |
|
|
Bill24 did you solve this canbus problem ? Please put on website |
|
![](templates/subSilver/images/spacer.gif) |
turhan
Joined: 24 Aug 2012 Posts: 9
|
|
Posted: Mon Sep 17, 2012 10:01 am |
|
|
I solved this problem.
Last:
Code: |
#include <18F25K80.h>
#device adc=12
#fuses HSH,NOWDT,BROWNOUT,PUT,NOPLLEN,SOSC_DIG,NOIESO,NOFCMEN,CANB
#use delay(clock=20M)
#include <can-18F4580.c>
|
Compiler version should be 4.128
oscillator =20MHZ |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|