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.
Musst du nicht auch noch in einem Mask-Register etwas einstellen? (ich kenne den PIC nicht, beim MCP2515 muß man dem aber so tun...)
Hmm. Sollte unabhängig vom PIC sein. Was muss ich denn da eintragen?? Habs mal mit FF und 1 probiert, noch keine Änderung.
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.
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??
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.
>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)
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??
>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.
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.
@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 !
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.
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.