XC8 için MCP2515 Can kütüphanesi

Başlatan Mucit23, 17 Eylül 2015, 08:52:35

Mucit23

Selamlar,

CCS ile Can Bus ile uğraşıyorum. Normalde CAN Bus haberleşmesinde sıkıntı yaşamadım. Kullandığım kütüphane çalışıyor fakat CCS bana anlamsız sıkıntılar yaşatıyor. Dün artık doğru düzgün bir LCD yi bile çalıştıramayacak duruma geldim. Çalışan kodlara birşeyler oluyor. Daha önce başıma gelmişti. Şuanda Aynı anda iki ayrı program üzerinde çalışıyorum. Biri 18F252 için, Diğeri ise 18F46K22 için. Daha önceden CCS'nin farklı yerlerdeki kodları birbirine karıştırdığını gördüm.

Bugün yine  uğraşacam. CCS ile sorunları çözüp devam etmeyi istiyorum ama dün çaresizlikten XC8'e baktım fakat programın bel kemiği olan MCP2515 Can kütüphanesini bulamadım. XC8 için böyle bir kütüphane varmı? Yoksa sıfırdan yazmakmı gerekir?

kantirici

#1
ccs c den port etsen olmaz mı?

Şurada avr için yazılmış bir örnek var. http://www.kreatives-chaos.com/artikel/can-testboard

Ayrıca microchip in mcp2515 dev. board. sayfasında da örnek kod var. İşe yarabilir.

sadogan

#2
İki proje ile uğraşırken, Bir programı kapatıp diğerini açtığında ccs yeni açtığın projeyi
bir önceki proje dizininde zannedebiliyor ve build ettiğinde değişme olan dosyaları buraya
atabiliyor ve dahası ayını isimli c uzantılı bir dosya varsa burdakini kullanıyor istediğin kadar bu dosyada
programı değiştir build et  program istediğiniz gibi davranmıyor sonra saç baş yolmaca.
sözüm: bir proje açtığında proje dosyaları nede ise ccs üzerinden yerlerine save edince bu sorun olmuyor.
Benim pc de böyle oluyor ama her zaman olmuyor.
EE bedeva sirke baldan tatlı olunca bazen bozuk tat olması kaçınılmaz.

Mucit23

Özellikle include ettiğim dosyalarda karışıklık oluyordu. Şuanda CCS ile ilgili programımı çalıştırdım. Main'de sıkıntı yok gibi. Yaptığım değişiklikleri görebiliyorum.

Eklediğim kütüphaneleri ise doğrudan proje dizininin adresini vererek ekledim. Aşağıdaki gibi.
   #include "C:\Users\Ferhat\Desktop\CAN_Test\Software\Anakart\lcd_driver.c"
   #include "C:\Users\Ferhat\Desktop\CAN_Test\Software\Anakart\mcp2515.c"

Herhalde artık karışıklık olmaz.

Dün nedense 18F252'lerden bir tanesi aşırı akım çekiyordu. Yani tek başına yaklaşık 100ma. 20Mhz de çalışıyor üstelik.
İçindeki programı sildim boşken enerji verdim düzeldi. Şimdi tekrar aynı programı yükledim şuanda sıkıntı yok gibi. 3 adet can cihazı toplamda 90ma çekiyor.

M_B

@Mucit23 hocam;
mcp2515.c dosyasını CCS C nin icinde bulamadım.  Nerden temin edebilirim veya elinizde XC8 icin var mı ?


Teşekkürler
İmkanın sınırlarını görmek için imkansızı denemek lazım.                                                             Fatih Sultan Mehmet

Mucit23

XC8 kullanmıyorum ama CCS ile birçok defa MCP2515 kullandım. İsterseniz göndereyim.


M_B

Alıntı yapılan: Mucit23 - 02 Şubat 2016, 00:32:20
XC8 kullanmıyorum ama CCS ile birçok defa MCP2515 kullandım. İsterseniz göndereyim.
@Mucit23 Hocam CCS C olanı gönderirseniz bir inceleyim.
Teşekkürler.

Bir de hocam 8 veya 18 pinli  icerisinde Can modulu olan pic  biliyormusunuz.

İmkanın sınırlarını görmek için imkansızı denemek lazım.                                                             Fatih Sultan Mehmet

Mucit23

Buraya ekledim hocam
mcp251x.c
/////////////////////////////////////////////////////////////////////////
////                        can-mcp251x.c                            ////
//// CAN Library routines for Microchip's MCP2510 (and compatable)   ////
//// CAN IO expanders.                                               ////
////                                                                 ////
//// This library provides the following functions:                  ////
////  (for more information on these functions see the comment       ////
////   header above each function)                                   ////
////                                                                 ////
////    can_init - Configures the MCP2510 CAN peripheral             ////
////                                                                 ////
////    can_set_baud - Sets the baud rate control registers          ////
////                                                                 ////
////    can_set_mode - Sets the CAN module into a specific mode      ////
////                                                                 ////
////    can_set_id - Sets the standard and extended ID               ////
////                                                                 ////
////    can_get_id - Gets the standard and extended ID               ////
////                                                                 ////
////    can_putd - Sends a message/request with specified ID         ////
////                                                                 ////
////    can_getd - Returns specifid message/request and ID           ////
////                                                                 ////
////    can_kbhit - Returns true if there is data in one of the      ////
////                receive buffers                                  ////
////                                                                 ////
////    can_tbe - Returns true if the transmit buffer is ready to    ////
////              send more data                                     ////
////                                                                 ////
////    can_abort - Aborts all pending transmissions                 ////
////                                                                 ////
//// You will need a CAN transeiver to connect CANRX and CANTX       ////
//// pins to CANH and CANL bus lines.                                ////
////                                                                 ////
//// CCS provides an example, ex_can_ccs_b.c, which shows how to use ////
//// this library with CCS's CAN Prototype board.                    ////
////                                                                 ////
/////////////////////////////////////////////////////////////////////////
////                                                                 ////
//// Version History                                                 ////
////                                                                 ////
////  Jul 27 04 - can_init() uses CAN_USE_EXTENDED_ID instead of     ////
////              setting all RX filters to extended.                ////
////                                                                 ////
////  Apr 20 04 - Fixed a compling problem.                          ////
////                                                                 ////
////  Feb 24 04 - can_get_id() fixed for EID<18:20>.                 ////
////                                                                 ////
////  Jul 17 09 - Updated for PCD Compiler                           ////
////                                                                 ////
////  May 20 10 - Changed all variable types to unsigned for PCD and ////
////              if #device ANSI is used with PCH or PCM            ////
////                                                                 ////
////  Nov 10 10 - Modified SPI protocol to use #use SPI()            ////
////                                                                 ////
/////////////////////////////////////////////////////////////////////////
////        (C) Copyright 1996,2010 Custom Computer Services         ////
//// This source code may only be used by licensed users of the CCS  ////
//// C compiler.  This source code may only be distributed to other  ////
//// licensed users of the CCS C compiler.  No other use,            ////
//// reproduction or distribution is permitted without written       ////
//// permission.  Derivative programs created using this software    ////
//// in object code form are not restricted in any way.              ////
/////////////////////////////////////////////////////////////////////////

