Can-Bus mehrere Bytes hintereinander senden

OP #2653296
Lesenswert?

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
OP #2653579
Lesenswert?

Das Datenblatt Akker ich schon seit 2 Stunden durch, gott hat das teil 
viele register.....aber Interrups und so interessieren mich ja erstmal 
nicht.

Den wert vom dlc kann ich ja selber festlegen.

Wie soll ich mir da denn nen array reinstopfen? das Register "CANMSG" 
hat ja nur 8Bit.

Wenn ich also den DLC auf "2" stelle, hät ich ja 16Bit...wo bleibt die 
andere Hälfte, wer sagt mir denn wann welche Daten im CANMSG stehen.
Die letzen 8 Bit stehen ja drin....

Hat das was mit den "Pages" zu tun? Das kapier ich nämlich noch nicht ^^
Gast #2660040
Lesenswert?

Alexander G. schrieb:
> Wie soll ich mir da denn nen array reinstopfen? das Register "CANMSG"
>
> hat ja nur 8Bit.
>
>
>
> Wenn ich also den DLC auf "2" stelle, hät ich ja 16Bit...wo bleibt die
>
> andere Hälfte, wer sagt mir denn wann welche Daten im CANMSG stehen.
>
> Die letzen 8 Bit stehen ja drin....



Alexander G. schrieb:

unit8 var[8];

> for(j=0;j<=8;j++)
>
>       {
>
>          CANMSG=0;        //Autoincrement aktiv

/* so einfach geht das Auslesen. */
           var[j] = CANMSG;

>
>       }

Allerdings muß das AINC - BIt im CANPAGE auf logisch 0 sein.

Viel Erfolg

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren