Forum: Mikrocontroller und Digitale Elektronik PIC 18F4480 CAN-Modul


von Martin Fichtlscherer (Gast)


Lesenswert?

Hi.

Ich verwende das CAN-Module des PICs um Pakete über CAN zu empfangen und 
dann über RS232 wieder zu senden, was soweit auch funktioniert. Nun 
versuche ich jedoch, nur bestimmte Nachrichten über die Receive-Filter 
zuzulassen, erhalte jedoch trotzdem immer alle Pakete. Zur 
Initialisierung des PICs verwende ich den Microchip Application Maestro, 
die Einträge bei den Filtern haben aber keine Auswirkungen.

Hat damit jemand Erfahrungen??
Schon mal besten Dank im Vorraus.

von Rahul, der Trollige (Gast)


Lesenswert?

Musst du nicht auch noch in einem Mask-Register etwas einstellen? (ich 
kenne den PIC nicht, beim MCP2515 muß man dem aber so tun...)

von Martin Fichtlscherer (Gast)


Lesenswert?

Hmm. Sollte unabhängig vom PIC sein. Was muss ich denn da eintragen?? 
Habs mal mit FF und 1 probiert, noch keine Änderung.

von Anton Keller (Gast)


Lesenswert?

hallo martin,

ich glaube da hat rahul schon recht.
soweit ich mich erinnern kann muss man einen filter mit einer maske
verknuepfen (und-verknuepfung).
d.h. wenn du nach einer bestimmten id filtern willst, solltest du
die zugehoerige maske auf 0xff setzen.

gruss
a.

von Martin Fichtlscherer (Gast)


Lesenswert?

Diese Verknüpfungen etc. erledigt eigentlich der Application Maestro für 
mich. Hab mir den generierten Code mal ein bisschen angeschaut, der 
verknuepft die nach einigem hin-und-her-geschiebe miteinander. Das Ganze 
wird mir immer mysterioeser. Für was gibt es denn die Einstellungen im 
Maestro, wenn sie nichts bewirken??

von Rahul, der Trollige (Gast)


Lesenswert?

Ich hab das Datenblatt jetzt mal nur überflogen: Auf Seite 303 
(AcrobatReader Seite 305) fangen die Mask-Register-Beschreibungen 
scheinbar an.
Besonders gut ist das Maskieren im Datenblatt IMO aber nicht 
beschrieben.
Da würde ich mir an deiner Stelle noch das des MCP2515 angucken; 
zumindest den Teil mit der Maskierung.

von Rahul, der Trollige (Gast)


Lesenswert?

>Für was gibt es denn die Einstellungen im Maestro, wenn sie nichts >bewirken??

Code-Wizards.... bäh!
Lerne den Controller dadurch kennen, dass du dich direkt mit dem Ding 
beschäftigst. (meine Meinung zu dem Thema)

von Martin Fichtlscherer (Gast)


Lesenswert?

Ich weiss, mach ich normalerweise auch so, nur mit dem CAN war ich dann 
doch überfordert, bzw. es hat mir einfach zulang gedauert.

Ist dass bei dem 4480 genauso, der braucht den MCP2515 nicht, ist bei 
dem mit integriert??

von Rahul, der Trollige (Gast)


Lesenswert?

>Ist dass bei dem 4480 genauso, der braucht den MCP2515 nicht, ist bei
>dem mit integriert??

Es ist mir klar, dass der 4480 den 2515 nicht braucht. Es ging nur um 
dessen Datenblatt, weil dort das Maskieren umfangreicher beschrieben 
ist.

von Martin Fichtlscherer (Gast)


Lesenswert?

Schon klar. Hab mich da inzwischen auch mal ein bisschen durchgearbeitet 
und hab den Fehler gefunden. Nach der Aktivierung der Masken zu den 
Filtern war noch der falsche Mode eingestellt. Nachdem ich auf Enhanced 
Fifo umgestellt hab, funktionierts.

Vielen Dank nochmal für die Hilfe. Hätt ich alleine ewig gebraucht.

von Ivana (Gast)


Lesenswert?

@Martin Fichtlscherer
Hallo Martin,
habe aufmerksam gelesen, weil ich mich für einen preiswerten Adapter CAN 
seriell interessiere.
Schneidet dein Controller-Programm alles mit was auf den CAN-Bus läuft?
Wenn ja würdest du den Code und das Hex-file hier reinstellen?
Vielen Dank !

von Martin Fichtlscherer (Gast)


Lesenswert?

Kommt ganz auf die Filtereinstellungen an. Habs schnell so geändert, 
dass alles übertragen wird. Sind 4 Dateien, stell die mal alle rein.



CAN.h******************************************************************* 
*******************



#ifndef __CAN_H
#define __CAN_H

#include "candef.h"

#define CANInit() CANOpen(CAN_CONFIG_1, CAN_CONFIG_2, CAN_CONFIG_3)

#define MASK_ENABLE_ALL 0x00000000      //The mask to enable all 
incoming messages

#define ACCEPTANCE_MASK_0_1 RXMASK0      //Acceptance mask for filters 0 
and 1
#define ACCEPTANCE_MASK_2_5 RXMASK1      //Acceptance mask for filters 
2, 3, 4 and 5

//                          0x1FFFFFFF      Maximum extended identifier
//                          0x000007FF      Maximum standard identifier
#define ACCEPTANCE_FILTER_0 RXFILT0      //Acceptance filter 0
#define ACCEPTANCE_FILTER_1 RXFILT1      //Acceptance filter 1

//                          0x1FFFFFFF      Maximum extended identifier
//                          0x000007FF      Maximum standard identifier
#define ACCEPTANCE_FILTER_2 RXFILT2      //Acceptance filter 2
#define ACCEPTANCE_FILTER_3 RXFILT3      //Acceptance filter 3
#define ACCEPTANCE_FILTER_4 RXFILT4      //Acceptance filter 4
#define ACCEPTANCE_FILTER_5 RXFILT5      //Acceptance filter 5

//If a desired filter is to accept extended identifiers
//then comment the appropriate line out
#ifdef ST_FILTER_0
#define ACCEPT_STANDARD_FILTER_0
#endif
#ifdef ST_FILTER_1
#define ACCEPT_STANDARD_FILTER_1
#endif
#ifdef ST_FILTER_2
#define ACCEPT_STANDARD_FILTER_2
#endif
#ifdef ST_FILTER_3
#define ACCEPT_STANDARD_FILTER_3
#endif
#ifdef ST_FILTER_4
#define ACCEPT_STANDARD_FILTER_4
#endif
#ifdef ST_FILTER_5
#define ACCEPT_STANDARD_FILTER_5
#endif




//                            0x1FFFFFFF      Maximum extended 
identifier
//                            0x000007FF      Maximum standard 
identifier
#define MY_ADDRESS_IDENTIFIER MY_IDENT

//To use extended identifier for my address, comment the following line 
out
#ifdef STD_IDENT
#define MY_ADDRESS_IS_STANDARD
#endif


//If using normal mode, comment the following line out
#ifdef LPBACK
#define USE_LOOPBACK_MODE
#endif


//Size of RX buffer (14 bytes per buffer entry) has to be greater than 
or equal to 2
#define RXBUF RX_BUFFER

//Size of TX buffer (14 bytes per buffer entry) has to be greater than 
or equal to 2
#define TXBUF TX_BUFFER

#if TXBUF < 2 || RXBUF < 2
#error "The RXbuffer and TXbuffer has to greater than or equal to 2"
#endif

//CAN message structure (one message is 15 bytes wide)
struct CANMessage {
  unsigned long Address;
  unsigned char Data[8];
  unsigned char NoOfBytes;
  unsigned char Priority;
  unsigned Ext:1;
  unsigned Remote:1;
};

#define CAN_LISTEN_MODE 0x7F
#define CAN_LOOPBACK_MODE 0x5F
#define CAN_DISABLE_MODE 0x3F
#define CAN_NORMAL_MODE 0x1F