#include <mcp251x.h>

//IO pins connected to MCP2510
#ifndef EXT_CAN_CS
   #if defined(__PCD__)
      #define EXT_CAN_CS   PIN_B1
      #define EXT_CAN_SI   PIN_B2
      #define EXT_CAN_SO   PIN_B4
      #define EXT_CAN_SCK  PIN_E5
   #else
      #define EXT_CAN_CS   PIN_C2
      #define EXT_CAN_SI   PIN_C5
      #define EXT_CAN_SO   PIN_C4
      #define EXT_CAN_SCK  PIN_C3
   #endif
//   #define EXT_CAN_RESET   PIN_B5 //CCS library does not use this pin by default
//   #define EXT_CAN_TX0RTS  PIN_C4 //CCS library does not use this pin by default
//   #define EXT_CAN_TX1RTS  PIN_B4 //CCS library does not use this pin by default
//   #define EXT_CAN_TX2RTS  PIN_C2 //CCS library does not use this pin by default
#endif

#if CAN_DO_DEBUG
 #define can_debug printf
#else
 #define can_debug
#endif

////////////////////////////////////////////////////////////////////////
//
// can_init()
//
// Initializes MCP2510 CAN peripheral.  Sets the RX filter and masks so the
// CAN peripheral will receive all incoming IDs.  Configures both RX buffers
// to only accept valid valid messages (as opposed to all messages, or all
// extended message, or all standard messages).
//
// The constants (CAN_USE_RX_DOUBLE_BUFFER, CAN_ENABLE_DRIVE_HIGH,
// CAN_ENABLE_CAN_CAPTURE, etc) are given a default define in the can-mcp2510.h file.
// These default values can be overwritten in the main code, but most
// applications will be fine with these defaults.
//
//////////////////////////////////////////////////////////////////////////////
void can_init(void) {
   struct struct_RXB0CTRL b_rxb0ctrl;

   mcp2510_init();

   can_set_mode(CAN_OP_CONFIG);   //must be in config mode before params can be set
   can_set_baud();

   mcp2510_write(CANINTE,0x01); //Enable Rx Buffer empty interrupts

   memset(&b_rxb0ctrl,0,1);
  // b_rxb0ctrl=0;
   b_rxb0ctrl.rxm=CAN_RX_VALID;
   b_rxb0ctrl.bukt=CAN_USE_RX_DOUBLE_BUFFER;
   mcp2510_write(RXB0CTRL, (unsigned int8)b_rxb0ctrl);
   mcp2510_write(RXB1CTRL, (unsigned int8)b_rxb0ctrl);

   //if you want to configure the TXnRTS pins, do it here.  default is off

   can_set_id(RX0MASK, CAN_MASK_ACCEPT_ALL, CAN_USE_STANDART_ID);  //set mask 0 (RX BUFFER 0)
   can_set_id(RX0FILTER0, 0, CAN_USE_STANDART_ID);  //set filter 0 of mask 0 (RX BUFFER 0)
   can_set_id(RX0FILTER1, 0, CAN_USE_STANDART_ID);  //set filter 1 of mask 0 (RX BUFFER 0)

   can_set_id(RX1MASK, CAN_MASK_ACCEPT_ALL, CAN_USE_STANDART_ID);  //set mask 1 (RX BUFFER 1)
   can_set_id(RX1FILTER2, 0, CAN_USE_STANDART_ID);  //set filter 0 of mask 1 (RX BUFFER 1)
   can_set_id(RX1FILTER3, 0, CAN_USE_STANDART_ID);  //set filter 1 of mask 1 (RX BUFFER 1)
   can_set_id(RX1FILTER4, 0, CAN_USE_STANDART_ID);  //set filter 2 of mask 1 (RX BUFFER 1)
   can_set_id(RX1FILTER5, 0, CAN_USE_STANDART_ID);  //set filter 3 of mask 1 (RX BUFFER 1)

   can_set_mode(CAN_OP_NORMAL);
}

////////////////////////////////////////////////////////////////////////
//
// can_set_baud() Set Baudrate to 250Kbps
//
// Configures the baud rate control registers.  All the defines here
// are defaulted in the can-mcp2510.h file.  These defaults can, and
// probably should, be overwritten in the main code.
//
// Current defaults are set to work with CCS's CAN Prototype board and
// Microchip's MCP250xxx CAN Developers Kit if this PIC is running at 20Mhz.
//
////////////////////////////////////////////////////////////////////////
void can_set_baud(void) {
   mcp2510_write(CNF1, 0x01);
   mcp2510_write(CNF2, 0xB0);
   mcp2510_write(CNF3, 0x06);
}

