Hallo,
folgendes Problem
nachdem ich den CAN-Bus konfiguriert habe möchte ich wieder in den
Normal-Mode zurück... das geschieht ja bekanntlich mit folgendem
Codeschnipsel
1 | CANCON = 0x00;
| 2 |
| 3 | while(CANSTATbits.OPMODE0 == TRUE &&
| 4 | CANSTATbits.OPMODE1 == TRUE &&
| 5 | CANSTATbits.OPMODE2 == FALSE );
|
aber der PIC(PIC18F2480) bleibt in dieser While-schleife einfach
hängen... also irgendwie läst sich die 0x00 nicht in das CANCON-Register
schreiben wie mir scheint?
kann mir jemand helfen? habe ich etwas nicht beachtet?
MfG
Christoph
kleiner Fehler...
alle drei Bits müssen NULL/FALSE sein
also ...
1 | CANCON = 0x00;
| 2 |
| 3 | while(CANSTATbits.OPMODE0 == FALSE &&
| 4 | CANSTATbits.OPMODE1 == FALSE &&
| 5 | CANSTATbits.OPMODE2 == FALSE );
|
Hallo Christoph,
ich nutze den Code aus den Microchip Beispielen und da wird das
folgendermaßen erledigt...
1 | typedef enum _CAN_OP_MODE
| 2 | {
| 3 | CAN_OP_MODE_BITS = 0xe0, // Use this to access opmode bits
| 4 | CAN_OP_MODE_NORMAL = 0x00,
| 5 | CAN_OP_MODE_SLEEP = 0x20,
| 6 | CAN_OP_MODE_LOOP = 0x40,
| 7 | CAN_OP_MODE_LISTEN = 0x60,
| 8 | CAN_OP_MODE_CONFIG = 0x80
| 9 | } CAN_OP_MODE;
| 10 |
| 11 | :::
| 12 |
| 13 | void CAN_SetOperationMode(CAN_OP_MODE mode)
| 14 | {
| 15 | CANCON &= 0x1F; // clear previous mode
| 16 | CANCON |= mode; // set new mode
| 17 | // Wait untill desired mode is set
| 18 | while( (CANSTAT & CAN_OP_MODE_BITS) != mode );
| 19 | }
|
Das ist ja bis hier praktisch identisch mit deinem Code. Allerdings wird
diese Funktion nur für das Umschalten in den ConfigMode benutzt, beim
zurück Schalten in den NormalMode nutzt Microchip ein nicht
blockierendes Makro (Funktion) ala...
1 | #define CANSetOperationModeNoWait(mode) \
| 2 | { \
| 3 | CANCON &= 0x1F; \
| 4 | CANCON |= mode; \
| 5 | }
|
Der Aufruf im Programm sieht dann in etwa so aus...
1 | void CAN_Init (void)
| 2 | {
| 3 | CAN_SetOperationMode(CAN_OP_MODE_CONFIG);
| 4 | :::
| 5 | CANSetOperationModeNoWait(CAN_OP_MODE_NORMAL);
| 6 | }
|
Ich hab mir darüber noch nie Gedanken gemacht, so mach ich es auch und
es funktioniert! Was will man mehr...
Gruß, Steffen
erstmal besten Dank!
habs noch nicht ausprobiert aber wenns bei dir funzt und es von
microchip ist bin ich da guter dinge...
allerdings ist mein Code-schnipsle auch von Microchip... und
funktioniert nicht...
wo genau hast du das her?
...sind aus dem CanOpen Stack von Microchip.
can.h
can.c
Gruß, Steffen
Gerade noch mal nachgeschaut...
in der AN738 von Microchip macht man es auch so wie Du. Hier mal der
Codeauschnitt.
1 | enum CAN_OP_MODE
| 2 | {
| 3 | CAN_OP_MODE_BITS = 0b11100000, // Use this to access opmode
| 4 | // bits
| 5 | CAN_OP_MODE_NORMAL = 0b00000000,
| 6 | CAN_OP_MODE_SLEEP = 0b00100000,
| 7 | CAN_OP_MODE_LOOP = 0b01000000,
| 8 | CAN_OP_MODE_LISTEN = 0b01100000,
| 9 | CAN_OP_MODE_CONFIG = 0b10000000
| 10 | };
| 11 |
| 12 | :::
| 13 |
| 14 | void CANSetOperationMode(enum CAN_OP_MODE mode)
| 15 | {
| 16 | // Request desired mode.
| 17 | CANCON = mode;
| 18 |
| 19 | // Wait till desired mode is set.
| 20 | while( (CANSTAT & CAN_OP_MODE_BITS) != mode );
| 21 | }
|
Hab es jetzt nicht mehr genau in Erinnerung, aber ich würde behaupten
das auch das bei mir funktioniert hat.
Obwohl, ich sehe gerade... hängst Du hier nicht in einer Endlosschleife
fest?
1 | CANCON = 0x00;
| 2 |
| 3 | while(CANSTATbits.OPMODE0 == FALSE &&
| 4 | CANSTATbits.OPMODE1 == FALSE &&
| 5 | CANSTATbits.OPMODE2 == FALSE );
|
Die CANSTATbits müssen doch 0 sein. Deine Abfrage macht so doch nicht
das selbe wie der Code von Microchip.
Gruß, Steffen
ich schreibe doch in das CANSTAT-Register eine 0x00 und frage dann ab ob
auch wirklich alle null sind? wenn alle null sind gehts weiter. Ich denk
das ist so richtig... funktioniert hat es allerdings nicht... aber wenns
falsch ist versteh ich nicht warum...
noch eine Frage zu diesen AN´s,
also ich hab die AN945 gefunden... blicke da aber überhaupt nicht
durch...
die von dir erwähnt AN738 erscheint mir wesentlich übersichtlicher.
Kann ich die AN738 nutzen? gibt es irgendwo mal einen vollständigen Code
damit ich mir angucken kann wie soetwas auszusehen hat?
Christoph Herzog schrieb...
> ich schreibe doch in das CANSTAT-Register eine 0x00 und frage dann ab ob
> auch wirklich alle null sind? wenn alle null sind gehts weiter. Ich denk
> das ist so richtig...
Eben nicht... eine While-Schleife wird doch so lange ausgeführt, wie die
Bedingung wahr ist. Wenn du die CANSTATbits auf FALSE (0) testest ergibt
es doch Wahr, also wird die Schleife nie verlassen.
Schau dir mal die AN878 an, ist so ähnlich wie AN738, nutzt nur den ECAN
Mode.
oki also das mit der whileschleife war ein denkfehler von mir...
danke!!!
AN878 wird angeguckt ! ;)
diese ECAN.def-Datei soll ja noch definiert werden?
ist es sinnvoll das mit dieser Software zu machen oder per Hand? ich hab
mir die software mal angeguckt und die Datei ... naja und beide sind für
den Einstieg noch recht schwerzu verstehen finde ich
Keine Ahnung, hab damit nicht gearbeitet. Ich tue mich mit fremdem Code
auch immer schwer, jeder hat ja da so seine Vorlieben. Ich nehme mir
immer Teile davon vor und schreibe damit meine eigenen Funktionen. Dabei
lernt man dann auch wie es wirklich funktioniert.
Hier mal Teile meiner can.h und can.c
1 | #define PORT_CAN_TX_PIN LATCbits.LATC6
| 2 |
| 3 | // CAN Baud Rate Prescaler bei FOSC 64MHz und BitTime 16TQ
| 4 | #define CAN_BRP_100K 0x13 // 100kbit
| 5 | #define CAN_BRP_125K 0x0F // 125kbit
| 6 | #define CAN_BRP_250K 0x07 // 250kbit
| 7 | #define CAN_BRP_500K 0x03 // 500kbit
| 8 | #define CAN_BRP_1000K 0x01 // 1000kbit
| 9 |
| 10 |
| 11 | typedef enum _CAN_FLAGS
| 12 | {
| 13 | CAN_MSG_STD = 0,
| 14 | CAN_MSG_XTD = 1,
| 15 |
| 16 | CAN_CONFIG_B0_BITS = 0b01100100,
| 17 | CAN_CONFIG_B1_BITS = 0b01100000,
| 18 |
| 19 | CAN_DBL_BUFFER_ON = 0b00000100, // XXX1XXXX
| 20 | CAN_DBL_BUFFER_OFF = 0b00000000, // XXX0XXXX
| 21 |
| 22 | CAN_ALL_MSG = 0b01100000, // X11XXXXX
| 23 | CAN_VALID_XTD_MSG = 0b01000000, // X10XXXXX
| 24 | CAN_VALID_STD_MSG = 0b00100000, // X01XXXXX
| 25 | CAN_ALL_VALID_MSG = 0b00000000 // X00XXXXX
| 26 | } CAN_FLAGS;
| 27 |
| 28 |
| 29 | void CAN_SetBaudRate (BYTE brp)
| 30 | {
| 31 | /* Sync Jump Width
| 32 | <--->
| 33 | |_Sync_|_Delay _|______Phase1______|__Phase2__|
| 34 | | ^ ^ ^ |
| 35 | | SamplePoint |
| 36 | |<---------------- Bit Time ----------------->| */
| 37 |
| 38 | // Die folgenden 4 Elemente ergeben die CAN Bit Time
| 39 | #define CAN_SYNC_SEG 1 // (immer 1) Sync Segment = 1TQ
| 40 | #define CAN_PROP_DELAY 2 // (1-8) Propagation Delay = 2TQ
| 41 | #define CAN_PH_SEG_1 8 // (1-8) Phase Segment 1 = 8TQ
| 42 | #define CAN_PH_SEG_2 5 // (1-8) Phase Segment 2 = 5TQ
| 43 | // Bit Time = (Sync Segment + Propagation Delay + Phase Segment 1 + Phase Segment 2) = 16*TQ
| 44 |
| 45 | #define CAN_JUMP_WDH 1 // Syncronization Jump Width = 1 (1-4)
| 46 |
| 47 | #define CAN_SEG_2_FREE 1 // (bit) Phase Segment 2 frei Programierbar
| 48 | #define CAN_MULTI_SMPL 1 // (bit) Multiple sampling is on
| 49 | #define CAN_WAKE_UP_DIS 0 // (bit) Wake-up Disable
| 50 | #define CAN_LINE_FLT 0 // (bit) Selects CAN bus Line Filter for Wake-up
| 51 |
| 52 | BRGCON1 = ((CAN_JUMP_WDH-1) << 6) | (brp);
| 53 |
| 54 | BRGCON2 = (CAN_SEG_2_FREE << 7) |
| 55 | (CAN_MULTI_SMPL << 6) |
| 56 | ((CAN_PH_SEG_1-1) << 3) |
| 57 | (CAN_PROP_DELAY-1);
| 58 |
| 59 | BRGCON3 = (CAN_WAKE_UP_DIS << 7) |
| 60 | (CAN_LINE_FLT << 6) |
| 61 | (CAN_PH_SEG_2-1);
| 62 | }
| 63 |
| 64 |
| 65 | void CAN_Init (BYTE brp, BYTE config)
| 66 | {
| 67 | CAN_SetOperationMode(CAN_OP_MODE_CONFIG);
| 68 |
| 69 | // Set I/O control
| 70 | CIOCON = 0x00; // Reset CAN I/O Control Register
| 71 | CIOCONbits.ENDRHI = 1; // CANTX pin will drive VDD when recessive
| 72 | CIOCONbits.CLKSEL = 0; // Use the PLL as the source of the CAN system clock
| 73 |
| 74 | PORT_CAN_TX_PIN = 1; // CAN TX Pin auf 1 setzen, der Tranceiver funktioniert sonst nicht
| 75 |
| 76 | CAN_SetBaudRate (brp);
| 77 |
| 78 | // ECAN Module in mode 0
| 79 | ECANCON = 0x00;
| 80 |
| 81 | RXB0CON = config & CAN_CONFIG_B0_BITS;
| 82 | RXB1CON = config & CAN_CONFIG_B1_BITS;
| 83 |
| 84 | // Set default filter and mask registers for all receive buffers.
| 85 | CANSetMask(CAN_MASK_B1, 0x0800FF00, CAN_MSG_XTD);
| 86 | CANSetMask(CAN_MASK_B2, 0x000000FF, CAN_MSG_XTD);
| 87 |
| 88 | // By default, there will be no mask on any receive filters,
| 89 | // hence filter value of '0' will be ignored.
| 90 | CANSetFilter(CAN_FILTER_B1_F1, 0x08000000, CAN_MSG_XTD); // Filter 1
| 91 | CANSetFilter(CAN_FILTER_B1_F2, 0x08000400, CAN_MSG_XTD); // Filter 2
| 92 | CANSetFilter(CAN_FILTER_B2_F1, 0x00000000, CAN_MSG_XTD); // Filter 3
| 93 | CANSetFilter(CAN_FILTER_B2_F2, 0x00000000, CAN_MSG_XTD); // Filter 4
| 94 | CANSetFilter(CAN_FILTER_B2_F3, 0x00000000, CAN_MSG_XTD); // Filter 5
| 95 | CANSetFilter(CAN_FILTER_B2_F4, 0x00000000, CAN_MSG_XTD); // Filter 6
| 96 |
| 97 | // Set interrupts
| 98 | PIE5bits.RXB0IE = 1; // Receive Buffer 0 Interrupt enabled
| 99 | PIE5bits.RXB1IE = 1; // Receive Buffer 1 Interrupt enabled
| 100 | IPR5bits.RXB0IP = 0; // Low priority for Receive Buffer 0
| 101 | IPR5bits.RXB1IP = 0; // Low priority for Receive Buffer 1
| 102 |
| 103 | CANSetOperationModeNoWait(CAN_OP_MODE_NORMAL);
| 104 | }
|
in der Main
1 | CAN_Init (CAN_BRP_250K, CAN_VALID_XTD_MSG | CAN_DBL_BUFFER_ON);
|
CANSetMask() und CANSetFilter() sind fast 1:1 aus der AN738
folgendes Probelm tut sich gerad bei meinem Code auf
1 | typedef enum _BOOL { FALSE = 0, TRUE } BOOL;
|
ich habe mich zu diesem enum-Zeug ein bissel belesen und kann kein
Fehler finden... ist ja eigentlich auch von Mircochip selbst... ich hab
das gar nicht angefast... :(
ECAN.h:77: error: enum tag "_BOOL" redefined (from C:\Program Files
(x86)\Microchip\xc8\v1.12\include\GenericTypeDefs.h:65)
in der GenericTypeDefs.h hab ich mich auch mal umgeschaut...
was will der compiler jetzt von mir?
das Problem hab ich gelöst ;)
aber werden sicher weitere Folgen ;)
hallo nochmal... also ich habe die Konfiguration für den CAN-Bus jetzt
fertig denke ich...
wenn ich jetzt einen Frame senden möchte wird allerdings das ERRI und
das IRXI Flag gesetzt...
ich weiß aber nicht genau was die beiden auslöst...
Auf dem Bus ist auf jeden fall ne Menge los. wenn ich ein Frame senden
möchte hört der Pic gar nicht mehr auf zu senden.
wie kann ich mir das erklären?
an bei mal meine Init und die Transmitfunktion
wer toll wenn mal einer drüber schauen könnte
MfG
Christoph
1 | #include <p18cxxx.h>
| 2 | #include "ECAN.h"
| 3 |
| 4 |
| 5 | /*********************************************************************
| 6 | *
| 7 | * Defines
| 8 | *
| 9 | *********************************************************************/
| 10 |
| 11 |
| 12 | // ECAN
| 13 | #define F_ECANMode2_FP CANCON&0x0F
| 14 | #define F_ECANFIFO_0 RXB0CONbits.RXFUL
| 15 | #define F_ECANFIFO_1 RXB1CONbits.RXFUL
| 16 | #define F_ECANFIFO_2 B0CONbits.RXFUL
| 17 | #define F_ECANFIFO_3 B1CONbits.RXFUL
| 18 | #define F_ECANFIFO_4 B2CONbits.RXFUL
| 19 | #define F_ECANFIFO_5 B3CONbits.RXFUL
| 20 | #define F_ECANFIFO_6 B4CONbits.RXFUL
| 21 | #define F_ECANFIFO_7 B5CONbits.RXFUL
| 22 |
| 23 |
| 24 |
| 25 | #define CANSetOperationModeNoWait(mode) \
| 26 | { \
| 27 | CANCON &= 0x1F; \
| 28 | CANCON |= mode; \
| 29 | }
| 30 |
| 31 |
| 32 | /*********************************************************************
| 33 | *
| 34 | * Global Variables
| 35 | *
| 36 | *********************************************************************/
| 37 | unsigned char temp_EIDH;
| 38 | unsigned char temp_EIDL;
| 39 | unsigned char temp_SIDH;
| 40 | unsigned char temp_SIDL;
| 41 | unsigned char temp_DLC;
| 42 | unsigned char temp_D0;
| 43 | unsigned char temp_D1;
| 44 | unsigned char temp_D2;
| 45 | unsigned char temp_D3;
| 46 | unsigned char temp_D4;
| 47 | unsigned char temp_D5;
| 48 | unsigned char temp_D6;
| 49 | unsigned char temp_D7;
| 50 |
| 51 | typedef enum _CAN_OP_MODE
| 52 | {
| 53 | CAN_OP_MODE_BITS = 0xe0, // Use this to access opmode bits
| 54 | CAN_OP_MODE_NORMAL = 0x00,
| 55 | CAN_OP_MODE_SLEEP = 0x20,
| 56 | CAN_OP_MODE_LOOP = 0x40,
| 57 | CAN_OP_MODE_LISTEN = 0x60,
| 58 | CAN_OP_MODE_CONFIG = 0x80
| 59 | } CAN_OP_MODE;
| 60 |
| 61 |
| 62 |
| 63 | /*********************************************************************
| 64 | *
| 65 | * Configure the CAN Module
| 66 | *
| 67 | *********************************************************************/
| 68 | void InitECAN(void)
| 69 | {
| 70 | // Enter CAN module into config mode
| 71 |
| 72 |
| 73 | CANSTAT &= 0x1F; // clear previous mode
| 74 | CANSTAT |= 0x80; // set new mode
| 75 | // Wait untill desired mode is set
| 76 | while( CANSTAT != 0x80 );
| 77 |
| 78 |
| 79 | // Enter CAN module into Mode 2
| 80 |
| 81 | ECANCON = 0x80;
| 82 |
| 83 |
| 84 | // Initialize CAN Timing
| 85 |
| 86 | // 8MHz
| 87 | BRGCON1 = 0xE1; //1110 0001 //SJW=4 TQ BRP 4
| 88 | BRGCON2 = 0x1B; //0001 1011 //SEG2PHTS 1 sampled once PS1=4TQ PropagationT 4TQ
| 89 | BRGCON3 = 0x03; //0000 0011 //PS2 4TQ
| 90 |
| 91 |
| 92 |
| 93 |
| 94 | // Setup Programmable buffers
| 95 | // B0 is a receive buffer AND B2,B3,B4,B5 are Transmit buffers
| 96 | BSEL0 = 0xF8; //1111 10--
| 97 |
| 98 | // Initialize Receive Masks
| 99 |
| 100 | RXM0EIDH = 0x00; // 0's for EID and SID
| 101 | RXM0EIDL = 0x00;
| 102 | RXM0SIDH = 0xFF; // Standard ID FILTER
| 103 | RXM0SIDL = 0x80;
| 104 |
| 105 | RXM1EIDH = 0x00;
| 106 | RXM1EIDL = 0x00;
| 107 | RXM1SIDH = 0xFF;
| 108 | RXM1SIDL = 0x80;
| 109 |
| 110 |
| 111 | // Enable Filters
| 112 | // Filter 0
| 113 | RXFCON0 = 0x01; //
| 114 | RXFCON1 = 0x00; //Disable all from Filter 1-15
| 115 |
| 116 | // Assign Filters to Masks
| 117 |
| 118 | MSEL0 = 0xFF; //Assign Filters 0-3 to // No mask
| 119 | MSEL1 = 0xFF; //Assign Filters 4-7 to // No mask
| 120 | MSEL2 = 0xFF; //Assign Filters 8-11 to // No mask
| 121 | MSEL3 = 0xFF; //Assign Filters 12-15 to // No mask
| 122 |
| 123 |
| 124 |
| 125 |
| 126 | // Initialize Receive Filters
| 127 | // Filter 0 = 0xFFC
| 128 | RXF0EIDH = 0x00;
| 129 | RXF0EIDL = 0x00;
| 130 | RXF0SIDH = 0x6B;
| 131 | RXF0SIDL = 0xC0;
| 132 | // Filter 1 = 0xFFC
| 133 | RXF1EIDH = 0x00;
| 134 | RXF1EIDL = 0x00;
| 135 | RXF1SIDH = 0xFF;
| 136 | RXF1SIDL = 0xC0;
| 137 |
| 138 | // Enter CAN module into normal mode
| 139 | CANSetOperationModeNoWait(CAN_OP_MODE_NORMAL);
| 140 |
| 141 | // Set Receive Mode for buffers
| 142 | RXB0CON = 0x00;
| 143 | RXB1CON = 0x00;
| 144 |
| 145 | }
| 146 |
| 147 |
| 148 | /*********************************************************************
| 149 | *
| 150 | * Transmit Sample Mesaage
| 151 | *
| 152 | *********************************************************************/
| 153 | void ECAN_Transmit(void)
| 154 | {
| 155 | TXB0EIDH = 0x00; // Identifier
| 156 | TXB0EIDL = 0x00; // Identifier
| 157 |
| 158 | //0x35E 0110 1011 110
| 159 | TXB0SIDH = 0x6B; // Identifier
| 160 | TXB0SIDL = 0xC0; // Identifier
| 161 |
| 162 | TXB0DLC = 0x03; // DataLength
| 163 | TXB0D0 = 0xAA; // DataByte
| 164 | TXB0D1 = 0xCC; // DataByte
| 165 | TXB0D2 = 0x55; // DataByte
| 166 | TXB0D3 = 0x00; // DataByte
| 167 | TXB0D4 = 0x00; // DataByte
| 168 | TXB0D5 = 0x00; // DataByte
| 169 | TXB0D6 = 0x00; // DataByte
| 170 | TXB0D7 = 0x00; // DataByte
| 171 |
| 172 | TXB0CONbits.TXREQ = 1; //Set the buffer to transmit
| 173 |
| 174 |
| 175 |
| 176 | }
|
Du hast aber mindestens noch einen 2. aktiven Teilnehmer am CAN-Bus?
ja den hab ich...
aber da ich nicht weiß ob die initialisierung wirklich richtig ist weiß
ich auch nicht ob das alles so hin haut
Da kann ich dir jetzt leider auch nicht direkt helfen, ich habe das
CAN-Modul im Mode0 benutzt.
Was für einen Quarz hängt an deinem PIC und benutzt Du die interne PLL?
Bedenke das die Werte im BRP-Register von FOSC ausgehen. Z.B. bei einem
8MHz Quarz und 4xPLL = 32MHz. Die Pic rechnet dann wieder nur mit 8MHz,
da er immer 4 Taktzyklen für einen Befehl benötigt.
Stimmen alle Richtungen der IO's? Ich weiß jetzt nicht ob sich das
CAN-Modul die Ein- und Ausgänge selber setzt. Ich mußte bei mir, in der
Init() Routine den CAN-TX Pin von Hand auf high setzen, sonst ging
nichts. Aber bei dir scheint ja auf dem Bus schon was los zu sein...
Kennst Du das Tool MBTime von Microchip, mit dem kann man die Werte für
die BRP-Register berechnen lassen. Funktioniert für den mcp2551 und die
pic18.
http://www.codeforge.com/article/200254
Gruß, Steffen
Sehe gerade das man sich zum Download anmelden muß, also wenn du es
benötigst kurze Nachricht an mich. Sende es dir dann per mail.
ich werde das jetzt auch alles für den Mode 0 machen...
zum einen weiß ich noch gar nicht genau was der FIFO-Mode ist zum
anderen brauch ich den EXTENDED-Kram gar nicht...
Auf dem Bus ist schon ordentlich Party ja... also gesendet wird sobald
ich das will... aber ich weiß halt nicht genau für was die beiden
Fehler-bits ERRI und IRXI stehen...
der andere Busteilnehmer müssten doch den empfang bestätigen ne? sonst
hört der sendende Busteilnehmer nicht auf???
Christoph Herzog schrieb:
> der andere Busteilnehmer müssten doch den empfang bestätigen ne? sonst
> hört der sendende Busteilnehmer nicht auf???
Genau so sollte es sein. Allerdings müßte der sendende Knoten irgendwann
in der Error Status gehen und das Senden aufgeben. Haben auch alle
Knoten die selbe Baudrate?
Versuch doch mal den Loopback Modus, dann solltest Du keinen weiteren
Teilnehmer benötigen. Du empfängst dann praktisch deine eigenen
Telegramme.
Baudrate ist die gleiche... sind beides Pic18F2480 mit internen 8Mhz
gleiche ECAN-ini... nur die Filter sind geändert bzw. die Identifier.
was genau bringt mir der Loopback modus... also ich habe ihn schon mal
ausprobiert und benutzt allerdings nicht mit dir jetztige von mir selbst
geschriebenen ECAN.h / ECAN.c.
also ich schicke was und Empfange es gleich wieder... liegt es dann auch
auf dem bus?oder Passiert das nur intern im Controller?
muss ich im Loopback-modus den gleichen Filter haben wie ich als
identifier raus gebe?
na mal sehen was wird ;) teste das jetzt mal
danke erstmal
PS.: auch für die Datei
Du arbeitest mit dem internen 8Mhz Oszillator? Ich kann mich täuschen,
aber ich glaube da reichen die Toleranzen nicht. Bei CAN sollte man
schon einen externen Quarz nehmen, oder mal ganz ganz niedrige Baudraten
versuchen.
So ganz genau kenne ich mich mit dem Loopbackmodus auch nicht aus. Ich
habe das so verstanden, das er dann quasi mit sich selbst kommuniziert
ohne die Signale auf den Bus zu legen. Du mußt natürlich auch die Filter
so setzen, das die Frames durchgehen. Damit kann man im Prinzip die
grundlegende Funktionalität ohne weitere Teilnehmer testen.
PS: Gerne...
eine Frage mal noch zum auslesen bzw. senden auf den Can-Bus
ich habe das ganze jetzt erstmal im Loop-modus zu laufen.
wenn ich einmal sende ist alles oki... es wird gesendet und empfangen
und der pic läuft weiter...
wenn ich ein zweites mal senden will bleibt das ding irgendwo hängen,
also in einem Interrupt mit sicherheit. komischer weiße wird mir nicht
angezeigt welches der 4 Flags auslöst ( ERRI IRXIF TXB0IF TXB1IF)
da stellt sich mir die frage was ich mit den empfangenen Daten anstellen
darf/muss... müssen irgendwelche bits nach dem Empfangen manuel zurück
gesetzt werden??
beim schreiben setze ich einfache alle notwendigen variablen und setze
am ende das TXREQ-Bit zum senden
beim auslesen, lese ich alle Daten aus beschreibe sie danach mit Null
und setze das PIR3.RXB0IF = 0
Kann dir jetzt auf die Schnelle nur meine Intrruptabfrage zeigen, muß
gleich los...
1 | // CAN Receive Buffer 0 Interrupt Flag
| 2 | if (PIR5bits.RXB0IF)
| 3 | {
| 4 | if (RXB0CONbits.RXFUL)
| 5 | {
| 6 | CAN_ReceiveMessage ();
| 7 | RXB0CONbits.RXFUL = 0;
| 8 | }
| 9 | PIR5bits.RXB0IF = 0; // Clear the received flag.
| 10 | }
| 11 |
| 12 | // CAN Receive Buffer 1 Interrupt Flag
| 13 | if (PIR5bits.RXB1IF)
| 14 | {
| 15 | if (RXB1CONbits.RXFUL)
| 16 | {
| 17 | CAN_ReceiveMessage ();
| 18 | RXB1CONbits.RXFUL = 0;
| 19 | }
| 20 | PIR5bits.RXB1IF = 0; // Clear the received flag.
| 21 | }
|
Die Funktion CAN_ReceiveMessage() liest nur die Register aus, da wird
nichts geändert. Störe dich nicht an den Registernamen, ich arbeite mit
dem PIC18F46K80. Versuch doch auch mal mit den Prioritäten der Interrups
zu spielen, sind da alle Register richtig gesetzt?
Gruß, viel Erfolg und ein schönes WE... :-)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
|