/*********************************************************************
 * Function:        char CANOpen(unsigned char CONFIG1, unsigned char 
CONFIG2, unsigned char CONFIG3)
 *
 * PreCondition:    None
 *
 * Input:           Values to be written into BRGCON1 -> BRGCON3
 *
 * Output:          0 -> Initialasation succeeded
 *
 * Side Effects:    None
 *
 * Overview:        Sets up the appropriate register for the device to 
act
 *                  as a CAN node
 *
 * Note:            Input values 0x03, 0xAA, 0x05 at Fosc = 16MHz works 
with
 *                  the default firmware at nodeB on the CAN I/O 
expander board.
 ********************************************************************/
char CANOpen(unsigned char, unsigned char, unsigned char);


/*********************************************************************
 * Function:        void CANISR(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    Will modify the RX/TX Buffer registers´ Write/Read 
pointers
 *
 * Overview:        Checks if a CAN reception/transmission was complete
 *                  and if so write/read to the CAN RX/TX FIFO buffers
 *
 * Note:            This function is supposed to be called from the ISR
 ********************************************************************/
void CANISR(void);


/*********************************************************************
 * Function:        char CANPut(struct CANMessage Message)
 *
 * PreCondition:    None
 *
 * Input:           A CAN message
 *
 * Output:          1 -> Failed to put a CAN on the buffer, buffer is 
full
 *                  0 -> The CAN message is put on the buffer and will 
be
 *                       transmitted eventually
 *
 * Side Effects:    Will modify the TX Buffer register´s Write pointer
 *
 * Overview:        Initially checks if at least one buffer slot is 
available
 *                  and if so push the requested message in the buffer
 *
 * Note:            None
 ********************************************************************/
char CANPut(struct CANMessage);


/*********************************************************************
 * Function:        char CANRXMessageIsPending(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          1 -> At least one received message is pending in the 
RX buffer
 *                  0 -> No received messages are pending
 *
 * Side Effects:    None
 *
 * Overview:        Checks if the RX Write pointer is equal to RX Read 
pointer and
 *                  if so returns 0, else returns 1
 *
 * Note:            Since no care is taken if the buffer overflow
 *                  this function has to be polled frequently to
 *                  prevent a software receive buffer overflow
 ********************************************************************/
char CANRXMessageIsPending(void);


/*********************************************************************
 * Function:        struct CANMessage CANGet(void)
 *
 * PreCondition:    An unread message has to be in the buffer
 *                  use RXCANMessageIsPending(void) prior to
 *                  calling this function in order to determine
 *                  if an unread message is pending.
 *
 * Input:           None
 *
 * Output:          The received message
 *
 * Side Effects:    Will modify the RX Buffer register´s Read pointer
 *
 * Overview:        Pops the the first message of the RX buffer
 *
 * Note:            None
 ********************************************************************/
struct CANMessage CANGet(void);


/*********************************************************************
 * Function:        void CANSetMode(unsigned char Mode)
 *
 * PreCondition:    None
 *
 * Input:           Desired CAN Mode
 *                  (CAN_LISTEN_MODE, CAN_LOOPBACK_MODE
 *                   CAN_DISABLE_MODE, CAN_NORMAL_MODE)
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Requests to set the desired mode and waits until
 *          the mode has been set.
 *
 * Note:            If USE_LOOPBACK_MODE is defined the requested
 *                  mode will be loopback mode if the input is
 *                  Normal mode
 ********************************************************************/
void CANSetMode(unsigned char);

#endif


can.c******************************************************************* 
*******************************

#include "can.h"

#if defined(HI_TECH_C)
    #if defined(MPC)
        #define HITECH_C18
    #else
        #error "Unknown part is selected."
    #endif
#else
    #define MCHP_C18
#endif

#if defined(MCHP_C18) && defined(HITECH_C18)
#error "Invalid Compiler selection."
#endif

#if !defined(MCHP_C18) && !defined(HITECH_C18)
#error "Compiler not supported."
#endif


#if defined(HITECH_C18)
#include <pic18.h>

#elif defined(MCHP_C18)
#include <p18cxxx.h>

#define TRISB2 TRISBbits.TRISB2
#define TRISB3 TRISBbits.TRISB3
#define TXB0REQ TXB0CONbits.TXREQ
#define RXB0FUL RXB0CONbits.RXFUL
#define RXB0RTRRO RXB0CONbits.RXRTRRO

#define RXB0IF PIR3bits.RXB0IF
#define RXB1IF PIR3bits.RXB1IF
#define TXB0IF PIR3bits.TXB0IF
#define TXB1IF PIR3bits.TXB1IF
#define TXB2IF PIR3bits.TXB2IF
#define ERRIF PIR3bits.ERRIF
#define WAKIF PIR3bits.WAKIF

#define RXB0IE PIE3bits.RXB0IE
#define RXB1IE PIE3bits.RXB1IE
#define TXB0IE PIE3bits.TXB0IE
#define TXB1IE PIE3bits.TXB1IE
#define TXB2IE PIE3bits.TXB2IE
#define ERRIE PIE3bits.ERRIE
#define WAKIE PIE3bits.WAKIE


#endif



#define CONFIG_MODE 0x9F
#define LISTEN_MODE 0x7F
#define LOOPBACK_MODE 0x5F
#define DISABLE_MODE 0x3F
#define NORMAL_MODE 0x1F
#define MODE_MASK 0xE0

#define NoInterrupt 0x00
#define ErrorInterrupt 0x02
#define TXB2Interrupt 0x04
#define TXB1Interrupt 0x06
#define TXB0Interrupt 0x08
#define RXB1Interrupt 0x0A
#define RXB0Interrupt 0x0C
#define WakeUpInterrupt 0x0E


#ifdef CAN_ERROR_HANDLER_ENABLE
extern void CANErrorHandler(void);
#define CAN_INT_BITS 0x3F  //CAN interrupts which should be enabled, 
simply what PIE3 is to be loaded with (Note all TXB IE will be set 
regardless of this value)
#else
#define CAN_INT_BITS 0x1F  //CAN interrupts which should be enabled, 
simply what PIE3 is to be loaded with (Note all TXB IE will be set 
regardless of this value)
#endif

union RXBuffer {        //Receive buffer structure
  unsigned char Data[14];    //It has to be a bit messy/strict for
  struct {          //it to go trough the PICC18 compiler
    union {
      unsigned char Byte;
      struct {
        unsigned FILHIT0:1;
        unsigned JTOFF:1;
        unsigned RXB0DBEN:1;
        unsigned RXRTRRO:1;
        unsigned :1;
        unsigned RXM0:1;
        unsigned RXM1:1;
        unsigned RXFUL:1;
      } Bits;
    } RXBCON;
    union {
      unsigned char Byte;
    } RXBSIDH;
    union {
      unsigned char Byte;
      struct {
        unsigned EID16:1;
        unsigned EID17:1;
        unsigned :1;
        unsigned EXID:1;
        unsigned SRR:1;
        unsigned SID0:1;
        unsigned SID1:1;
        unsigned SID2:1;
      } Bits;
    } RXBSIDL;
    union {
      unsigned char Byte;
    } RXBEIDH;
    union {
      unsigned char Byte;
    } RXBEIDL;
    union {
      unsigned char Byte;
      struct {
        unsigned DLC0:1;
        unsigned DLC1:1;
        unsigned DLC2:1;
        unsigned DLC3:1;
        unsigned RB0:1;
        unsigned RB1:1;
        unsigned RXRTR:1;
        unsigned :1;
      } Bits;
    } RXBDLC;
    union {
      unsigned char Array[8];
      struct {
        unsigned char RXBD0;
        unsigned char RXBD1;
        unsigned char RXBD2;
        unsigned char RXBD3;
        unsigned char RXBD4;
        unsigned char RXBD5;
        unsigned char RXBD6;
        unsigned char RXBD7;
      } Bytes;
    } RXBD;
  } Specific;
};