void can_set_mode(CAN_OP_MODE mode) {
   struct struct_CANCTRL old_CANCTRL;

   memset(&old_CANCTRL,mcp2510_read(CANCTRL),1);
   //old_CANCTRL=mcp2510_read(CANCTRL);

   old_CANCTRL.reqop=mode;

   mcp2510_write(CANCTRL, (unsigned int8)old_CANCTRL);

   do {
      memset(&old_CANCTRL,mcp2510_read(CANCTRL),1);
      //old_CANCTRL=mcp2510_read(CANCTRL);
      
   } while (old_CANCTRL.reqop != mode);
}


////////////////////////////////////////////////////////////////////////
//
// can_set_id()
//
// Configures the xxxxEIDL, xxxxEIDH, xxxxSIDL and xxxxSIDH registers to
// configure the defined buffer to use the specified ID
//
//   Paramaters:
//     addr - pointer to first byte of ID register, starting with xxxxEIDL.
//            For example, a pointer to RXM1EIDL
//     id - ID to set buffer to
//     ext - Set to TRUE if this buffer uses an extended ID, FALSE if not
//
////////////////////////////////////////////////////////////////////////
void can_set_id(unsigned int8 addr, unsigned int32 id, int1 ext) {
   unsigned int8 converted_id[4];
   unsigned int8 *ptr;

   ptr=&converted_id[3];   //3=eidl, 2=eidh, 1=sidl, 0=sidh

   if (ext) {  //extended
      //eidl
      *ptr=make8(id,0); //0:7

      //eidh
      ptr--;
      *ptr=make8(id,1); //8:15

      //sidl
      ptr--;
      *ptr=make8(id,2) & 0x03;   //16:17
      *ptr|=(make8(id,2) << 3) & 0xE0; //18:20
      *ptr|=0x08;


      //sidh
      ptr--;
      *ptr=((make8(id,2) >> 5) & 0x07 ); //21:23
      *ptr|=((make8(id,3) << 3) & 0xF8);//24:28
   }
   else {   //standard
      //eidl
      *ptr=0;

      //eidh
      ptr--;
      *ptr=0;

      //sidl
      ptr--;
      *ptr=(make8(id,0) << 5) & 0xE0;

      //sidh
      ptr--;
      *ptr=(make8(id,0) >> 3) & 0x1F;
      *ptr|=(make8(id,1) << 5) & 0xE0;
   }

   //0=eidl, 1=eidh, 2=sidl, 3=sidh
   mcp2510_write(addr--, converted_id[3]);
   mcp2510_write(addr--, converted_id[2]);
   mcp2510_write(addr--, converted_id[1]);
   mcp2510_write(addr, converted_id[0]);
}

////////////////////////////////////////////////////////////////////////
//
// can_get_id()
//
// Returns the ID of the specified buffer.  (The opposite of can_set_id())
// This is used after receiving a message, to see which ID sent the message.
//
//   Paramaters:
//     addr - pointer to first byte of ID register, starting with xxxxEIDL.
//            For example, a pointer to RXM1EIDL
//     ext - Set to TRUE if this buffer uses an extended ID, FALSE if not
//
//   Returns:
//     The ID of the buffer
//
////////////////////////////////////////////////////////////////////////
unsigned int32 can_get_id(unsigned int8 addr, int1 ext) {
   unsigned int32 ret;
   unsigned int8 * ptr;
   unsigned int8 converted_id[4];

   ptr=&converted_id[3];   //3=eidl, 2=eidh, 1=sidl, 0=sidh

   converted_id[3]=mcp2510_read(addr--);
   converted_id[2]=mcp2510_read(addr--);
   converted_id[1]=mcp2510_read(addr--);
   converted_id[0]=mcp2510_read(addr);

   ret=0;


   if (ext) {
      ret=(unsigned int32)*ptr;  //eidl

      ptr--;     //eidh
      ret|=((unsigned int32)*ptr << 8);

      ptr--;     //sidl
      ret|=((unsigned int32)*ptr & 0x03) << 16;
      ret|=((unsigned int32)*ptr & 0xE0) << 13;

      ptr--;     //sidh
      ret|=((unsigned int32)*ptr << 21);
   }
   else {
      ptr-=2;    //sidl
      ret=((unsigned int32)*ptr & 0xE0) >> 5;

      ptr--;     //sidh
      ret|=((unsigned int32)*ptr << 3);
   }

   return(ret);
}

