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 support@ccsinfo.com

Please help: 18F25K80 CAN module not working [Solved]

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



Joined: 24 Aug 2012
Posts: 4
Location: Canada

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

Please help: 18F25K80 CAN module not working [Solved]
PostPosted: Fri Aug 24, 2012 4:11 pm     Reply with quote

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");
         }
      }
   }
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19245

View user's profile Send private message

PostPosted: Sat Aug 25, 2012 4:19 am     Reply with quote

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
otaggart



Joined: 24 Aug 2012
Posts: 4
Location: Canada

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

PostPosted: Tue Aug 28, 2012 3:20 pm     Reply with quote

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?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Aug 28, 2012 5:02 pm     Reply with quote

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
turhan



Joined: 24 Aug 2012
Posts: 9

View user's profile Send private message MSN Messenger

PostPosted: Wed Aug 29, 2012 2:23 am     Reply with quote

I have same problem. Can you send your softwares to try it ? I gonna crazy.
Bill24



Joined: 30 Jun 2012
Posts: 45

View user's profile Send private message

PostPosted: Wed Aug 29, 2012 6:31 am     Reply with quote

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.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Aug 29, 2012 1:57 pm     Reply with quote

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.
otaggart



Joined: 24 Aug 2012
Posts: 4
Location: Canada

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

PostPosted: Wed Aug 29, 2012 5:59 pm     Reply with quote

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.
Bill24



Joined: 30 Jun 2012
Posts: 45

View user's profile Send private message

PostPosted: Thu Aug 30, 2012 9:39 am     Reply with quote

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.
turhan



Joined: 24 Aug 2012
Posts: 9

View user's profile Send private message MSN Messenger

PostPosted: Mon Sep 10, 2012 3:39 am     Reply with quote

Bill24 did you solve this canbus problem ? Please put on website
turhan



Joined: 24 Aug 2012
Posts: 9

View user's profile Send private message MSN Messenger

PostPosted: Mon Sep 17, 2012 10:01 am     Reply with quote

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
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