union TXBuffer {          //Transmit buffer structure
  unsigned char Data[14];
  struct {
    union {
      unsigned char Byte;
      struct {
        unsigned TXPRI0:1;
        unsigned TXPRI1:1;
        unsigned :1;
        unsigned TXREQ:1;
        unsigned TXERR:1;
        unsigned TXLARB:1;
        unsigned TXABT:1;
      } Bits;
    } TXBCON;
    union {
      unsigned char Byte;
    } TXBSIDH;
    union {
      unsigned char Byte;
      struct {
        unsigned EID16:1;
        unsigned EID17:1;
        unsigned :1;
        unsigned EXIDE:1;
        unsigned :1;
        unsigned SID0:1;
        unsigned SID1:1;
        unsigned SID2:1;
      } Bits;
    } TXBSIDL;
    union {
      unsigned char Byte;
    } TXBEIDH;
    union {
      unsigned char Byte;
    } TXBEIDL;
    union {
      unsigned char Byte;
      struct {
        unsigned DLC0:1;
        unsigned DLC1:1;
        unsigned DLC2:1;
        unsigned DLC3:1;
        unsigned :1;
        unsigned :1;
        unsigned TXRTR:1;
        unsigned :1;
      } Bits;
    } TXBDLC;
    union {
      unsigned char Array[8];
      struct {
        unsigned char TXBD0;
        unsigned char TXBD1;
        unsigned char TXBD2;
        unsigned char TXBD3;
        unsigned char TXBD4;
        unsigned char TXBD5;
        unsigned char TXBD6;
        unsigned char TXBD7;
      } Bytes;
    } TXBD;
  } Specific;
};
union RXBuffer RXMessage[RXBUF];    //Received messages FIFO buffer
union TXBuffer TXMessage[TXBUF];    //Pending messages to transmit FIFO 
buffer
char RXRPtr = 0;            //Read pointer for RXMessage buffer
char RXWPtr = 0;            //Write pointer for RXMessage buffer
char TXRPtr = 0;            //Read pointer for TXMessage buffer
char TXWPtr = 0;            //Write pointer for TXMessage buffer


/*********************************************************************
 * Function:        void CANGetMessage(void)
 *
 * PreCondition:    <WIN2:WIN0> in the CANCON register has to set
 *                  to reflect the desired RXB registers
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    Will modify the RX FIFO Write pointer (RXWPtr)
 *
 * Overview:        Gets the registers for a RXB and puts them in the
 *                  CAN Receive buffer
 *
 * Note:            Care is not taken if buffer is full
 ********************************************************************/
void CANGetMessage(void);

/*********************************************************************
 * Function:        char CANPutMessage(void)
 *
 * PreCondition:    <WIN2:WIN0> in the CANCON register has to set
 *                  to reflect the desired TXB registers
 *
 * Input:           None
 *
 * Output:          0 -> A new message has been put in the transmit 
queue
 *                  1 -> There was no messages in the TX buffer to send
 *
 * Side Effects:    Will modify the TX buffer´s Read pointer (TXRPtr)
 *
 * Overview:        Checks if there is any messages to transmit and if 
so
 *                  place it in the registers reflected by <WIN2:WIN0>
 *
 * Note:            None
 ********************************************************************/
 char CANPutMessage(void);

/*********************************************************************
 * Function:        char CANOpen(void)
 *
 * PreCondition:    None
 *
 * Input:           Values to be written into BRGCON1 -> BRGCON3
 *
 * Output:          0 -> Initialasation succeeded
 *
 * Side Effects:    None
 *
 * Overview:        Sets up the appropriate register for the device to 
act
 *                  as a CAN node
 *
 * Note:            Input values 0x03, 0xAA, 0x05 at Fosc = 16MHz works 
with
 *                  the default firmware at nodeB on the CAN I/O 
expander board.
 ********************************************************************/