////////////////////////////////////////////////////////////////////////////////
//
// can_putd()
//
// Puts data on a transmit buffer, at which time the CAN peripheral will
// send when the CAN bus becomes available.
//
//    Paramaters:
//       id - ID to transmit data as
//       data - pointer to data to send
//       len - length of data to send
//       priority - priority of message.  The higher the number, the
//                  sooner the CAN peripheral will send the message.
//                  Numbers 0 through 3 are valid.
//       ext - TRUE to use an extended ID, FALSE if not
//       rtr - TRUE to set the RTR (request) bit in the ID, false if NOT
//
//    Returns:
//       If successful, it will return TRUE
//       If un-successful, will return FALSE
//
////////////////////////////////////////////////////////////////////////////////
int1 can_putd(unsigned int32 id, unsigned int8 * data, unsigned int8 len, unsigned int8 priority, int1 ext, int1 rtr) {
   unsigned int8 i;
   unsigned int8 port;

   unsigned int8 TXRXBaD0;
   unsigned int8 TXBaCTRL;
   unsigned int8 TXRXBaEIDL;
   unsigned int8 TXBaDLC;

   struct txbNctrl_struct b_TXBaCTRL;
   struct rxbNdlc_struct b_TXBaDLC;
   struct txbNctrl_struct b_TXB0CTRL, b_TXB1CTRL, b_TXB2CTRL;

   //b_TXB0CTRL=mcp2510_read(TXB0CTRL);
   memset(&b_TXB0CTRL,mcp2510_read(TXB0CTRL),1);
   //b_TXB1CTRL=mcp2510_read(TXB1CTRL);
   memset(&b_TXB1CTRL,mcp2510_read(TXB1CTRL),1);
   //b_TXB2CTRL=mcp2510_read(TXB2CTRL);
   memset(&b_TXB2CTRL,mcp2510_read(TXB2CTRL),1);

    // find emtpy transmitter
    //map access bank addresses to empty transmitter
   if (!b_TXB0CTRL.txreq) {
      TXRXBaD0=TXB0D0;
      TXBaCTRL=TXB0CTRL;
      TXRXBaEIDL=TXB0EIDL;
      TXBaDLC=TXB0DLC;
      port=0;
   }
   else if (!b_TXB1CTRL.txreq) {
      TXRXBaD0=TXB1D0;
      TXBaCTRL=TXB1CTRL;
      TXRXBaEIDL=TXB1EIDL;
      TXBaDLC=TXB1DLC;
      port=1;
   }
   else if (!b_TXB2CTRL.txreq) {
      TXRXBaD0=TXB2D0;
      TXBaCTRL=TXB2CTRL;
      TXRXBaEIDL=TXB2EIDL;
      TXBaDLC=TXB2DLC;
      port=2;
   }
   else {
      #if CAN_DO_DEBUG
         can_debug("\r\nCAN_PUTD() FAIL: NO OPEN TX BUFFERS\r\n");
      #endif
      return(0);
   }

   //set priority.
   //b_TXBaCTRL=mcp2510_read(TXBaCTRL);
   memset(&b_TXBaCTRL,mcp2510_read(TXBaCTRL),1);
   
   b_TXBaCTRL.txpri=priority;
   mcp2510_write(TXBaCTRL, (unsigned int8)b_TXBaCTRL);

   //set tx mask
   can_set_id(TXRXBaEIDL, id, ext);

   //set tx data count
   //b_TXBaDLC=len;
   memset(&b_TXBaDLC,len,1);
   b_TXBaDLC.rtr=rtr;
   mcp2510_write(TXBaDLC, (unsigned int8)b_TXBaDLC);

   //write to buffer
    for (i=TXRXBaD0; i<(TXRXBaD0 + len); i++) {
      mcp2510_write(i,*data);
      data++;
    }

   //enable transmission
   //b_TXBaCTRL=mcp2510_read(TXBaCTRL);
   memset(&b_TXBaCTRL,mcp2510_read(TXBaCTRL),1);
   b_TXBaCTRL.txreq=1;
   mcp2510_write(TXBaCTRL, (unsigned int8)b_TXBaCTRL);

   #if CAN_DO_DEBUG
            can_debug("\r\nCAN_PUTD(): BUFF=%U ID=%LX LEN=%U PRI=%U EXT=%U RTR=%U\r\n", port, id, len, priority, ext, rtr);
            if ((len)&&(!rtr)) {
               data-=len;
               can_debug("  DATA = ");
               for (i=0;i<len;i++) {
                  can_debug("%X ",*data);
                  data++;
               }
               can_debug("\r\n");
            }
   #endif

   return(1);
}

////////////////////////////////////////////////////////////////////////////////
//
// can_getd()
//
// Gets data from a receive buffer, if the data exists
//
//    Returns:
//      id - ID who sent message
//      data - pointer to array of data
//      len - length of received data
//      stat - structure holding some information (such as which buffer
//             recieved it, ext or standard, etc)
//
//    Returns:
//      Function call returns a TRUE if there was data in a RX buffer, FALSE
//      if there was none.
//
////////////////////////////////////////////////////////////////////////////////
int1 can_getd(unsigned int32 & id, unsigned int8 * data, unsigned int8 & len, struct rx_stat & stat)
{
   unsigned int8 i;

   struct struct_RXB0CTRL b_RXB0CTRL;
   struct struct_RXB1CTRL b_RXB1CTRL;
   struct struct_EFLG b_EFLG;

   unsigned int8 RXBaDLC;
   struct rxbNdlc_struct b_RXBaDLC;

   unsigned int8 TXRXBaSIDL;
   struct struct_TXRXBaSIDL b_TXRXBaSIDL;


   unsigned int8 RXBaD0;
   struct struct_CANINTF b_CANINTF;

   //b_CANINTF=mcp2510_read(CANINTF);
   memset(&b_CANINTF,mcp2510_read(CANINTF),1);

   //b_RXB0CTRL=mcp2510_read(RXB0CTRL);
   memset(&b_RXB0CTRL,mcp2510_read(RXB0CTRL),1);
   //b_RXB1CTRL=mcp2510_read(RXB1CTRL);
   memset(&b_RXB1CTRL,mcp2510_read(RXB1CTRL),1);
   //b_EFLG=mcp2510_read(EFLG);
   memset(&b_EFLG,mcp2510_read(EFLG),1);

    if (b_CANINTF.rx0if) {
        stat.buffer=0;

        stat.err_ovfl=b_EFLG.rx0ovr;
        b_EFLG.rx0ovr=0;
        mcp2510_write(EFLG, (unsigned int8)b_EFLG);

        if (b_RXB0CTRL.bukt) {
         stat.filthit=b_RXB0CTRL.filhit0;
        }

        RXBaDLC=RXB0DLC;
        TXRXBaSIDL=RXB0SIDL;
        RXBaD0=RXB0D0;
    }
    else if (b_CANINTF.rx1if)
    {
        stat.buffer=1;

        stat.err_ovfl=b_EFLG.rx1ovr;
        b_EFLG.rx1ovr=0;
        mcp2510_write(EFLG, (unsigned int8)b_EFLG);


        stat.filthit=b_RXB1CTRL.filhit0;
        RXBaDLC=RXB1DLC;
        TXRXBaSIDL=RXB1SIDL;
        RXBaD0=RXB1D0;
    }
    else {
      #if CAN_DO_DEBUG
         can_debug("\r\nFAIL ON CAN_GETD(): NO MESSAGE IN BUFFER\r\n");
      #endif
      return (0);
    }

   //get count
    //b_RXBaDLC=mcp2510_read(RXBaDLC);
    memset(&b_RXBaDLC,mcp2510_read(RXBaDLC),1);
    len = b_RXBaDLC.dlc;
    stat.rtr=b_RXBaDLC.rtr;

   //was it extended or standard?
    //b_TXRXBaSIDL=mcp2510_read(TXRXBaSIDL);
    memset(&b_TXRXBaSIDL,mcp2510_read(TXRXBaSIDL),1);
    stat.ext=b_TXRXBaSIDL.ext;
    id=can_get_id(TXRXBaSIDL + 2,stat.ext);

   //get data
    for ( i = RXBaD0; i < (RXBaD0 + len); i++ ) {
         *data=mcp2510_read(i);
        data++;
    }

    stat.inv=b_CANINTF.merrf;
    if (b_CANINTF.merrf) {
      b_CANINTF.merrf=0;
    }

    if (stat.buffer) {
      b_CANINTF.rx1if=0;
    }
    else {
      b_CANINTF.rx0if=0;
    }
    mcp2510_write(CANINTF, (unsigned int8)b_CANINTF);

    #if CAN_DO_DEBUG
       can_debug("\r\nCAN_GETD(): BUFF=%U ID=%LX LEN=%U OVF=%U ", stat.buffer, id, len, stat.err_ovfl);
       can_debug("FILT=%U RTR=%U EXT=%U INV=%U", stat.filthit, stat.rtr, stat.ext, stat.inv);
       if ((len)&&(!stat.rtr)) {
          data-=len;
          can_debug("\r\n    DATA = ");
          for (i=0;i<len;i++) {
            can_debug("%X ",*data);
            data++;
          }
       }
       can_debug("\r\n");
    #endif

    return(1);
}

