Forum: Mikrocontroller und Digitale Elektronik Normal-Mode CAN-BUS


von Christoph H. (obbedair)


Lesenswert?

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

von Christoph H. (obbedair)


Lesenswert?

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

von Ste N. (steno)


Lesenswert?

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

von Christoph H. (obbedair)


Lesenswert?

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?

von Ste N. (steno)


Lesenswert?

...sind aus dem CanOpen Stack von Microchip.

can.h
can.c

Gruß, Steffen

von Ste N. (steno)


Lesenswert?

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

von Christoph H. (obbedair)


Lesenswert?

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?

von Ste N. (steno)


Lesenswert?

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.

von Christoph H. (obbedair)


Lesenswert?

oki also das mit der whileschleife war ein denkfehler von mir... 
danke!!!
AN878 wird angeguckt ! ;)

von Christoph H. (obbedair)


Lesenswert?

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

von Ste N. (steno)


Lesenswert?

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

von Christoph H. (obbedair)


Lesenswert?

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?

von Christoph H. (obbedair)


Lesenswert?

das Problem hab ich gelöst ;)

aber werden sicher weitere Folgen ;)

von Christoph H. (obbedair)


Lesenswert?

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
}

von Ste N. (steno)


Lesenswert?

Du hast aber mindestens noch einen 2. aktiven Teilnehmer am CAN-Bus?

von Christoph H. (obbedair)


Lesenswert?

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

von Ste N. (steno)


Lesenswert?

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.

von Christoph H. (obbedair)


Lesenswert?

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

von Ste N. (steno)


Lesenswert?

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.

von Christoph H. (obbedair)


Lesenswert?

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

von Ste N. (steno)


Lesenswert?

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

von Christoph H. (obbedair)


Lesenswert?

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

von Ste N. (steno)


Lesenswert?

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.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.