char CANOpen(unsigned char CONFIG1, unsigned char CONFIG2, unsigned char 
CONFIG3)
{
  TRISB2 = 0;
  TRISB3 = 1;
  PIE3 = 0;                    //Disable all CAN interrupts
  PIR3 = 0;                    //and clear all CAN interrupt flags
  CANCON = (CONFIG_MODE & MODE_MASK) | (CANCON & 0x3F);  //Set 
configuration mode
  while((CANSTAT & MODE_MASK) != (CONFIG_MODE & MODE_MASK));  //Wait 
until config mode is set

  BRGCON1 = CONFIG1;
  BRGCON2 = CONFIG2;
  BRGCON3 = CONFIG3;

  RXB0CON = 0x04;          //Receive all valid messages receive buffer 
overflow
  RXB1CON = 0x00;          //writes to RXB1

  //Set the acceptance filters for all the filters
#ifdef ACCEPT_STANDARD_FILTER_0
  RXF0SIDL = (unsigned char)(ACCEPTANCE_FILTER_0 << 5);
  RXF0SIDH = (unsigned char)(ACCEPTANCE_FILTER_0 >> 3);
#else
  RXF0EIDL = (unsigned char)(ACCEPTANCE_FILTER_0 & 0xFF);
  RXF0EIDH = (unsigned char)((ACCEPTANCE_FILTER_0 >> 8) & 0xFF);
  RXF0SIDL = (unsigned char)((ACCEPTANCE_FILTER_0 >> 16) & 0x03) | 
(unsigned char)((ACCEPTANCE_FILTER_0 >> 13) & 0xE0) | 0x08;
  RXF0SIDH = (unsigned char)((ACCEPTANCE_FILTER_0 >> 21) & 0xFF);
#endif
#ifdef ACCEPT_STANDARD_FILTER_1
  RXF1SIDL = (unsigned char)(ACCEPTANCE_FILTER_1 << 5);
  RXF1SIDH = (unsigned char)(ACCEPTANCE_FILTER_1 >> 3);
#else
  RXF1EIDL = (unsigned char)(ACCEPTANCE_FILTER_1 & 0xFF);
  RXF1EIDH = (unsigned char)((ACCEPTANCE_FILTER_1 >> 8) & 0xFF);
  RXF1SIDL = (unsigned char)((ACCEPTANCE_FILTER_1 >> 16) & 0x03) | 
(unsigned char)((ACCEPTANCE_FILTER_1 >> 13) & 0xE0) | 0x08;
  RXF1SIDH = (unsigned char)((ACCEPTANCE_FILTER_1 >> 21) & 0xFF);
#endif

#ifdef ACCEPT_STANDARD_FILTER_2
  RXF2SIDL = (unsigned char)(ACCEPTANCE_FILTER_2 << 5);
  RXF2SIDH = (unsigned char)(ACCEPTANCE_FILTER_2 >> 3);
#else
  RXF2EIDL = (unsigned char)(ACCEPTANCE_FILTER_2 & 0xFF);
  RXF2EIDH = (unsigned char)((ACCEPTANCE_FILTER_2 >> 8) & 0xFF);
  RXF2SIDL = (unsigned char)((ACCEPTANCE_FILTER_2 >> 16) & 0x03) | 
(unsigned char)((ACCEPTANCE_FILTER_2 >> 13) & 0xE0) | 0x08;
  RXF2SIDH = (unsigned char)((ACCEPTANCE_FILTER_2 >> 21) & 0xFF);
#endif

#ifdef ACCEPT_STANDARD_FILTER_3
  RXF3SIDL = (unsigned char)(ACCEPTANCE_FILTER_3 << 5);
  RXF3SIDH = (unsigned char)(ACCEPTANCE_FILTER_3 >> 3);
#else
  RXF3EIDL = (unsigned char)(ACCEPTANCE_FILTER_3 & 0xFF);
  RXF3EIDH = (unsigned char)((ACCEPTANCE_FILTER_3 >> 8) & 0xFF);
  RXF3SIDL = (unsigned char)((ACCEPTANCE_FILTER_3 >> 16) & 0x03) | 
(unsigned char)((ACCEPTANCE_FILTER_3 >> 13) & 0xE0) | 0x08;
  RXF3SIDH = (unsigned char)((ACCEPTANCE_FILTER_3 >> 21) & 0xFF);
#endif

#ifdef ACCEPT_STANDARD_FILTER_4
  RXF4SIDL = (unsigned char)(ACCEPTANCE_FILTER_4 << 5);
  RXF4SIDH = (unsigned char)(ACCEPTANCE_FILTER_4 >> 3);
#else
  RXF4EIDL = (unsigned char)(ACCEPTANCE_FILTER_4 & 0xFF);
  RXF4EIDH = (unsigned char)((ACCEPTANCE_FILTER_4 >> 8) & 0xFF);
  RXF4SIDL = (unsigned char)((ACCEPTANCE_FILTER_4 >> 16) & 0x03) | 
(unsigned char)((ACCEPTANCE_FILTER_4 >> 13) & 0xE0) | 0x08;
  RXF4SIDH = (unsigned char)((ACCEPTANCE_FILTER_4 >> 21) & 0xFF);
#endif

#ifdef ACCEPT_STANDARD_FILTER_5
  RXF5SIDL = (unsigned char)(ACCEPTANCE_FILTER_5 << 5);
  RXF5SIDH = (unsigned char)(ACCEPTANCE_FILTER_5 >> 3);
#else
  RXF5EIDL = (unsigned char)(ACCEPTANCE_FILTER_5 & 0xFF);
  RXF5EIDH = (unsigned char)((ACCEPTANCE_FILTER_5 >> 8) & 0xFF);
  RXF5SIDL = (unsigned char)((ACCEPTANCE_FILTER_5 >> 16) & 0x03) | 
(unsigned char)((ACCEPTANCE_FILTER_4 >> 13) & 0xE0) | 0x08;
  RXF5SIDH = (unsigned char)((ACCEPTANCE_FILTER_5 >> 21) & 0xFF);
#endif

//Set the acceptance masks
  RXM0EIDL = (unsigned char)(ACCEPTANCE_MASK_0_1 & 0xFF);
  RXM0EIDH = (unsigned char)((ACCEPTANCE_MASK_0_1 >> 8) & 0xFF);
  RXM0SIDL=(unsigned char)(ACCEPTANCE_MASK_0_1 <<5);
  RXM0SIDH=(unsigned char)(ACCEPTANCE_MASK_0_1 >>3);
  RXM1EIDL = (unsigned char)(ACCEPTANCE_MASK_2_5 & 0xFF);
  RXM1EIDH = (unsigned char)((ACCEPTANCE_MASK_2_5 >> 8) & 0xFF);
  RXM1SIDL=(unsigned char)(ACCEPTANCE_MASK_2_5 <<5);
  RXM1SIDH=(unsigned char)(ACCEPTANCE_MASK_2_5 >>3);

  CIOCON = 0x20;            //Drive TX pin Vdd when recessive, disable 
capture

#ifdef CAN_LOW_INT
  IPR3 = 0x00;
#else
  IPR3 = 0xFF;
#endif

#ifdef USE_LOOPBACK_MODE
  CANCON = (LOOPBACK_MODE & MODE_MASK) | (CANCON & (MODE_MASK ^ 0xFF)); 
//Set loopback mode for debug purposes only
  while((CANSTAT & MODE_MASK) != (LOOPBACK_MODE & MODE_MASK));  //Wait 
until loopback mode is set
#else
  CANCON = (NORMAL_MODE & MODE_MASK) | (CANCON & (MODE_MASK ^ 0xFF)); 
//Set normal mode
  while((CANSTAT & MODE_MASK) != (NORMAL_MODE & MODE_MASK));    //Wait 
until normal mode is set
#endif
  PIE3 = CAN_INT_BITS & 0xE3;      //Enable CAN interrupts except TX 
interrupts
  PIR3 = 0x18;            //Set TXB1 & TXB2 int flags

//Send my address to notify our presence
#ifdef MY_ADDRESS_IS_STANDARD
  TXB0SIDL = (unsigned char)(MY_ADDRESS_IDENTIFIER << 5);
  TXB0SIDH = (unsigned char)(MY_ADDRESS_IDENTIFIER >> 3);    //Load 
address with MY_ADDRESS_IDENTIFIER standard identifier
  TXB0DLC = 0x00;                        //0 data bytes to send
  TXB0CON = 0x00;                        //Initiate transmission
  TXB0REQ = 1;
#else
  TXB0EIDL = (unsigned char)(MY_ADDRESS_IDENTIFIER & 0xFF);  //Load 
address with MY_ADDRESS_IDENTIFIER extended identifier
  TXB0EIDH = (unsigned char)((MY_ADDRESS_IDENTIFIER >> 8) & 0xFF);
  TXB0SIDL = (unsigned char)((MY_ADDRESS_IDENTIFIER >> 16) & 0x03) | 
(unsigned char)((ACCEPTANCE_FILTER_2 >> 13) & 0xE0) | 0x08;
  TXB0SIDH = (unsigned char)((MY_ADDRESS_IDENTIFIER >> 21) & 0xFF);
  TXB0DLC = 0x00;                        //0 data bytes to send
  TXB0CON = 0x00;                        //Initiate transmission
  TXB0REQ = 1;
#endif

  return 0;
}


/*********************************************************************
 * Function:        void CANISR(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    Will modify the RX/TX interrupt flags
 *                  and interrupt enable bits
 *
 * Overview:        Checks if a CAN reception/transmission was complete
 *                  and if so write/read to the CAN RX/TX FIFO buffers
 *
 * Note:            This function is supposed to be called from the ISR
 ********************************************************************/
void CANISR(void)
{
  unsigned char TempCANCON;

  if(PIR3 & PIE3)
  {
    TempCANCON = CANCON;

    if(RXB0IF && RXB0IE)
    {
      RXB0IF = 0;    //Clear interrupt flag
      CANCON = CANCON & 0xF0 | RXB0Interrupt;
      CANGetMessage();
    }
    else if(RXB1IF && RXB1IE)
    {
      RXB1IF = 0;    //Clear interrupt flag
      CANCON = CANCON & 0xF0 | RXB1Interrupt;
      CANGetMessage();
    }
    else if(TXB0IF && TXB0IE)
    {
      CANCON = CANCON & 0xF0 | TXB0Interrupt;
      if(CANPutMessage())
        TXB0IE = 0;
      else
        TXB0IF = 0;
    }
    else if(TXB1IF && TXB1IE)
    {
      CANCON = CANCON & 0xF0 | TXB1Interrupt;
      if(CANPutMessage())
        TXB1IE = 0;
      else
        TXB1IF = 0;
    }
    else if(TXB2IF && TXB2IE)
    {
      CANCON = CANCON & 0xF0 | TXB2Interrupt;
      if(CANPutMessage())      //if there wasn't any more messages to 
send
        TXB2IE = 0;        //disable interrupts for TXB2 and leave 
TXB2IF
      else            //still on so PutCAN() can reenable the interrupt 
and instantly vector to ISR
        TXB2IF = 0;        //message was sent, just clear the interrupt 
flag.
    }
    else if(ERRIF && ERRIE)
    {
      ERRIF = 0;      //Clear interrupt flag
#ifdef CAN_ERROR_HANDLER_ENABLE
      CANErrorHandler();
#endif
                //No error handler implemented!!!
    }
    else if(WAKIF && WAKIE)
    {
      WAKIF = 0;      //Clear interrupt flag
    }

    CANCON = TempCANCON;
  }
}


/*********************************************************************
 * Function:        void CANGetMessage(void)
 *
 * PreCondition:    <WIN2:WIN0> in the CANCON register has to set
 *                  to reflect the desired RXB registers
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    Will modify the RX FIFO Write pointer (RXWPtr)
 *
 * Overview:        Gets the registers for a RXB and puts them in the
 *                  CAN Receive buffer
 *
 * Note:            Care is not taken if buffer is full
 ********************************************************************/