///////////////////////////////////////////////////////////////////////////////
//
// can_kbhit()
//
// Returns TRUE if there is data in the receive buffers
//
////////////////////////////////////////////////////////////////////////////////
int1 can_kbhit(void) {
   struct struct_CANINTF b_CANINTF;

   //b_CANINTF=mcp2510_read(CANINTF);
   memset(&b_CANINTF,mcp2510_read(CANINTF),1);
   if (b_CANINTF.rx0if || b_CANINTF.rx1if)
      {return(1);}

   return(0);
}

////////////////////////////////////////////////////////////////////////
//
// can_tbe()
//
// Returns TRUE if the transmit buffers are empty and ready to transmit data
//
//////////////////////////////////////////////////////////////////////////////
int1 can_tbe(void) {
   struct txbNctrl_struct b_TXB0CTRL, b_TXB1CTRL, b_TXB2CTRL;

   //b_TXB0CTRL=mcp2510_read(TXB0CTRL);
   memset(&b_TXB0CTRL,mcp2510_read(TXB0CTRL),1);
   //b_TXB1CTRL=mcp2510_read(TXB1CTRL);
   memset(&b_TXB1CTRL,mcp2510_read(TXB1CTRL),1);
   //b_TXB2CTRL=mcp2510_read(TXB2CTRL);
   memset(&b_TXB2CTRL,mcp2510_read(TXB2CTRL),1);

   if (!b_TXB0CTRL.txreq || !b_TXB1CTRL.txreq || !b_TXB2CTRL.txreq)
      {return(1);}

   return(0);
}

////////////////////////////////////////////////////////////////////////////////
//
// can_abort()
//
// Aborts all pending tranmissions.
//
////////////////////////////////////////////////////////////////////////////////
void can_abort(void) {
   struct struct_CANCTRL b_CANCTRL;

   //b_CANCTRL=mcp2510_read(CANCTRL);
   memset(&b_CANCTRL,mcp2510_read(CANCTRL),1);
   b_CANCTRL.abat=1;
   mcp2510_write(CANCTRL, (unsigned int8)b_CANCTRL);

   delay_ms(5);
   b_CANCTRL.abat=0;
   mcp2510_write(CANCTRL, (unsigned int8)b_CANCTRL);
}

///////////////////
///
//
// SPI CODE
//
///
//////////////////

#ifndef USE_HARDWARE_SPI
   #use spi(MASTER,MODE=0,DI=EXT_CAN_SO,DO=EXT_CAN_SI,CLK=EXT_CAN_SCK,bits=8,stream=MCP2510)
#else
   #use spi(MASTER,MODE=0,DI=EXT_CAN_SO,DO=EXT_CAN_SI,CLK=EXT_CAN_SCK,bits=8,stream=MCP2510,FORCE_HW)
#endif

//data clocked in on rising edge
//data driven out on falling edge
unsigned int8 mcp2510_read(unsigned int8 address) {
   unsigned int8 data;

   output_low(EXT_CAN_CS);
   
   spi_xfer(MCP2510,0x03);
   spi_xfer(MCP2510,address);
   data = spi_xfer(MCP2510,0);
   
   output_high(EXT_CAN_CS);

   return(data);
}

unsigned int8 mcp2510_status(void) {
   unsigned int8 data;
   
   output_low(EXT_CAN_CS);
   
   spi_xfer(MCP2510,0xA0);
   data = spi_xfer(MCP2510,0);
   spi_xfer(MCP2510,0);
   
   output_high(EXT_CAN_CS);

   return(data);
}


void mcp2510_write(unsigned int8 address, unsigned int8 data) {
   output_low(EXT_CAN_CS);
   
   spi_xfer(MCP2510,0x02);
   spi_xfer(MCP2510,address);
   spi_xfer(MCP2510,data);
   
   output_high(EXT_CAN_CS);
}

void mcp2510_command(unsigned int8 command) {
   output_low(EXT_CAN_CS);
   
   spi_xfer(MCP2510,command);
   
   output_high(EXT_CAN_CS);
}

void mcp2510_init(void) {

   
   output_high(EXT_CAN_CS);

   #ifdef EXT_CAN_TX0RTS
    output_high(EXT_CAN_TX0RTS);
   #endif
   #ifdef EXT_CAN_TX1RTS
    output_high(EXT_CAN_TX1RTS);
   #endif
   #ifdef EXT_CAN_TX2RTS
    output_high(EXT_CAN_TX2RTS);
   #endif

  #ifdef EXT_CAN_TX0RTS
   output_high(EXT_CAN_RESET);
   output_low(EXT_CAN_RESET);
   output_high(EXT_CAN_RESET);
   delay_ms(5);
  #endif

   mcp2510_command(0xC0);   //reset
   delay_ms(5);
}


mcp251x.h
/////////////////////////////////////////////////////////////////////////
////                        can-mcp251x.h                            ////
////                                                                 ////
//// Prototypes, definitions, defines and macros used for and with   ////
//// the CCS CAN library for the MCP2510 (and compatable) CAN IO     ////
//// expanders.                                                      ////
////                                                                 ////
//// (see can-mcp251x.c)                                             ////
////                                                                 ////
/////////////////////////////////////////////////////////////////////////
////                                                                 //// 
//// Version History                                                 ////
////                                                                 ////
////  Apr 20 04 - Fixed a compling problem                           ////
////                                                                 ////
////  Jul 17 09 - Updated for PCD Compiler                           ////
////                                                                 ////
////  May 20 10 - Changed all variable types to unsigned for PCD and ////
////              if #device ANSI is used with PCH or PCM            ////
////                                                                 ////
/////////////////////////////////////////////////////////////////////////
////        (C) Copyright 1996,2010 Custom Computer Services         ////
//// This source code may only be used by licensed users of the CCS  ////
//// C compiler.  This source code may only be distributed to other  ////
//// licensed users of the CCS C compiler.  No other use,            ////
//// reproduction or distribution is permitted without written       ////
//// permission.  Derivative programs created using this software    ////
//// in object code form are not restricted in any way.              ////
/////////////////////////////////////////////////////////////////////////

#ifndef __CCS_CANMCP2510_LIB_DEFINES__
#define __CCS_CANMCP2510_LIB_DEFINES__

#ifndef CAN_DO_DEBUG
 #define CAN_DO_DEBUG FALSE
#endif

#IFNDEF CAN_USE_EXTENDED_ID
  #define CAN_USE_EXTENDED_ID         TRUE
#ENDIF

#IFNDEF CAN_USE_STANDART_ID
  #define CAN_USE_STANDART_ID         FALSE
#ENDIF

#IFNDEF CAN_BRG_SYNCH_JUMP_WIDTH
  #define CAN_BRG_SYNCH_JUMP_WIDTH  0  //synchronized jump width (def: 1 x Tq)
#ENDIF

#IFNDEF CAN_BRG_PRESCALAR
  #define CAN_BRG_PRESCALAR  4  //baud rate generator prescalar (def: 4) ( Tq = (2 x (PRE + 1))/Fosc )
#ENDIF

#ifndef CAN_BRG_SEG_2_PHASE_TS
 #define CAN_BRG_SEG_2_PHASE_TS   TRUE //phase segment 2 time select bit (def: freely programmable)
#endif

#ifndef CAN_BRG_SAM
 #define CAN_BRG_SAM 0 //sample of the can bus line (def: bus line is sampled 1 times prior to sample point)
#endif

#ifndef CAN_BRG_PHASE_SEGMENT_1
 #define CAN_BRG_PHASE_SEGMENT_1  5 //phase segment 1 (def: 6 x Tq)
#endif

#ifndef CAN_BRG_PROPAGATION_TIME
 #define CAN_BRG_PROPAGATION_TIME 2 //propagation time select (def: 3 x Tq)
#endif

#ifndef CAN_BRG_WAKE_FILTER
 #define CAN_BRG_WAKE_FILTER FALSE   //selects can bus line filter for wake up bit
#endif

#ifndef CAN_BRG_PHASE_SEGMENT_2
 #define CAN_BRG_PHASE_SEGMENT_2 5 //phase segment 2 time select (def: 6 x Tq)
#endif

#ifndef CAN_USE_RX_DOUBLE_BUFFER
 #define CAN_USE_RX_DOUBLE_BUFFER TRUE   //if buffer 0 overflows, do NOT use buffer 1 to put buffer 0 data
#endif

#ifndef CAN_ENABLE_DRIVE_HIGH
 #define CAN_ENABLE_DRIVE_HIGH 0
#endif

#ifndef CAN_ENABLE_CAN_CAPTURE
 #define CAN_ENABLE_CAN_CAPTURE 0
#endif

enum CAN_OP_MODE {CAN_OP_CONFIG=4, CAN_OP_LISTEN=3, CAN_OP_LOOPBACK=2, CAN_OP_SLEEP=1, CAN_OP_NORMAL=0};

//can control
struct struct_CANCTRL {
   int  clkpre:2; //0:1 //clkout pin prescalar
   int1 clken; //2   //clkout pin enable
   int1 void3; //3
   int1 abat;  //4   //abort all pending transmissions
   CAN_OP_MODE reqop:3; //5:7 //request operation mode
};
#define CANCTRL   0x0F  //or 1f, or 2f, or 3f ... or 7f

enum CAN_INT_CODE {CAN_INT_RX1=7, CAN_INT_RX0=6, CAN_INT_TX2=5, CAN_INT_TX1=4, CAN_INT_TX0=3, CAN_INT_WAKEUP=2, CAN_INT_ERROR=1, CAN_INT_NO=0};

