Forum: Mikrocontroller und Digitale Elektronik AVRCAN bekommt RX-Interrupt nicht mit


von Mechatronk A. (mechatronk)


Lesenswert?

Mein AVRCAN hat ein Problem, lustiger weise mit Code, von dem ich 
schwören könnte der es vor einem Jahr in der Form noch getan hat.

Mit 2 verschiedenen Can-Interfaces, Oszi und allen möglichen 
Einstellungen getestet, das zu Empfangenen Signal ist auf jeden Fall im 
Bus und sieht OK aus.
Senden geht vom Controller aus wunderbar, der TX Interrupt feuert auch 
wenn man ihn aktiviert.
Der RX Interrupt wird einfach nicht ausgelöst, Remote Requests 
Funktionieren auch nicht.
Ich verwende eine leicht modifizierte Lib Michael aus diesem Thread:
Beitrag "CAN-Bibliothek für den at90CAN128 und das AVRStudio"

Ich habe zusätzlich eine Inbox angelegt, in der für jeden Mob bei 
eintreffen einer den Filter passierenden Nachricht die Nachricht 
hinterlegt wird, aber so weit kommt es ja garnicht.

Ich habe mein Programm auf das Nötigste eingedampft. In einer 
Endlosschleife wird der Bereich der Inbox auf Mob 0 mit ID 2 ausgegeben, 
der von Mob 1 mit ID 1 beschrieben wird.
Ich bitte Schönheitsfehler zu entschuldigen, ich pfusche da schon den 
ganzen Tag dran rum und komme auf keinen grünen Zweig.

Danke das ihr bis hier gelesen habt, da ist der Code:

main.c
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <inttypes.h>
4
#include <stdbool.h>
5
6
#define F_CPU 16000000ULL
7
#include <util/delay.h>
8
9
#include "can.h"
10
11
//Variablen
12
13
14
int8_t can_out[8];
15
16
17
  
18
void PORT_Init()
19
{
20
  PORTA = 0b00000000;
21
  DDRA = 0b00000000;
22
23
  PORTB = 0b00000000;
24
  DDRB = 0b00000000;     
25
26
  PORTC = 0b00000000;
27
  DDRC = 0b00000000;
28
29
  PORTD = 0b00000000;
30
  DDRD = 0b00000100;     
31
32
  PORTE = 0b00010000;
33
  DDRE = 0b00010000;    //Led set as output (Bit4 = 1) 
34
    
35
  PORTF = 0b00000000;
36
  DDRF = 0b00000000;
37
  }
38
39
40
void WDT_off(void)
41
  {
42
  cli();
43
  /* Write logical one to WDCE and WDE */
44
  WDTCR = (1<<WDCE) | (1<<WDE);
45
  /* Turn off WDT */
46
  WDTCR = 0x00;
47
  }
48
void bus_init(void)
49
  {
50
    
51
  // baudrate: 1M,rx interrupt, extendet Id
52
  can_init(CAN_BAUDRATE_1000K , CAN_INTERRUPT_RX, 1);
53
 
54
  can_enable_mob(1, CAN_MODE_RECEIVE_DATA,    1, 0xffffffff);
55
 
56
  }
57
58
59
void sleep(uint32_t i) 
60
{
61
  while(i--)
62
    _delay_ms(1);
63
}
64
65
int main()
66
  {
67
  WDT_off();
68
  PORT_Init();
69
  bus_init(); 
70
  sei();  // Alles Initialisiert, Interupts Freischalten
71
  
72
    
73
  
74
  while (1)
75
  
76
    {
77
78
79
80
     //Ausgabe Status  
81
82
     int j;
83
    
84
      for (j=0;j<8;j++)
85
        {
86
        can_out[j]=inbox[0][j];
87
        }
88
      can_enable_mob(0, CAN_MODE_TRANSMIT_DATA, 2 ,0xffffffff);
89
      can_send_data(0,8,can_out); 
90
      can_disable_mob(0);
91
      sleep(100);
92
      
93
      
94
95
    
96
     }
97
98
     
99
  }