void CANGetMessage(void)
{
  unsigned char i;
  if(++RXWPtr >= RXBUF)    //If pointer overflowed
    RXWPtr = 0;        //Clear it

  for(i=0;i<14;i++)
  {
    RXMessage[RXWPtr].Data[i] = *(unsigned char *)(0xF60+i);
  }
  RXB0FUL = 0;
}


/*********************************************************************
 * Function:        char CANPutMessage(void)
 *
 * PreCondition:    <WIN2:WIN0> in the CANCON register has to set
 *                  to reflect the desired TXB registers
 *
 * Input:           None
 *
 * Output:          0 -> A new message has been put in the transmit 
queue
 *                  1 -> There was no messages in the TX buffer to send
 *
 * Side Effects:    Will modify the TX buffer´s Read pointer (TXRPtr)
 *
 * Overview:        Checks if there is any messages to transmit and if 
so
 *                  place it in the registers reflected by <WIN2:WIN0>
 *
 * Note:            None
 ********************************************************************/
char CANPutMessage(void)
{
  unsigned char i;
  if(TXWPtr != TXRPtr)            //If there are any more data to send
  {
    if(++TXRPtr >= TXBUF)          //then increment the TX read pointer
      TXRPtr = 0;
    for(i=0;i<14;i++)
      *(unsigned char *)(0xF60+i) = TXMessage[TXRPtr].Data[i];
    RXB0RTRRO = 1;              //TXREQ = 1;
    return 0;
  }
  else
    return 1;
}


/*********************************************************************
 * Function:        char CANPut(struct CANMessage Message)
 *
 * PreCondition:    None
 *
 * Input:           A CAN message
 *
 * Output:          1 -> Failed to put a CAN on the buffer, buffer is 
full
 *                  0 -> The CAN message is put on the buffer and will 
be
 *                       transmitted eventually
 *
 * Side Effects:    Will modify the TX Buffer register´s Write pointer
 *
 * Overview:        Initially checks if at least one buffer slot is 
available
 *                  and if so push the requested message in the buffer.
 *                  Checks if the TX modules are idle and if they are, 
reactivate one.
 *
 * Note:            None
 ********************************************************************/
char CANPut(struct CANMessage Message)
{
  unsigned char TempPtr, i;
  if(TXWPtr == TXRPtr-1 || (TXWPtr == TXBUF-1 && TXRPtr == 0))  //if all 
transmit buffers are full return 1
    return 1;

  //Do not modify the TX pointer until the message has been successfully 
copied so the CANISR don't
  //send a message that isn't ready
  if(TXWPtr >= TXBUF-1)          //check if transmit write pointer will 
overflow
  {
    TempPtr = 0;              //and post clear write pointer
  }
  else
  {
    TempPtr = TXWPtr+1;              //and postincrement write pointer
  }

  if(Message.NoOfBytes > 8)          //Ensure we don't handle more than 
8 bytes
    Message.NoOfBytes = 8;

  TXMessage[TempPtr].Specific.TXBDLC.Byte = Message.NoOfBytes; 
//Set the data count

  if(!Message.Remote)      //If dataframe
  {
    TXMessage[TempPtr].Specific.TXBDLC.Bits.TXRTR = 0; 
//Clear the Remote Transfer Request bit

    for(i = 0; i < Message.NoOfBytes; i++)  //Load data registers
    {
      TXMessage[TempPtr].Specific.TXBD.Array[i] = Message.Data[i];
    }
  }
  else                      //Remote frame
  {
    TXMessage[TempPtr].Specific.TXBDLC.Bits.TXRTR = 1; 
//Set TXRTR bit
  }
  if(Message.Ext)            //Extended identifier
  {
    TXMessage[TempPtr].Specific.TXBEIDL.Byte = (unsigned 
char)(Message.Address & 0xFF);      // Put address <7:0> in EIDL
    TXMessage[TempPtr].Specific.TXBEIDH.Byte = (unsigned 
char)((Message.Address >> 8) & 0xFF);  // Put address <15:8> in EIDH
    TXMessage[TempPtr].Specific.TXBSIDL.Byte = (unsigned 
char)((Message.Address >> 16) & 0x03) | (unsigned char)((Message.Address 
>> 13) & 0xE0);
    TXMessage[TempPtr].Specific.TXBSIDH.Byte = (unsigned 
char)((Message.Address >> 21) & 0xFF);
    TXMessage[TempPtr].Specific.TXBSIDL.Bits.EXIDE = 1;
  }
  else                      //Standard identifier
  {
    TXMessage[TempPtr].Specific.TXBSIDL.Byte = (unsigned 
char)((Message.Address << 5) & 0xFF);  //Put address <2:0> in SIDL
    TXMessage[TempPtr].Specific.TXBSIDH.Byte = (unsigned 
char)((Message.Address >> 3) & 0xFF);  //Put address <10:3> in SIDH
    TXMessage[TempPtr].Specific.TXBSIDL.Bits.EXIDE = 0;
  }
  TXMessage[TempPtr].Specific.TXBCON.Byte = Message.Priority & 0x03; 
//Set the internal priority of the data frame

  TXWPtr = TempPtr;

  //Reenable an interrupt if it is idle, it doesn't matter if another TX 
source caught the pending message
  //before the source that is enabled here does since the interrupt 
CHECKS if there are any messages pending
  //and if the buffer is empty, it will disable itself again.
  if(!TXB0IE)      //TXB0 is idle
    TXB0IE = 1;    //enable TXB0 to fire an interrupt to send the 
pending message
  else if(!TXB1IE)    //else if TXB1 is idle
    TXB1IE = 1;    //same procedure
  else if(!TXB2IE)    //finally try TXB2
    TXB2IE = 1;

  return 0;
}


/*********************************************************************
 * Function:        char CANRXMessageIsPending(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          1 -> At least one received message is pending in the 
RX buffer
 *                  0 -> No received messages are pending
 *
 * Side Effects:    None
 *
 * Overview:        Checks if the RX Write pointer is equal to RX Read 
pointer and
 *                  if so returns 0, else returns 1
 *
 * Note:            Since no care is taken if the buffer overflow
 *                  this function has to be polled frequently to
 *                  prevent a software receive buffer overflow
 ********************************************************************/
char CANRXMessageIsPending(void)
{
  if(RXWPtr != RXRPtr)
    return 1;
  else
    return 0;
}



/*********************************************************************
 * Function:        struct CANMessage CANGet(void)
 *
 * PreCondition:    An unread message has to be in the buffer
 *                  use RXCANMessageIsPending(void) prior to
 *                  calling this function in order to determine
 *                  if an unread message is pending.
 *
 * Input:           None
 *
 * Output:          The received message
 *
 * Side Effects:    Will modify the RX Buffer register´s Read pointer
 *
 * Overview:        Pops the the first message of the RX buffer
 *
 * Note:            None
 ********************************************************************/
struct CANMessage CANGet(void)
{
  struct CANMessage ReturnMessage;
  unsigned char TempPtr, i;

  /*Do not modify the RX pointer until the message has been successfully
    copied to prevent ISR to overwrite it (Note. this is not implemented 
in the ISR yet)*/
  if(RXRPtr >= RXBUF-1)          //Check if pointer will overflow
  {
    TempPtr = 0;
  }
  else
  {
    TempPtr = RXRPtr+1;
  }

  ReturnMessage.NoOfBytes = RXMessage[TempPtr].Specific.RXBDLC.Byte & 
0x0F;          //copy data count
  if(RXMessage[TempPtr].Specific.RXBCON.Bits.RXRTRRO)  //Remote frame 
request
  {
    ReturnMessage.Remote = 1;
  }
  else        //Data frame
  {
    ReturnMessage.Remote = 0;                  //Clear remote flag
    for(i = 0; i < ReturnMessage.NoOfBytes; i++)        //copy data 
content
      ReturnMessage.Data[i] = RXMessage[TempPtr].Specific.RXBD.Array[i];
  }
  CANCON = CANCON & 0xF0;