//can status register READ-ONLY
struct struct_CANSTAT {
   int1 void0;   //0
   CAN_INT_CODE icode:3;   //1:3   //interrupt code
   int1 void4;   //4
   CAN_OP_MODE opmode:3;   //5:7   //operation mode status
};
#define CANSTAT 0x0E //or 1e, or 2e ... or 7e

//error flag register
struct struct_EFLG {
   int1 ewarn;      //0 //error warning
   int1 rxwar;      //1 //receiver warning
   int1 txwar;      //2 //transmitter warning
   int1 rxep;   //3 //receive error passive flag
   int1 txep;   //4 //transmit error passive flag
   int1 txbo;   //5   //bus off error flag
   int1 rx0ovr;   //6   //receive buffer 0 overflow
   int1 rx1ovr;   //7   //receive buffer 1 overflow
};
#define EFLG   0x2D

//interupt enable register
struct struct_CANINTE {
   int1 rx0ie; //0   //receive buffer 0 full interrupt enable
   int1 rx1ie; //1   //receive buffer 1 full interrupt enable
   int1 tx0ie; //2   //transmit buffer 0 embty interrupt enable
   int1 tx1ie; //3   //transmit buffer 1 embty interrupt enable
   int1 tx2ie; //4   //transmit buffer 2 embty interrupt enable
   int1 errie; //5   //error interrupt enable
   int1 wakie; //6   //wakeup interrupt  enable
   int1 merre; //7   //message error interrupt enable
};
#define CANINTE   0x2B

//interupt enable register
struct struct_CANINTF {
   int1 rx0if; //0   //receive buffer 0 full interrupt flag
   int1 rx1if; //1   //receive buffer 1 full interrupt flag
   int1 tx0if; //2   //transmit buffer 0 embty interrupt flag
   int1 tx1if; //3   //transmit buffer 1 embty interrupt flag
   int1 tx2if; //4   //transmit buffer 2 embty interrupt flag
   int1 errif; //5   //error interrupt flag
   int1 wakif; //6   //wakeup interrupt flag
   int1 merrf; //7   //message error interrupt flag
};
#define CANINTF   0x2C


//error counters
#define TEC    0x1C
#define REC    0x1D

//baud rate control register 1
struct struct_CNF1 {
   int brp:6;   //0:5   //baud rate prescalar
   int sjw:2;   //6:7   //synchronized jump width
};
#define CNF1   0x2A

//baud rate control register 2
struct struct_CNF2 {
   int prseg:3; //0:2 //propagation time select
   int phseg1:3; //3:5 //phase segment 1
   int1 sam; //6 //sample of the can bus line
   int1 btlmode; //7 //phase segment 2 bit time length
};
#define CNF2   0x29

//baud rate control register 3
struct struct_CNF3 {
   int phseg2:3;     //0:2 //phase segment 2 time select
   int void543:3;    //3:5
   int1 wakfil;      //6   //selects can bus line filter for wake-up
   int1 sof;         //7
};
#define CNF3   0x28
//can i/o control register

//transmit buffer n control register
struct txbNctrl_struct {
   int  txpri:2;   //0:1   //transmit priority bits
   int1 void2; //2
   int1 txreq;   //3   //transmit request status (clear to request message abort)
   int1 txerr;   //4   //transmission error detected
   int1 mloa;   //5   //message lost arbitration
   int1 abtf;   //6   //message was aborted / or transmitted succesfully
   int1 void7;
};
#define TXB0CTRL  0x30
#define TXB1CTRL  0x40
#define TXB2CTRL  0x50

//TXnRTS pin control and status register
struct struct_TXRTSCTRL {
   int1 b0rtsm; //0  //1=request message trans, 0=digital
   int1 b1rtsm; //1  //1=request message trans, 0=digital
   int1 b2rtsm; //2  //1=request message trans, 0=digital
   int1 b0rts; //3   //reads as tx2rts when in digital, 0 when in rts
   int1 b1rts; //4   //reads as tx2rts when in digital, 0 when in rts mode
   int1 b2rts; //5  //reads as tx2rts when in digital, 0 when in rts mode
   int  void67:2; //6:7
};
#define TXRTSCTRL 0x0D

//transmit buffer n standard identifier
#define TXB0SIDH 0x31
#define TXB0SIDL 0x32
#define TXB1SIDH 0x41
#define TXB1SIDL 0x42
#define TXB2SIDH 0x51
#define TXB2SIDL 0x52

//transmit buffer n extended identifier
#define TXB0EIDH 0x33
#define TXB0EIDL 0x34
#define TXB1EIDH 0x43
#define TXB1EIDL 0x44
#define TXB2EIDH 0x53
#define TXB2EIDL 0x54

//transmit buffer n data byte m
#define TXB0D0 0x36
#define TXB0D7 0x3D

#define TXB1D0 0x46
#define TXB1D7 0x4D

#define TXB2D0 0x56
#define TXB2D7 0x5D

//transmit buffer n data length
struct txbNdlc_struct {
   int dlc:4;   //0:3
   int void54:2; //4:5
   int1 rtr; //6 //transmission frame remote tranmission
   int1 void7; //7
};
#define TXB0DLC 0x35
#define TXB1DLC 0x45
#define TXB2DLC 0x55

//#byte TXBaDLC=0xF65  //txbXdlc when in the access bank


//transmit error count register
#byte TXERRCNT=0xF76


enum CAN_RX_MODE {CAN_RX_ALL=3, CAN_RX_EXT=2, CAN_RX_STD=1, CAN_RX_VALID=0};

//receive buffer 0 control register
struct struct_RXB0CTRL {
   int1 filhit0;   //0 //filter hit
   int1 bukt1;   //1 //read only copy of bukt bit (used internally by mcp2510)
   int1 bukt;   //2 //rollover enable
   int1 rxrtr;   //3 //receive remote transfer request
   int1 void4;   //4
   CAN_RX_MODE rxm:2;   //5:6 //receiver buffer mode
   int1 void7;   //7 //receive full status
};
#define RXB0CTRL  0x60

