Hallo,
ich nutze den Atmega64M1 um Nachrichten auf den Bus zu senden/empfangen.
Dies funktioniert auch soweit, allerdings springt nach dem Senden einer
Nachricht die ISR nicht an, obwohl ich das entsprechende Bit gesetzt
habe (ENTX in CANGIE). Senden kann ich aber trotzdem mehrere Nachrichten
hintereinander.
Anders als bei erfolgreichem Empfang einer Nachricht. Hier springt die
IRS an. Mehrere Nachrichten hintereinander empfangen ist kein Problem.
Kann jemand sagen, was ich falsch mache?
Nochmal was ich will: Nachricht senden und dann soll die IRS
CAN_INT_vect starten ausgelöst durch TXOK Bit.
Eigentlich dachte ich, ich könne mit folgendem Code prüfen, ob
erfolgreich gesendet wurde und entsprechend die Register zurücksetzen:
1 | ISR (CAN_INT_vect)
|
2 | {
|
3 | if(CANSTMOB & (1 << TXOK))
|
4 | {
|
5 | CANCDMOB = 0x00; // Disable Transmission
|
6 | CANSTMOB = 0x00; // Clear TXOK flag
|
7 | // CANSTMOB &= ~(1 << TXOK); // clear interrupt flag
|
8 | }
|
9 | }
|
Hier zum einen meine Initialisierung:
1 | void can_init(void){
|
2 |
|
3 | CANGCON = ( 1 << SWRES ); // Software reset
|
4 | CANTCON = 0x00; // CAN timing prescaler set to 0;
|
5 |
|
6 | // Aus EEPROM
|
7 | CANBT1 = geraetedaten_info[5]; // 500kb/s
|
8 | CANBT2 = geraetedaten_info[6]; // http://www.bittiming.can-wiki.info/
|
9 | CANBT3 = geraetedaten_info[7]; //
|
10 |
|
11 | for ( anzahl = 0; anzahl < 3; anzahl++ )
|
12 | {
|
13 | // TX
|
14 | // Mob 0 bis 2 werden als Tx genutzt
|
15 |
|
16 | CANPAGE = ( anzahl << MOBNB0 ); // Selects Message Object 0-2
|
17 | CANCDMOB = 0x00; // Disable mob
|
18 | CANSTMOB = 0x00; // Clear mob status register;
|
19 |
|
20 | // TAG
|
21 | CANIDT4 = 0x00;
|
22 | CANIDT3 = 0x00;
|
23 | CANIDT2 = 0x00;
|
24 | CANIDT1 = 0b0000000;
|
25 |
|
26 | // MASK
|
27 | CANIDM4 = 0x00;
|
28 | CANIDM3 = 0x00;
|
29 | CANIDM2 = 0x00;
|
30 | CANIDM1 = 0b00000000;
|
31 | }
|
32 |
|
33 |
|
34 | for ( anzahl = 3; anzahl < 6; anzahl++ )
|
35 | {
|
36 | // RX
|
37 | // Mob 3 bis 5 werden als RX genutzt
|
38 | CANPAGE = ( anzahl << MOBNB0 ); // Selects Message Object 3-5
|
39 | CANCDMOB = 0x00; // Disable mob
|
40 | CANSTMOB = 0x00; // Clear mob status register;
|
41 |
|
42 | // TAG
|
43 | CANIDT4 = 0x00;
|
44 | CANIDT3 = 0x00;
|
45 | CANIDT2 = 0x00;
|
46 | CANIDT1 = 0b00010000;
|
47 |
|
48 | // MASK
|
49 | CANIDM4 = 0x01; // IDEMSK = 1
|
50 | CANIDM3 = 0x00;
|
51 | CANIDM2 = 0x00;
|
52 | CANIDM1 = 0b11110000;
|
53 |
|
54 | CANCDMOB = ( 1 << CONMOB1) | ( 1 << IDE ) | ( 8 << DLC0); // Enable Reception 29 bit IDE DLC8
|
55 | }
|
56 |
|
57 | CANGIE = ( 1 << ENIT ) | ( 1 << ENRX ) | ( 1 << ENTX ); // ( 1 << ENIT ) | ( 1 << ENBOFF) | ( 1 << ENRX ) | ( 1 << ENTX ) | (1 << ENERR) | (1 << ENBX) | (1 << ENERG);
|
58 | CANIE1 = 0xFF;
|
59 | CANIE2 = (1<<IEMOB5) | (1<<IEMOB4) | (1<<IEMOB3) | (1<<IEMOB2) | (1<<IEMOB1) | (1<<IEMOB0); // Enable interrupts on all MObs
|
60 |
|
61 | CANGIT = 0xff; // RESET aller Interrupt Flags
|
62 | CAN_ENABLE; // Enable mode. CAN channel enters in enable mode once 11 recessive bits have been read
|
63 | }
|
Zum anderen die Funktion, mit der ich sende:
1 | void can_tx (uint8_t dlc, uint8_t bl_befehl, uint8_t * tx_data)
|
2 | {
|
3 |
|
4 | for (select_free_mob = 0; select_free_mob < 3; select_free_mob++)
|
5 | {
|
6 | if (!(CANEN2 & (1 << select_free_mob)))
|
7 | {
|
8 | break;
|
9 | }
|
10 | }
|
11 |
|
12 | CANPAGE = select_free_mob << MOBNB0; // Select MOb0 for transmission
|
13 | CANSTMOB = 0x00; // Clear mob status register
|
14 |
|
15 | // CAN ID setzen:
|
16 | CANIDT1 = SEKTION_BL << 4 | (geraete_id >> 5);
|
17 | CANIDT2 = (geraete_id << 3) | bl_befehl;
|
18 | CANIDT3 = (BL_VERSION << 3) | (geraetedaten_info[3] >> 5);
|
19 | CANIDT4 = geraetedaten_info[3] << 3;
|
20 |
|
21 | // Nachrichten
|
22 | for ( uint8_t i = 0; i < dlc; ++i )
|
23 | {
|
24 | CANMSG = tx_data[i];
|
25 | }
|
26 |
|
27 | CANCDMOB = ( 1 << CONMOB0 ) | ( 1 << IDE ) | ( dlc << DLC0 ); // Enable transmission, data length, (CAN Standard rev 2.0B(29 bit identifiers))
|
28 | }
|
Freue mich sehr über Hinweise. Vielen Dank.