can.h
1
#ifndef CAN_H
2
  #define CAN_H
3
4
  #include <inttypes.h>
5
6
  #define setbit(ADR,BIT)   (ADR |= (1<<BIT))
7
  #define clearbit(ADR,BIT) (ADR &=~(1<<BIT))
8
  #define getbit(ADR, BIT)  (ADR &  (1<<BIT))
9
10
  /* CAN Objekte */
11
  #define NO_MOBS 15   // Anzahl der Message Objects festlegen
12
  #define NOMOB   0xff // Definition für ungültigen Objektindex
13
14
  // Betriebsmodi
15
  enum { CAN_MODE_DISABLED, CAN_MODE_TRANSMIT_DATA, CAN_MODE_TRANSMIT_REMOTE,
16
         CAN_MODE_RECEIVE_DATA, CAN_MODE_AUTO_REPLY };
17
18
  // Interrupt-Modi
19
  enum { CAN_INTERRUPT_NONE, CAN_INTERRUPT_TX, CAN_INTERRUPT_RX,
20
         CAN_INTERRUPT_TXRX };
21
22
  // baudrate
23
  enum { CAN_BAUDRATE_100K, CAN_BAUDRATE_125K, CAN_BAUDRATE_200K,
24
         CAN_BAUDRATE_250K, CAN_BAUDRATE_500K, CAN_BAUDRATE_1000K };
25
26
  // "hauptfunktionen"
27
  int can_init(uint8_t baudrate, uint8_t intmode, uint8_t eid);
28
  int can_deinit(void);
29
  int can_enable_mob(uint8_t mob, uint8_t mode, uint32_t id, uint32_t idm);
30
  int can_disable_mob(uint8_t mob);
31
  int can_send_data(uint8_t mob, uint8_t length, int8_t * data);
32
  int can_send_remote(uint8_t mob);
33
  void can_set_autoreply(uint8_t mob, uint8_t length, int8_t *buf);
34
35
  volatile uint8_t inbox[15][8]; // Inbox auf die uebergreifend zugegriffen werden kann
36
37
  // sonstige hilfsfunktionen
38
  int can_set_baudrate(uint8_t baudrate);
39
  int can_set_interrupt(uint8_t mode);
40
  void can_get_mob(uint8_t mob);
41
  uint32_t can_get_id(void);
42
  void can_set_id_mask(uint32_t idm);
43
  void can_set_id(uint32_t id);
44
  int can_set_mode(uint8_t mode);
45
  uint8_t can_get_mode(void);
46
  void can_set_data(uint8_t length, int8_t * data);
47
  void can_get_data(int8_t *msg);
48
  void can_set_mob_interrupt(uint8_t object);
49
  void can_clear_mob_interrupt(uint8_t mob);
50
  uint8_t can_get_mob_interrupt(void);
51
52
#endif /* CAN_H */

can.c
1
#include "can.h"
2
3
#include <avr/io.h>
4
#include <avr/interrupt.h>
5
#include <util/delay.h>  
6
#include <inttypes.h>
7
#include <stdbool.h>
8
9
10
int8_t iemob[15] = {
11
  IEMOB0, IEMOB1, IEMOB2,  IEMOB3,  IEMOB4,  IEMOB5,  IEMOB6, IEMOB7,
12
  IEMOB8, IEMOB9, IEMOB10, IEMOB11, IEMOB12, IEMOB13, IEMOB14 };
13
14
15
// extended id
16
int8_t extended_id;
17
18
// Message Objects zuruecksetzen, CAN-Controller aktivieren
19
// Parameter:
20
//   uint8_t baud: 0,1,2...5 (fuer 100, 125, 200, 250, 500, 1000)
21
//   uint8_t intmode: Ereignis, bei dem ein Interrupt ausgelöst werden soll
22
//     - NONE  - Deaktiviert
23
//     - TX    - Daten gesendet
24
//     - RX    - Daten empfangen
25
//     - TXRX  - Daten gesendet und/oder empfangen
26
int can_init(uint8_t baudrate, uint8_t intmode, uint8_t eid)
27
{
28
  uint8_t i;
29
30
  extended_id = eid ? 1 : 0;
31
32
  // Status- und Steuerregister aller Message Objects initialisieren
33
  for(i = 0; i < NO_MOBS; i++)
34
  {
35
    can_get_mob(i);
36
    CANSTMOB = 0;
37
    CANCDMOB = 0;
38
  }
39
40
  // set baudrate
41
  if(can_set_baudrate(baudrate) == 0)
42
    return 0;
43
44
  if(can_set_interrupt(intmode) == 0)
45
    return 0;
46
47
  // CAN-Controller in Enabled Mode setzen
48
  setbit(CANGCON, ENASTB);
49
50
  // Warten bis der CAN-Controller das Enabled-Bit gesetzt hat und
51
  // einsatzbereit ist
52
  while (!getbit(CANGSTA, ENFG));
53
54
  return 1; 
55
}
56
57
int can_deinit(void)
58
{
59
  uint8_t i;
60
61
  for(i = 0; i < 15; i++)
62
    can_disable_mob(i);
63
64
  // CAN-Controller ausschalten
65
  clearbit(CANGCON, ENASTB);
66
67
  // warten bis wirklich ausgechaltet
68
  while (getbit(CANGSTA, ENFG));
69
70
  return 1;
71
}
72
73
void can_set_autoreply(uint8_t mob, uint8_t length, int8_t *buf)
74
{
75
  can_get_mob(mob);
76
  can_set_mode(CAN_MODE_AUTO_REPLY);
77
  can_set_data(length, buf);
78
}
79
80
int can_set_baudrate(uint8_t baudrate)
81
{
82
  // @16 MHz
83
  switch(baudrate)
84
  {
85
    case CAN_BAUDRATE_100K:
86
      CANBT1 = 0x12;
87
      CANBT2 = 0x0c;
88
      CANBT3 = 0x37;
89
      break;
90
91
    case CAN_BAUDRATE_125K:
92
      CANBT1 = 0x0e;
93
      CANBT2 = 0x0c;
94
      CANBT3 = 0x37;
95
      break;
96
97
    case CAN_BAUDRATE_200K:
98
      CANBT1 = 0x08;
99
      CANBT2 = 0x0c;
100
      CANBT3 = 0x37;
101
      break;
102
103
    case CAN_BAUDRATE_250K:
104
      CANBT1 = 0x06;
105
      CANBT2 = 0x0c;
106
      CANBT3 = 0x37;
107
      break;
108
109
    case CAN_BAUDRATE_500K:
110
      CANBT1 = 0x02;
111
      CANBT2 = 0x0c;
112
      CANBT3 = 0x37;
113
      break;
114
115
    case CAN_BAUDRATE_1000K:
116
      CANBT1 = 0x00;
117
      CANBT2 = 0x0c;
118
      CANBT3 = 0x37;
119
      break;
120
121
    default:
122
      return 0;
123
  }
124
125
  return 1;
126
}
127
128
// Parameter:
129
//   uint8_t mob: Nummer des zu wählenden Objekts (0-14)
130
//
131
//   uint8_t mode
132
//     - Betriebsart des Message Objekts:
133
//     - DISABLED         Deaktiviert
134
//     - TRANSMIT_DATA    Daten senden
135
//     - TRANSMIT_REMOTE  Anfrage senden
136
//     - RECEIVE_DATA     Empfangsmodus
137
//     - AUTO_REPLY       automatischer Antwortmodus
138
//
139
// Funktion setzt die Betriebsart des vorher gewählten Objekts
140
int can_enable_mob(uint8_t mob, uint8_t mode, uint32_t id, uint32_t idm)
141
{
142
  // Objekt wählen
143
  can_get_mob(mob);
144
145
  // Interrupt für dieses Objekt aktivieren
146
  can_set_mob_interrupt(mob);
147
148
  // ID-Maske setzen
149
  can_set_id_mask(idm);
150
151
  // ID setzen
152
  can_set_id(id);
153
154
  // Betriebsmodus setzen
155
  if(can_set_mode(mode) == 0)
156
    return 0;
157
158
  return 1;
159
}
160
161
162
int can_send_data(uint8_t mob, uint8_t length, int8_t * data)
163
{
164
  uint8_t mode;
165
166
  // Objekt wählen
167
  can_get_mob(mob);
168
  
169
  // Aktuelle Betriebsart sichern
170
  mode = can_get_mode();
171
172
  // Nutzdaten in Register schreiben
173
  can_set_data(length, data);
174
175
  // Datenübertragung starten
176
  can_set_mode(CAN_MODE_TRANSMIT_DATA);
177
178
  // Warten bis die Datenübertragung beendet ist (TXOK-Flag von CAN-Controller
179
  // gesetzt)
180
  while (!getbit(CANSTMOB, TXOK));      
181
182
  // TXOK-Flag von Hand löschen
183
  clearbit(CANSTMOB, TXOK);
184
185
  // Alte Betriebsart wiederherstellen
186
  can_set_mode(mode);
187
188
  return 1;
189
}
190
191
192
// Parameter: uint8_t mode: Ereignis, bei dem Interrupt ausgelöst werden soll
193
//   - NONE  - Deaktiviert
194
//   - TX    - Daten gesendet
195
//   - RX    - Daten empfangen
196
//   - TXRX  - Daten gesendet und/oder empfangen
197
int can_set_interrupt(uint8_t mode)
198
{
199
  switch(mode)
200
  {
201
    case CAN_INTERRUPT_NONE:
202
      clearbit(CANGIE, ENIT);
203
      clearbit(CANGIE, ENRX);
204
      clearbit(CANGIE, ENTX);
205
      break;
206
207
    case CAN_INTERRUPT_TX:
208
      setbit(CANGIE, ENIT);
209
      clearbit(CANGIE, ENRX);
210
      setbit(CANGIE, ENTX);
211
      break;
212
213
    case CAN_INTERRUPT_RX:
214
      setbit(CANGIE, ENIT);
215
      setbit(CANGIE, ENRX);
216
      clearbit(CANGIE, ENTX);
217
      break;
218
219
    case CAN_INTERRUPT_TXRX:
220
      setbit(CANGIE, ENIT);
221
      setbit(CANGIE, ENRX);
222
      setbit(CANGIE, ENTX);
223
      break;
224
225
    default:
226
      return 0;
227
  }
228
229
  return 1;
230
}
231
232
233
// Funktion wählt CANPAGE des betreffenden Objekts aus und stellt Zugang zu
234
// Registern des Objekts her
235
void can_get_mob(uint8_t mob)
236
{
237
  CANPAGE = (mob << 4);
238
}
239
240
  
241
// Parameter: uint32_t idm: ID-Maske in Dezimalschreibweise
242
// Funktion setzt ID-Maske eines Objekts auf einen neuen Wert. In CANIDM4
243
// bleiben dabei die Werte der unteren 3 Bit (RTRTAG, Reserved und IDEMSK)
244
// erhalten.
245
void can_set_id_mask(uint32_t idm)
246
{
247
  //Standart identifier (11 bit)
248
  if(!extended_id)
249
  {
250
    CANIDM2 = (uint8_t)(idm << 5); 
251
    CANIDM1 = (uint8_t)(idm >> 3);
252
  }
253
  //extended identifier
254
  else
255
  {
256
    idm <<= 3;
257
    idm  |= 7;
258
259
    CANIDM4 = (int8_t) (idm);
260
    CANIDM3 = (int8_t) (idm>>8);
261
    CANIDM2 = (int8_t) (idm>>16);
262
    CANIDM1 = (int8_t) (idm>>24);
263
  }
264
}
265
266
// Funktion holt ID der empfangenen Nachricht
267
uint32_t can_get_id(void)
268
{
269
  uint32_t id = 0;
270
271
  //Standart identifier (11 bit)
272
  if(!extended_id)
273
  {
274
    id  = (uint8_t)  CANIDT2 >> 5;
275
    id |= (uint16_t) CANIDT1 << 3;
276
  }
277
  //extended identifier
278
  else
279
  {
280
    id |= ((uint32_t) CANIDT1 << 24);
281
    id |= ((uint32_t) CANIDT2 << 16);
282
    id |= ((uint32_t) CANIDT3 << 8);
283
    id |= (CANIDT4&0xF8);
284
    id >>= 3;
285
  }
286
287
  return id;
288
}
289
290
// Funktion setzt ID eines Objekts auf einen neuen Wert. In CANIDM4 bleiben
291
// dabei die Werte der unteren 3 Bit (RTRTAG, RB1TAG und RB0TAG) erhalten.
292
void can_set_id(uint32_t id)
293
{
294
  //Standart identifier (11 bit)
295
  if(!extended_id)
296
  {
297
    CANIDT2 = (uint8_t)(id << 5); 
298
    CANIDT1 = (uint8_t)(id >> 3);
299
  }
300
  //extended identifier
301
  else
302
  {
303
    id <<= 3;
304
    id &= 0xfffffff8;
305
    id |= (CANIDT4 & 0x07);
306
307
    CANIDT4 = (int8_t) (id);
308
    CANIDT3 = (int8_t) (id>>8);
309
    CANIDT2 = (int8_t) (id>>16);
310
    CANIDT1 = (int8_t) (id>>24);
311
  }
312
}
313
314
315
// Funktion setzt die Betriebsart des vorher gewählten Objekts.
316
// Parameter: uint8_t mode:
317
//   - Betriebsart des Message Objekts:
318
//   - DISABLED        - Deaktiviert
319
//   - TRANSMIT_DATA   - Daten senden
320
//   - TRANSMIT_REMOTE - Anfrage senden
321
//   - RECEIVE_DATA    - Empfangsmodus
322
//   - AUTO_REPLY      - automatischer Antwortmodus
323
int can_set_mode(uint8_t mode)
324
{
325
  if(extended_id)
326
    setbit(CANCDMOB, IDE);
327
  else
328
    clearbit(CANCDMOB, IDE);
329
330
  switch(mode)
331
  {
332
    case CAN_MODE_DISABLED:
333
      clearbit(CANCDMOB, CONMOB0);
334
      clearbit(CANCDMOB, CONMOB1);
335
      clearbit(CANCDMOB, RPLV);
336
      clearbit(CANIDT4, RTRTAG);
337
      clearbit(CANIDM4, RTRMSK);
338
      break;
339
340
    case CAN_MODE_TRANSMIT_DATA:
341
      setbit(CANCDMOB, CONMOB0);
342
      clearbit(CANCDMOB, CONMOB1);
343
      clearbit(CANCDMOB, RPLV);
344
      clearbit(CANIDT4, RTRTAG);
345
      break;
346
347
    case CAN_MODE_TRANSMIT_REMOTE:
348
      clearbit(CANCDMOB, CONMOB1);
349
      setbit(CANCDMOB, CONMOB0);
350
      clearbit(CANCDMOB, RPLV);
351
      setbit(CANIDT4, RTRTAG);
352
      break;
353
354
    case CAN_MODE_RECEIVE_DATA:
355
      clearbit(CANCDMOB, CONMOB0);
356
      setbit(CANCDMOB, CONMOB1);
357
      clearbit(CANCDMOB, RPLV);
358
      clearbit(CANIDT4, RTRTAG);
359
      break;
360
361
    case CAN_MODE_AUTO_REPLY:
362
      clearbit(CANCDMOB, CONMOB0);
363
      setbit(CANCDMOB, CONMOB1);
364
      setbit(CANCDMOB, RPLV);
365
      setbit(CANIDT4, RTRTAG);
366
      break;
367
368
    default:
369
      return 0;
370
  }
371
372
  return 1;
373
}
374
375
376
// Funktion holt die Betriebsart des vorher gewaehlten Objekts
377
uint8_t can_get_mode(void)
378
{
379
  uint8_t mode = 0;
380
381
  if(!getbit(CANCDMOB, CONMOB1) && !getbit(CANCDMOB, CONMOB0))
382
  {
383
    mode = CAN_MODE_DISABLED;
384
  }
385
  else if(!getbit(CANCDMOB, CONMOB1) && getbit(CANCDMOB, CONMOB0) &&
386
    !getbit(CANIDT4, RTRTAG))
387
  {
388
    mode = CAN_MODE_TRANSMIT_DATA;
389
  }
390
  else if(!getbit(CANCDMOB, CONMOB1) && getbit(CANCDMOB, CONMOB0) &&
391
    getbit(CANIDT4, RTRTAG))
392
  {
393
    mode = CAN_MODE_TRANSMIT_REMOTE;
394
  }
395
  else if(getbit(CANCDMOB, CONMOB1) && !getbit(CANCDMOB, CONMOB0) &&
396
    !getbit(CANIDT4, RTRTAG))
397
  {
398
    mode = CAN_MODE_RECEIVE_DATA;
399
  }
400
  else if(getbit(CANCDMOB, CONMOB1) && !getbit(CANCDMOB, CONMOB0) &&
401
    getbit(CANCDMOB,RPLV) && getbit(CANIDT4, RTRTAG))
402
  {
403
    mode = CAN_MODE_AUTO_REPLY;
404
  }
405
406
  return mode;
407
}
408
409
410
// Funktion schreibt in das Objekt die zu uebermittelnden Daten
411
void can_set_data(uint8_t length, int8_t * data)
412
{
413
  uint8_t i;
414
  uint8_t cancdmob;
415
416
  if(length > 8)
417
    length = 8;
418
419
  // Anzahl der Datenbytes in der Nachricht
420
  // scheinbar darf man das CANCDMOB register nicht beliebig oft
421
  // schreiben/lesen, daher speichern wir den wert dazwischen, loeschen die
422
  // entsprechenden bits fuer die laenge und schreiben dann usere laenge rein
423
  // wie dem auch sei: so funktionierts zumindest, also vorsicht beim aufraeumen ;-)
424
  cancdmob = CANCDMOB;
425
  clearbit(cancdmob, DLC0);
426
  clearbit(cancdmob, DLC1);
427
  clearbit(cancdmob, DLC2);
428
  clearbit(cancdmob, DLC3);
429
  CANCDMOB = (cancdmob | (length << DLC0));
430
  for(i = 0; i < length; i++)
431
    CANMSG = data[i];
432
}
433
434
void can_get_data(int8_t *msg)
435
{
436
  uint8_t i;
437
438
  for(i = 0; i < 8; i++)
439
    msg[i] = CANMSG;
440
}
441
442
// Parameter: uint8_t mob: Nummer des Objekts (0-14)
443
// Funktion setzt den Interrupt für das jeweilige Objekt
444
void can_set_mob_interrupt(uint8_t mob)
445
{
446
  setbit(CANIE2, iemob[mob]);
447
}
448
449
// Parameter: uint8_t mob: Nummer des Objekts (0-14)
450
// Funktion löscht den Interrupt für das jeweilige Objekt
451
void can_clear_mob_interrupt(uint8_t mob)
452
{
453
  clearbit(CANIE2, iemob[mob]);
454
}
455
456
// Rückgabe: uint8_t mob: Nummer des Objekts
457
// Funktion ermittelt, welches Objekt Interrupt ausgeloest hat
458
uint8_t can_get_mob_interrupt(void)
459
{
460
  uint8_t  mob;
461
  uint16_t maske;
462
  maske = CANSIT2 | (CANSIT1 << 8);
463
464
  // Wenn alle 32 Bit der Bitmaske 0 sind dann ist ein Fehler aufgetreten
465
  if(maske == 0)
466
    return NOMOB;
467
468
  // Die Bitmaske wird so lange nach rechts geschoben, bis Bit0 eine 1 hat.
469
  // Die Anzahl der Schiebeoperatoren gibt somit die Nummer des MOBs zurück
470
  for(mob=0; (maske & 0x01)==0; maske >>= 1, ++mob);
471
472
  // Kontrolle: Wenn mob größer als die Anzahl der verfügbaren
473
  // Message Objects ist das Ergebnis falsch
474
  if(mob > 14)
475
    return NOMOB;
476
477
  return mob;
478
}
479
480
481
// Funktion deaktiviert das gewählte Objekt
482
int can_disable_mob(uint8_t mob)
483
{
484
  // Objekt wählen
485
  can_get_mob(mob);
486
487
  // Interrupt für dieses Objekt aktivieren
488
  can_clear_mob_interrupt(mob);
489
490
  // Betriebsmodus setzen
491
  can_set_mode(CAN_MODE_DISABLED);
492
493
  return 1;
494
}
495
496
497
// Funktion sendet eine Anfrage (Remote Frame)
498
int can_send_remote(uint8_t mob)
499
{
500
  uint8_t mode;
501
502
  // Objekt wählen
503
  can_get_mob(mob);
504
  
505
  // Aktuelle Betriebsart sichern
506
  mode = can_get_mode();
507
508
  // Datenübertragung starten
509
  can_set_mode(CAN_MODE_TRANSMIT_REMOTE);
510
511
  // Warten bis die Datenübertragung beendet ist (TXOK-Flag von CAN-Controller
512
  // gesetzt)
513
  while (!getbit(CANSTMOB, TXOK));      
514
515
  // TXOK-Flag von Hand löschen
516
  clearbit(CANSTMOB, TXOK);
517
518
  // Alte Betriebsart wiederherstellen
519
  can_set_mode(mode);
520
521
  return 1;
522
}
523
524
525
// Interrupt fuer Empfang einer Nachricht
526
SIGNAL(SIG_CAN_INTERRUPT1)
527
{
528
  uint8_t save_canpage;
529
  uint8_t mob;
530
  uint8_t i;
531
  // Aktuelle CANPAGE sichern
532
  save_canpage = CANPAGE;
533
534
  // Index des MOB ermitteln, der den Interrupt ausgelöst hat
535
  mob = can_get_mob_interrupt();
536
    
537
  // Falls es kein gültiges MOB war abbrechen
538
  if(mob == NOMOB)
539
    return;
540
541
  // Objekt das den Interrupt ausgelöst hat holen
542
  can_get_mob(mob);
543
  
544
  // XXX hier eintragen, was bei einem interrupt passieren soll XXX
545
  // Id der Nachricht holen und Daten des MOBs aus CANMSG auslesen
546
  //id = can_get_id();
547
  
548
   for(i = 0; i < 8; i++)
549
    inbox[mob][i] = CANMSG;
550
551
  // RXOK-Flag löschen
552
  clearbit(CANSTMOB, RXOK);
553
    
554
  // MOB auf Empfang und CAN 2.0B Standard setzen
555
  can_set_mode(CAN_MODE_RECEIVE_DATA);
556
    
557
  // CANPAGE wiederherstellen
558
  CANPAGE = save_canpage;
559
}

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.