  ReturnMessage.Address = (unsigned 
int)(RXMessage[TempPtr].Specific.RXBSIDH.Byte) << 3;      //Load the 
standard identifier into the address
  ReturnMessage.Address |= (RXMessage[TempPtr].Specific.RXBSIDL.Byte >> 
5);

  if(RXMessage[TempPtr].Specific.RXBSIDL.Bits.EXID)        //Extended 
identifier
  {
    ReturnMessage.Ext = 1;                    //Set the extended 
identifier flag
    ReturnMessage.Address = (ReturnMessage.Address << 2) | 
(RXMessage[TempPtr].Specific.RXBSIDL.Byte & 0x03);
    ReturnMessage.Address = ReturnMessage.Address << 16;    //and copy 
the extended address
    ReturnMessage.Address |= (unsigned 
int)(RXMessage[TempPtr].Specific.RXBEIDH.Byte) << 8;
    ReturnMessage.Address |= RXMessage[TempPtr].Specific.RXBEIDL.Byte;
  }
  else                //Standard identifier
  {
    ReturnMessage.Ext = 0;    //clear the extended identifier flag
  }

  RXRPtr = TempPtr;
  return ReturnMessage;
}


/*********************************************************************
 * Function:        void CANSetMode(unsigned char Mode)
 *
 * PreCondition:    None
 *
 * Input:           Desired CAN Mode
 *                  (CAN_LISTEN_MODE, CAN_LOOPBACK_MODE
 *                   CAN_DISABLE_MODE, CAN_NORMAL_MODE)
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Requests to set the desired mode and waits until
 *                  the mode has been set.
 *
 * Note:            If USE_LOOPBACK_MODE is defined the requested
 *                  mode will be loopback mode if the input is
 *                  Normal mode
 ********************************************************************/
void CANSetMode(unsigned char Mode)
{
#ifdef USE_LOOPBACK_MODE
  if(Mode == NORMAL_MODE)
  {
    CANCON = (LOOPBACK_MODE & MODE_MASK) | (CANCON & (MODE_MASK ^ 
0xFF));
    while((CANSTAT & MODE_MASK) != (LOOPBACK_MODE & MODE_MASK));
  }
  else
#endif
  {
    CANCON = (Mode & MODE_MASK) | (CANCON & (MODE_MASK ^ 0xFF));
    while((CANSTAT & MODE_MASK) != (Mode & MODE_MASK));
  }

}


CANDef.h**************************************************************** 
***************************


//Baudrate-Einstellung, hier 500kBit/sec
#define BAUD_RATE_PRESC 2
#define SJW_TIME 1
#define SAMPLES 3
#define PROP_TIME 1
#define PH_SEG_1 4
#define PH_SEG_2 4
//Ende Baudrate-Einstellung

#define CAN_CONFIG_1 BAUD_RATE_PRESC-1|(SJW_TIME-1<<6)
#if SAMPLES == 1
#define CAN_CONFIG_2 0x80|(PH_SEG_1-1<<3)|(PROP_TIME-1)
#elif SAMPLES == 3
#define CAN_CONFIG_2 0xC0|(PH_SEG_1-1<<3)|(PROP_TIME-1)
#else
#error "Number of samples is out of range"
#endif
#define CAN_CONFIG_3 PH_SEG_2-1

//Hier einfach die Werte und Masken für die Recieve Acceptance Filter 
eintragen
//RXMASK0--Filter 0-1
//RXMASK1--Filter 2-5
#define RXMASK0 0
#define RXMASK1 0
#define RXFILT0 0x000
#define ST_FILTER_0
#define RXFILT1 0x000
#define ST_FILTER_1
#define RXFILT2 0x000
#define ST_FILTER_2
#define RXFILT3 0x000
#define ST_FILTER_3
#define RXFILT4 0x000
#define ST_FILTER_4
#define RXFILT5 0x000
#define ST_FILTER_5
//Ende Filtereinstellungen

//#define LPBACK
#define MY_IDENT 100    //Standard-Identität, welche bei Power-On 
gesendet wird
#define STD_IDENT
#define RX_BUFFER 4
#define TX_BUFFER 4
//#define CAN_INT_LOW
//#define CAN_ERROR_HANDLER_ENABLE


main.c****************************************************************** 
*********************



#include  <p18cxxx.h>
#include "can.h"

#pragma config OSC = HS   //CPU=20 MHz
#pragma config PWRT = ON
#pragma config BOR = OFF
#pragma config WDT = OFF  //Watchdog Timer
#pragma config LVP = OFF  //Low Voltage ICSP
#pragma config PBADEN = OFF  //PORT B A/D-Wandler OFF

//Interrupthandler High
#pragma interrupt HighISR save=section(".tmpdata")
void HighISR(void)
{
  CANISR();
}

#pragma code highVector=0x08
void HighVector (void)
{
    _asm goto HighISR _endasm
}


#pragma code /* return to default code section */
void main()      //Main entry
{
  int j=0;
  struct CANMessage mes1;

  //Einrichten der RS232-Schnittstelle
  TXSTA = 0x20;                 // Sender RS232
    RCSTA = 0x90;                 // Empfänger RS232
  SPBRG = 7;
  SPBRGH = 0;                 // Baudrate 38400 bei 20MHz
  BAUDCON = 0x00;

  //Initialize CAN-Modul
  CANInit();
  //Alle Einstellung für das CAN-Modul befinden sich in der Datei
        //CANDef.h

  //Enable interrupts
  INTCONbits.GIE = 1;
  INTCONbits.PEIE = 1;

    while(1)
  {

    if(CANRXMessageIsPending())
    {
      mes1=CANGet();
      for(j=0;j<mes1.NoOfBytes;j++)
      {
        while ((~TXSTA) & 0x02);
        TXREG = (char)mes1.Data[j];
      }
    }
  }
}


CAN.hex**************************************************************