//receive buffer 1 control register
struct struct_RXB1CTRL {
   int filhit0:3;   //0:2
   int1 rxrtr;   //3 //receive remote transfer request
   int1 void4;   //4
   CAN_RX_MODE rxm:2;   //5:6 //receive buffer mode
   int1 void7;   //7
};
#define RXB1CTRL 0x70

//RXnBF pint control and status register
struct struct_BFPCTRL {
   int1  b0bfm; //0   //1=pin is interrupt when message loaded into rxb0, 0=digital
   int1  b1bfm; //1   //1=pin is interrupt when message loaded into rxb1, 0=digital
   int1  b0bfe; //2   //rx0bf pin function enable
   int1  b1bfe; //3   //rx1bf pin function enable
   int1  b0bfs; //4   //rx0bf pin state
   int1  b1bfs; //5   //rx1bf pin state
};

//receive buffer n standard identifier
#define   RXB0SIDH  0x61
#define   RXB0SIDL  0x62

#define   RXB1SIDH  0x71
#define   RXB1SIDL  0x72

//receive buffer n extended identifier
#define   RXB0EID8  0x63
#define   RXB0EID0  0x64

#define   RXB1EID8  0x73
#define   RXB1EID0  0x74

struct struct_TXRXBaSIDL {
   int void012:3; //0:2
   int1 ext;      //3 //extendid id
   int1 srr;      //4 //substitute remove request bit
   int void567:3; //5:7
};

//receive buffer n data length code register
struct rxbNdlc_struct {
   int dlc:4;   //0:3 //data length code
   int1 rb0;   //4   //reserved
   int1 rb1;   //5   //reserved
   int1 rtr;   //6   //receiver remote transmission request bit
   int1 void7;   //7
};
#define   RXB0DLC   0x65
#define   RXB1DLC   0x75

//receive buffer n data field byte m register
#define RXB0D0    0x66
#define RXB0D7    0x6D

#define RXB1D0    0x76
#define RXB1D7    0x7D

//receive acceptance filter n standard indifier
#define RXF0SIDH  0x00
#define RXF0SIDL  0x01
#define RXF1SIDH  0x04
#define RXF1SIDL  0x05
#define RXF2SIDH  0x08
#define RXF2SIDL  0x09
#define RXF3SIDH  0x10
#define RXF3SIDL  0x11
#define RXF4SIDH  0x14
#define RXF4SIDL  0x15
#define RXF5SIDH  0x18
#define RXF5SIDL  0x19

//receive acceptance filter n extended indifier
#define RXF0EIDH  0x02
#define RXF0EIDL  0x03
#define RXF1EIDH  0x06
#define RXF1EIDL  0x07
#define RXF2EIDH  0x0a
#define RXF2EIDL  0x0b
#define RXF3EIDH  0x12
#define RXF3EIDL  0x13
#define RXF4EIDH  0x16
#define RXF4EIDL  0x17
#define RXF5EIDH  0x1a
#define RXF5EIDL  0x1b

//receive acceptance mask n standard identifer mask
#define RXM0SIDH  0x20
#define RXM0SIDL  0x21
#define RXM1SIDH  0x24
#define RXM1SIDL  0x25

//receive acceptance mask n extended identifer mask
#define RXM0EIDH  0x22
#define RXM0EIDL  0x23
#define RXM1EIDH  0x26
#define RXM1EIDL  0x27

#define RX0MASK       RXM0EIDL   //rxm0eidl
#define RX1MASK       RXM1EIDL   //rxm1eidl
#define RX0FILTER0    RXF0EIDL   //rxf0eidl
#define RX0FILTER1    RXF1EIDL   //rxf1eidl
#define RX1FILTER2    RXF2EIDL   //rxf2eidl
#define RX1FILTER3    RXF3EIDL   //rxf3eidl
#define RX1FILTER4    RXF4EIDL   //rxf4eidl
#define RX1FILTER5    RXF5EIDL   //rxf5eidl
#define RXB0ID        RXB0EIDL   //rxb0eidl
#define RXB1ID        RXB1EIDL   //rxb1eidl
#define TXB0ID        TXB0EIDL   //txb0eidl
#define TXB1ID        TXB1EIDL   //txb1eidl
#define TXB2ID        TXB2EIDL   //tsb2eidl

//value to put in mask field to accept all incoming id's
#define CAN_MASK_ACCEPT_ALL   0


//PROTOTYPES and MACROS

struct rx_stat {
   int1 err_ovfl;
   int filthit:3;
   int1 buffer;
   int1 rtr;
   int1 ext;
   int1 inv;
};

void  can_init(void);
void  can_set_baud(void);
void  can_set_mode(CAN_OP_MODE mode);
void can_set_id(unsigned int8 addr, unsigned int32 id, int1 ext);
unsigned int32 can_get_id(unsigned int8 addr, int1 ext);
int1  can_putd(unsigned int32 id, unsigned int8 * data, unsigned int8 len, unsigned int8 priority, int1 ext, int1 rtr);
int1  can_getd(unsigned int32 & id, unsigned int8 * data, unsigned int8 & len, struct rx_stat & stat);

void mcp2510_init();
void mcp2510_command(unsigned int8 command);
void mcp2510_write(unsigned int8 address, unsigned int8 data);
unsigned int8 mcp2510_status(void);
unsigned int8 mcp2510_read(unsigned int8 address);

#endif

Yalnız baudrate ayarlarına dikkat edin. Ben doğrudan aşağıdaki linkteki yazılımla hesaplayıp yazıyordum baudrete registerlerine (CNF1, CNF2, CNF3)
http://www.intrepidcs.com/support/mbtime.htm

void can_set_baud(void) {
   mcp2510_write(CNF1, 0x01);
   mcp2510_write(CNF2, 0xB0);
   mcp2510_write(CNF3, 0x06);
}


Yanlışım yoksa 250Kbps ye ayarlı