Hallo, ich habe hier gerade ein kleines Verständnisproblem mit dem CAN-Bus. Ich habe 2 µC Boards mit Can verbunden. Einer sendet ein Byte und der andere empfängt dies. (Mit Atmel AT90CAN128) Hier mal die Programme: Sender
1 | // Definitionen MOb-Konfiguration
|
2 | #define TX 1
|
3 | #define DLC_1 1
|
4 | #define NO_IDE 0
|
5 | #define NO_Reply 0
|
6 | |
7 | const char info1[]PROGMEM = "CAN_Transmit_Data"; |
8 | const char info2[]PROGMEM = "20kBis/s, ID: 123h"; |
9 | //////////////////////////////////////////////////////////
|
10 | // Funktionen für CAN Initialisierung
|
11 | //////////////////////////////////////////////////////////
|
12 | |
13 | // Löschen der Konfigurationen von MOb0 ... MOb14
|
14 | void CanClearMOB(void) |
15 | {
|
16 | unsigned char i, j; |
17 | for(i=0;i<=14;i++) |
18 | {
|
19 | CANPAGE = (i << 4); // XXXX0000 -> Autoincrement aktiviert |
20 | CANSTMOB = 0; |
21 | CANCDMOB = 0; |
22 | CANIDT4 = 0; |
23 | CANIDT3 = 0; |
24 | CANIDT2 = 0; |
25 | CANIDT1 = 0; |
26 | CANIDM4 = 0; |
27 | CANIDM3 = 0; |
28 | CANIDM2 = 0; |
29 | CANIDM1 = 0; |
30 | for(j=0;j<=8;j++) |
31 | {
|
32 | CANMSG=0; //Autoincrement aktiv |
33 | }
|
34 | }
|
35 | }
|
36 | |
37 | ///////////////////////////////////
|
38 | // CAN-Initialisierungen //
|
39 | ///////////////////////////////////
|
40 | |
41 | void CanInit(void) |
42 | {
|
43 | CanClearMOB(); // Alle MOb's löschen |
44 | |
45 | // Einstellung der Baudrate 20kBit/s
|
46 | CANBT1 = 0x62; // Teiler = 49 |
47 | CANBT2 = 0x0C; // PRS = 7 TQs, PHS1= 7 TQs, PHS2= 7 TQs |
48 | CANBT3 = 0x36; // ==> Sample Point bei 75 % |
49 | |
50 | // Initialisierung MOb1 (Sender)
|
51 | CANPAGE = (1<<MOBNB1); // Selektierung von MOb1 |
52 | //CANPAGE = (1<<MOBNB2); // Selektierung von MOb2
|
53 | CANCDMOB|=1; // 1 Datenbyte senden |
54 | CANCDMOB|=NO_IDE<<4; // Botschaft als Standard Frame |
55 | CANCDMOB|=NO_Reply<<5; |
56 | //CANCDMOB|=TX<<6; // Sendemodus einstellen
|
57 | |
58 | // Initialisierung des Identifier (ID=0x123)
|
59 | CANIDT1 = 0x123 >>3; // Zuweisung ID-Bit 10 - 3 |
60 | CANIDT2 = 0x123 <<5; // Zuweisung ID-Bit 2 - 0 |
61 | |
62 | // CAN Controller aktivieren
|
63 | CANGCON |= 0X02; |
64 | |
65 | //CANMSG =0x35; // Nutzdatenbyte 35h eintragen
|
66 | }
|
67 | |
68 | // Hauptprogramm
|
69 | int main(void) |
70 | {
|
71 | char display_buffer[21]; |
72 | unsigned int i=0; |
73 | unsigned int k=1; |
74 | lcd_init( LCD_DISP_ON ); |
75 | G_DISPLAY = (1<<BELEUCHTUNG); |
76 | lcd_puts_p(info1); //Ausgabe von "ROM-Texten" Überschrift |
77 | lcd_gotoxy(0,1); |
78 | lcd_puts_p(info2); |
79 | CanInit(); // Konfiguration und Sendung der Botschaft |
80 | |
81 | while(1) |
82 | {
|
83 | |
84 | //if(k==1) CANMSG =0x11;
|
85 | //if(k==2) CANMSG =0x22;
|
86 | //if(k==3) CANMSG =0x33;
|
87 | //if(k==4) CANMSG =0x44;
|
88 | //if(k>=5) k=0;
|
89 | |
90 | CANCDMOB = (1 << CONMOB0); // Botschaft abschicken |
91 | |
92 | i++; |
93 | //k++;
|
94 | lcd_gotoxy(0,2); |
95 | sprintf(display_buffer,"Umlauf: %5d",i); |
96 | lcd_puts(display_buffer); |
97 | lcd_gotoxy(0,3); |
98 | sprintf(display_buffer,"Data: %02x",CANMSG); // Kontrolle auf LCD |
99 | lcd_puts(display_buffer); |
100 | _delay_ms(1000); |
101 | }
|
102 | return 0; |
103 | }
|
************Empfänger*************************************************** ***************************************
1 | // Definitionen MOb-Selektierung
|
2 | #define MO_1 1
|
3 | |
4 | // Definitionen MOb-Konfiguration
|
5 | #define RX 2
|
6 | #define DLC_1 1
|
7 | #define NO_IDE 0
|
8 | #define NO_Reply 0
|
9 | |
10 | const char info1[]PROGMEM = "CAN_Receive_Data"; |
11 | const char info2[]PROGMEM = "20kBis/s, ID: 123h"; |
12 | //////////////////////////////////////////////////////////
|
13 | // Funktionen für CAN Initialisierung
|
14 | //////////////////////////////////////////////////////////
|
15 | |
16 | // Löschen der Konfigurationen von MOb0 ... MOb14
|
17 | void CanClearMOB(void) |
18 | {
|
19 | unsigned char i, j; |
20 | for(i=0;i<=14;i++) |
21 | {
|
22 | CANPAGE = (i << 4); // XXXX0000 -> Autoincrement aktiviert |
23 | CANSTMOB = 0; |
24 | CANCDMOB = 0; |
25 | CANIDT4 = 0; |
26 | CANIDT3 = 0; |
27 | CANIDT2 = 0; |
28 | CANIDT1 = 0; |
29 | CANIDM4 = 0; |
30 | CANIDM3 = 0; |
31 | CANIDM2 = 0; |
32 | CANIDM1 = 0; |
33 | for(j=0;j<=8;j++) |
34 | {
|
35 | CANMSG=0; //Autoincrement aktiv |
36 | }
|
37 | }
|
38 | }
|
39 | |
40 | ///////////////////////////////////
|
41 | // CAN-Initialisierungen //
|
42 | ///////////////////////////////////
|
43 | |
44 | void CanInit(void) |
45 | {
|
46 | CanClearMOB(); // Alle MOb's löschen |
47 | |
48 | // Einstellung der Baudrate 20kBit/s
|
49 | CANBT1 = 0x62; // Teiler = 49 |
50 | CANBT2 = 0x0C; // PRS = 7 TQs, PHS1= 7 TQs, PHS2= 7 TQs |
51 | CANBT3 = 0x36; // ==> Sample Point bei 75 % |
52 | |
53 | // Initialisierung MOb1 (Sender)
|
54 | CANPAGE = (MO_1 << 4) | (AINC << 1); // Selektierung von MOb1 |
55 | CANCDMOB|=1; // 1 Datenbyte empfangen |
56 | CANCDMOB|=NO_IDE<<4; // Botschaft als Standard Frame |
57 | CANCDMOB|=NO_Reply<<5; |
58 | CANCDMOB|=RX<<6; // Empfangsmodus einstellen |
59 | |
60 | // Initialisierung des Identifier (ID=0x123)
|
61 | CANIDT1 = 0x123 >>3; // Zuweisung ID-Bit 10 - 3 |
62 | CANIDT2 = 0x123 <<5; // Zuweisung ID-Bit 2 - 0 |
63 | |
64 | // CAN Controller aktivieren
|
65 | CANGCON |= 0X02; |
66 | |
67 | //CANMSG =0x35; // Nutzdatenbyte 35h eintragen
|
68 | }
|
69 | |
70 | // Hauptprogramm
|
71 | int main(void) |
72 | {
|
73 | char display_buffer[21]; |
74 | unsigned int i=0; |
75 | unsigned char data=0; |
76 | lcd_init( LCD_DISP_ON ); |
77 | G_DISPLAY = (1<<BELEUCHTUNG); |
78 | lcd_puts_p(info1); //Ausgabe von "ROM-Texten" Überschrift |
79 | lcd_gotoxy(0,1); |
80 | lcd_puts_p(info2); |
81 | CanInit(); // Konfiguration und Sendung der Botschaft |
82 | |
83 | while(1){ |
84 | CANPAGE = (MO_1 << 4); // Selektierung von MOb1 |
85 | if(CANSTMOB & 0X20){ // nur wenn Botschaft vorhanden |
86 | i++; |
87 | lcd_gotoxy(0,2); // Anzahl der empfangenen Botschaften |
88 | sprintf(display_buffer,"Anz: %5d",i); |
89 | lcd_puts(display_buffer); |
90 | data=CANMSG; |
91 | lcd_gotoxy(0,3); |
92 | sprintf(display_buffer,"Data: %02X ",data); // Botschaftsinhalt |
93 | lcd_puts(display_buffer); |
94 | CANSTMOB=0X00; //MO-Status löschen |
95 | CANCDMOB|=RX<<6; // Empfangsmodus einstellen |
96 | |
97 | }
|
98 | else{ |
99 | if(i==0){ |
100 | lcd_gotoxy(0,3); |
101 | lcd_puts("Keine Daten auf BUS!"); |
102 | }
|
103 | }
|
104 | }
|
105 | return 0; |
106 | }
|
(Habe die includes hier weggelassen) Ein Byte zu senden ist soweit kein Problem. Aber mehr geht nicht... Im Register CANCDMOB (CAN MOb Control and DLC Register)kann mit den Bits DLC3:0 festgelegt werden wie viele Bytes übertragen werden. Aber ich weiss nicht wie ich damit umgehen soll. Im Empfänger Programm habe ich wie man sieht eine Abfrage eingebaut, das er jede Sekunde ein andres Byte sendet (ausgeklammert). Von diesen wird am Empfänger jedoch nur das Letzte Byte wiedergegeben. Als wenn er Empfänger sagt, "nö ich nehm nur den letzen egal was du tust"... Wenn ich in dem Register die Byte Anzahl erhöhe, hab ich dann EINEN längeren Wert`? Also zum 16Bit oder werden die Bytes nacheinander auf die einzelnen Objektregister geschrieben oder wie läuft das ab? Mein Plan war es zum ausprobieren, mal eben ein Paar Bytes hintereinander zu verschicken. Ging beim TWI ja auch...Tja aber falsch gedacht :D Ich hoffe es hat jemand einen Tipp für mich...aber keine Komplettlösung bitte.... Gruß Alexander