:020000040000FA
:06000000A2EF06F0120061
:0600080061EF05F012009B
:06002A0001005C0D000066
:08003000DA00000004000000EA
:08003800D9CFE6FFE1CFD9FFAB
:1000400093949386A36AA46A3F0E6F1480096F6E1F
:10005000E00E6E14800801E0FBD7FE0EDB50706EE0
:10006000FD0EDB50716EFC0EDB50726E040E606E86
:100070000F01506B200E016F220E006F400E056FB6
:10008000440E046F600E096F660E086F800E0D6FD0
:10009000880E0C6FA00E116FAA0E106FC00E156F98
:1000A000CC0E146F0F0E1B6F1A6FE00E196FE10E5E
:1000B000186FF00E1F6F0F0E1E6F1D6BFE0E1C6F64
:1000C000200E736EA5681F0E6F146F6EE00E6E1417
:1000D00001E0FCD7030EA36E180EA46E0F01800E74
:1000E000426F0C0E416F456B406B4087000E00D095
:1000F000E552E7CFD9FF1200D9CFE6FFE1CFD9FF14
:10010000E652A450A31460E06F50DF6EA450010BC0
:100110000AE0A350010B07E0A490F00E6F140C0945
:100120006F6E57D84FD0A450020B0AE0A350020BB9
:1001300007E0A492F00E6F140A096F6E4AD842D0FD
:10014000A450040B0EE0A350040B0BE0F00E6F1450
:1001500008096F6E84D8000902E0A39401D0A4942A
:1001600031D0A450080B0EE0A350080B0BE0F00EAA
:100170006F1406096F6E73D8000902E0A39601D0D0
:10018000A49620D0A450100B0EE0A350100B0BE04F
:10019000F00E6F1404096F6E62D8000902E0A39894
:1001A00001D0A4980FD0A450200B05E0A350200B41
:1001B00002E0A49A07D0A450400B04E0A350400BE7
:1001C00001E0A49CDF506F6EE552E552E7CFD9FF06
:1001D0001200D9CFE6FFE1CFD9FFE6520001DB2BB9
:1001E000040EE76EDB19E8AE02D0E73402D0E75028
:1001F000DB5D01E3DB6BDF6A0E0EDF5C2AE2DF50C2
:10020000EA6A600FE96E0F0EEA22EF50E66EDBC07D
:10021000E9FFEA6AE9BEEA680E0EEA02F3CFEAFFF6
:10022000E902F3CFE9FFF450EA26600EE926000E5A
:10023000EA22E9CF00F0EACF01F0DF500F010024FD
:10024000E96E000E0120EA6EE552E750EF6EDF2AFC
:10025000D3D7609EE552E552E7CFD9FF1200D9CF40
:10026000E6FFE1CFD9FFE6520001DC51DD5D3EE063
:10027000DC2B040EE76EDC19E8AE02D0E73402D0C6
:10028000E750DC5D01E3DC6BDF6A0E0EDF5C2AE227
:10029000DCC0E9FFEA6AE9BEEA680E0EEA02F3CFC3
:1002A000EAFFE902F3CFE9FFF450EA26980EE926C7
:1002B000000EEA22E9CF00F0EACF01F0DF500F0193
:1002C0000024E96E000E0120EA6EEF50E66EDF506A
:1002D000EA6A600FE96E0F0EEA22E552E750EF6E10
:1002E000DF2AD3D76086000E03D002D0010E00D0E3
:1002F000E552E552E7CFD9FF1200D9CFE6FFE1CFB3
:10030000D9FF020EE1260001DC05DD5D05E0030EEC
:10031000DD5D04E1DC5102E1010EDED1030EE76E8A
:10032000DD19E8AE02D0E73402D0E750DD5D02E32C
:10033000DF6A02D0DD29DF6EFC0EDB50080805E223
:10034000080EF36EFC0EF3CFDBFFDF500E0DF3CF84
:10035000E9FFF4CFEAFF980EE926000EEA22050E27
:10036000E926000EEA22FC0EDBCFEFFFD950F00F9A
:10037000E96EFF0EDA20EA6E0E0EE926000EEA2282
:10038000EF50020B4AE1DF500E0DF3CFE9FFF4CF3F
:10039000EAFF980EE926000EEA22050EE926000E75
:1003A000EA22EF9C010EDB6AFC0EDB50F36E010EBD
:1003B000DBCFF4FFF350F45C2FE2D950F40F026E60
:1003C000FF0EDA20036E010EDB500F010224E96EEE
:1003D000000E0320EA6EEF50E66EDF500E0DF3CFF5
:1003E000E9FFF4CFEAFF980EE926000EEA22060E96
:1003F000E926000EEA22E9CF00F0EACF01F0010E73
:10040000DB500024E96E000E0120EA6EE552E75051
:10041000EF6E010EDB2AC8D70FD0DF500E0DF3CFE1
:10042000E9FFF4CFEAFF980EE926000EEA22050E56
:10043000E926000EEA22EF8CD950F00FE96EFF0E8C
:10044000DA20EA6E0E0EE926000EEA22EF50010BCA
:1004500001E1C7D0F00EDBCF00F0F10EDBCF01F0F1
:10046000F20EDBCF02F0F30EDBCF03F00050E66EAE
:10047000DF500E0DF3CFE9FFF4CFEAFF980EE92627
:10048000000EEA22040EE926000EEA22E552E750A9
:10049000EF6EF00EDBCF00F0F10EDBCF01F0F20ECD
:1004A000DBCF02F0F30EDBCF03F0080ED89003325F
:1004B000023201320032E806F9E10050E66EDF5008
:1004C0000E0DF3CFE9FFF4CFEAFF980EE926000EF8
:1004D000EA22030EE926000EEA22E552E750EF6E0B
:1004E000F00EDBCF08F0F10EDBCF09F0F20EDBCF20
:1004F0000AF0F30EDBCF0BF00D0ED8900B320A3260
:1005000009320832E806F9E1E00E0C6E0D6A0E6A57
:100510000F6A0C5008160D5009160E500A160F508F
:100520000B16F00EDBCF04F0F10EDBCF05F0F20E70
:10053000DBCF06F0F30EDBCF07F006C000F007C0FC
:1005400001F00001026A036A030E0016016A026AE2
:10055000036A00500810E66EDF500E0DF3CFE9FF7E
:10056000F4CFEAFF980EE926000EEA22020EE926F1
:10057000000EEA22E552E750EF6EF00EDBCF00F0FE
:10058000F10EDBCF01F0F20EDBCF02F0F30EDBCF8A
:1005900003F0150ED8900332023201320032E80621
:1005A000F9E10050E66EDF500E0DF3CFE9FFF4CF16
:1005B000EAFF980EE926000EEA22EE52E552E750D5
:1005C000EF6EDF500E0DF3CFE9FFF4CFEAFF980E88
:1005D000E926000EEA22020EE926000EEA22EF8644
:1005E0005CD0F00EDBCF00F0F10EDBCF01F0F20EAD
:1005F000DBCF02F0F30EDBCF03F0050E1F0B07E09D
:10060000D8900036013602360336E806F9E100508C
:10061000E66EDF500E0DF3CFE9FFF4CFEAFF980E40
:10062000E926000EEA22020EE926000EEA22E55231
:10063000E750EF6EF00EDBCF00F0F10EDBCF01F0F4
:10064000F20EDBCF02F0F30EDBCF03F0030ED890F7
:100650000332023201320032E806F9E10050E66E60
:10066000DF500E0DF3CFE9FFF4CFEAFF980EE92635
:10067000000EEA22EE52E552E750EF6EDF500E0D0B
:10068000F3CFE9FFF4CFEAFF980EE926000EEA2245
:10069000020EE926000EEA22EF96FD0EDB50030B58
:1006A000E66EDF500E0DF3CFE9FFF4CFEAFF980EB0
:1006B000E926000EEA22E552E750EF6EDFCFDDF0CB
:1006C000A3B402D0A38406D0A3B602D0A38602D0DE
:1006D000A3A8A388000E00D0006E020EE15C02E227
:1006E000E16AE552E16E0050E552E7CFD9FF120012
:1006F0000001DA51DB5D03E0010E03D002D0000EF1
:1007000000D01200D9CFE6FFE1CFD9FF110EE126CC
:10071000030E0001E76EDA19E8AE02D0E73402D02A
:10072000E750DA5D03E30F0EDB6A05D0DA29E76EE6
:100730000F0EE7CFDBFFDB500E0DF3CFE9FFF4CF59
:10074000EAFF600EE926000EEA22050EE926000EF9
:10075000EA22EF500F0BE76E0C0EE7CFDBFF0F0E18
:10076000DB500E0DF3CFE9FFF4CFEAFF600EE92670
:10077000000EEA22EF50080B03E00E0EDB823CD0A5
:100780000E0EDB92100EDB6A0C0EDB50F36E100EB9
:10079000DBCFF4FFF350F45C2FE20F0EDB500E0DB5
:1007A000F3CFE9FFF4CFEAFF600EE926000EEA225C
:1007B000060EE926000EEA22E9CF02F0EACF03F0A6
:1007C000100EDB500F010224E96E000E0320EA6ECA
:1007D000EF50E66ED950040F006EDACF01F0100E24
:1007E000DB500024E96E000E0120EA6EE552E7506E
:1007F000EF6E100EDB2AC8D7F00E6F146F6E0F0E5F
:10080000DB500E0DF3CFE9FFF4CFEAFF600EE926CF
:10081000000EEA22EE52EF50006E016A030ED890ED
:1008200000360136E804FBE1000E00C0DFFF010ED8
:1008300001C0DBFF020EDB6A030EDB6A0F0EDB502A
:100840000E0DF3CFE9FFF4CFEAFF600EE926000EAC
:10085000EA22020EE926000EEA22EF50E00BE83809
:10086000E840006E016A026A036A0050DE1201501D
:10087000DE120250DE120350DD12DD52DD520F0E89
:10088000DB500E0DF3CFE9FFF4CFEAFF600EE9264F
:10089000000EEA22020EE926000EEA22EF50080BB3
:1008A00001E1A0D00E0EDB80D9CFE9FFDACFEAFF5D
:1008B000EECF00F0EECF01F0EECF02F0EFCF03F07D
:1008C000020E1F0B07E0D8900036013602360336C1
:1008D000E806F9E10F0EDB500E0DF3CFE9FFF4CF80
:1008E000EAFF600EE926000EEA22020EE926000E5B
:1008F000EA22EF50030B046E056A066A076A045089
:10090000001205500112065002120750031200C0D7
:10091000DFFF010E01C0DBFF020E02C0DBFF030E92
:1009200003C0DBFFD9CFE9FFDACFEAFFEECF00F05B
:10093000EECF01F0EECF02F0EFCF03F0100E1F0B61
:1009400007E0D8900036013602360336E806F9E1B2
:1009500000C0DFFF010E01C0DBFF020E02C0DBFFA3
:10096000030E03C0DBFF0F0EDB500E0DF3CFE9FFCC
:10097000F4CFEAFF600EE926000EEA22030EE92614
:10098000000EEA22EFCF00F000C001F0006A026A18
:10099000036A0050DE120150DE120250DE120350D4
:1009A000DD12DD52DD520F0EDB500E0DF3CFE9FFED
:1009B000F4CFEAFF600EE926000EEA22040EE926D3
:1009C000000EEA22EFCF00F0016A026A036A0050CB
:1009D000DE120150DE120250DE120350DD12DD5233
:1009E000DD5202D00E0EDB900F0EDBCFDAF0D9CF46
:1009F000E9FFDACFEAFFEECF00F0EECF01F0EECF65
:100A000002F0EECF03F0EECF04F0EECF05F0EECF24
:100A100006F0EECF07F0EECF08F0EECF09F0EECF04
:100A20000AF0EECF0BF0EECF0CF0EECF0DF0EFCFE3
:100A30000EF0D9CFE9FFDACFEAFFED50ED500EC04E
:100A4000EDFF0DC0EDFF0CC0EDFF0BC0EDFF0AC0C8
:100A5000EDFF09C0EDFF08C0EDFF07C0EDFF06C0C8
:100A6000EDFF05C0EDFF04C0EDFF03C0EDFF02C0C8
:100A7000EDFF01C0EDFF00C0EFFF110EE15C03E2EE
:100A800000D0E16AE552E16EE552E7CFD9FF1200EE
:100A9000D9CFE6FFE1CFD9FF1F0E6F14006EFE0E17
:100AA000DB50E00B00106F6EE00E6E14006EFE0E59
:100AB000DB50E00B005C01E0F7D7E552E7CFD9FF50
:020AC000120022
:0E0AC200DACFE4FFE2CFDAFFE9CFE4FFEACFBC
:100AD000E4FFF6CFE4FFF7CFE4FFF5CFE4FFF3CF79
:100AE000E4FFF4CFE4FFFACFE4FF00EE10F0020ED3
:100AF000E80403E3EECFE4FFFBD700EE00F0100EB6
:100B0000E80403E3EECFE4FFFBD7E6527CEC00F011
:100B1000E55200EE0FF0100EE80403E3E5CFEDFF21
:100B2000FBD700EE11F0020EE80403E3E5CFEDFF82
:100B3000FBD7E5CFFAFFE5CFF4FFE5CFF3FFE5CF35
:100B4000F5FFE5CFF7FFE5CFF6FFE5CFEAFFE5CF0D
:100B5000E9FFE5CFDAFF1100D9CFE6FFE1CFD9FFFA
:100B6000110EE126DE6ADD6A200EAC6E900EAB6ED1
:100B7000070EAF6EB06AB86A030EE66ED80EE66E68
:100B8000010EE66E1CEC00F0E552E552E552F28EE5
:100B9000F28C78EC03F0000901E17AD00F0EE12627
:100BA00082EC03F00F6E0F0EE15E0F50EECF00F0FF
:100BB000EECF01F0EECF02F0EECF03F0EECF04F077
:100BC000EECF05F0EECF06F0EECF07F0EECF08F057
:100BD000EECF09F0EECF0AF0EECF0BF0EECF0CF037
:100BE000EECF0DF0EECF0EF0020E00C0DBFF030ED5
:100BF00001C0DBFF040E02C0DBFF050E03C0DBFFFC
:100C0000060E04C0DBFF070E05C0DBFF080E06C0A2
:100C1000DBFF090E07C0DBFF0A0E08C0DBFF0B0E6F
:100C200009C0DBFF0C0E0AC0DBFF0D0E0BC0DBFFA3
:100C30000E0E0CC0DBFF0F0E0DC0DBFF100E0EC042
:100C4000DBFFDE6ADD6ADECF00F0DDCF01F00E0EE5
:100C5000DB50000101AE02D0D89003D0005C000E42
:100C6000015816E2D950060F006EDACF01F0DE50BF
:100C70000024E96EDD500120EA6EEF50AD6EAC1C31
:100C8000020B01E0FCD7DF2A010E01E3DB2ADBD7F0
:100C900080D7110EE15C02E2E16AE552E16EE552B5
:060CA000E7CFD9FF1200AE
:0A0CA6002A0EF66E000EF76E000E27
:100CB000F86E00010900F550D56F0900F550D66FA8
:100CC00003E1D56701D03DD00900F550D06F090090
:100CD000F550D16F0900F550D26F09000900F550A9
:100CE000E96E0900F550EA6E090009000900F550A7
:100CF000D36F0900F550D46F09000900F6CFD7F083
:100D0000F7CFD8F0F8CFD9F0D0C0F6FFD1C0F7FFB9
:100D1000D2C0F8FF0001D35302E1D45307E0090029
:100D2000F550EE6ED307F8E2D407F9D7D7C0F6FF37
:100D3000D8C0F7FFD9C0F8FF0001D507000ED65B79
:040D4000BFD7120007
:0C0D440012EE00F022EE00F0F86A119CA4
:0C0D500053EC06F0ACEC05F0FDD71200EF
:040D5C000000000093
:020000040030CA
:0100010002FC
:0100020018E5
:010003001EDE
:01000500807A
:010006008178
:00000001FF



Ich hoffe, du kannst damit was anfangen. Hab mir auch schon sagen lassen 
müssen, ich hätte einen ungewöhnlichen Programmierstil.




von Jürgen S. (Firma: privat) (jschmied)


Lesenswert?

Hallo!

Auch wenn der Thread schon alt ist, ein paar kleine Korrekturen:

1.) CANPutMessage:
     RXB0CONbits.RXRTRRO = 1;
Das Bit ist Read-Only, schreiben daher sinnlos.

2.) CANGetMessage:
     RXB0FUL = 0;
Das muss in die ISR, da je nach Interrupt RXB0FUL oder RXB1FUL 
zurückgesetzt werden muss. So wie es jetzt ist, funktioniert RXB1 gar 
nicht.

3.) RXRPtr, RXWPtr, TXRPtr, TXWPtr besser als unsigned definieren, das 
spart einige Bytes Code.

Ansonsten hat der Code mir viel geholfen. Danke!

vg

Jürgen

von Manuel (Gast)


Lesenswert?

Hi Leute,

Trotz dass der Thread alt ist, hoffe ich doch noch eine Antwort zu 
bekommen.

Die Can Übertragung funktioniert soweit super. Jetzt möchte ich jedoch 
auch nen Filter benutzen der nur die Nachrichten mit ID 0x104 
durchlässt. Dazu hab ich folgende Zeilen editiert:

#define CAN_CONFIG_3 PH_SEG_2-1
#define RXMASK0 0xFFF
#define RXMASK1 0
#define RXFILT0 0x104

Leider scheint das keinerlei Auswirkungen zu haben. Weiter oben steht 
man müsste den Mode noch ändern, jedoch weiß ich nicht welcher Mode 
damit in welchem Register gemeint ist.

Ich hoffe man kann mir hilfen und Vielen Dank schonmal.

Grüße Manu

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.