Forum: Mikrocontroller und Digitale Elektronik AT90CAN64 Fehler beim senden


von Florian (Gast)


Lesenswert?

Hallo,
ich versuche derzeit einen AT90CAN64 zur programmieren.
Das Programm liest einen ADC über die SPI aus und speichert die Daten in 
einen Buffer.
Wenn ein Receive Interrupt vom CAN bus ausgelöst wird, soll er diesen 
Buffer über den CAN bus an den rechner senden.
Die CAN Nachrichten sind dabei 4 Byte lang. Erstes Byte steht für die 
Kanalnummer, Zweites und drittes Byte für die ADC Daten und das vierte 
Byte ist eine 8-bit LRC.

Das Problem dabei: Bei der letzten Nachricht ist immer das 1te Byte 0 
ist, obwohl im CANMSG register der richtige Wert steht. Es ist auch egal 
ob ich nur 1 Nachricht schicke, oder mittels for-Schleife alle 64 
Nachrichten hintereinander. Jedesmal ist bei der letzten Nachricht das 1 
Byte eine 0.

Hier Auszüge aus meinem Code:
1
volatile uint16_t id_tag = 0x068F;
2
volatile uint16_t adc_data_buffer[64];
3
4
ISR(CANIT_vect)
5
{
6
  cli();
7
8
  uint8_t rx_data[8];
9
  uint16_t meanValue = 0;
10
  uint8_t channel;
11
  uint8_t rx_dlc = CANCDMOB & ((1<<DLC3)|(1<<DLC2)|(1<<DLC1)|(1<<DLC0));
12
13
  CANPAGE = CANHPMOB & 0xF0;
14
  for (uint8_t data_index = 0; data_index < rx_dlc; data_index++)
15
    *(rx_data + data_index) = CANMSG;
16
17
  can_clear_mob();
18
19
  switch(rx_data[0]){
20
  case (1):
21
    for (int i=0; i<64; i++)
22
      txCan(adc_data_buffer[i], i);
23
    break;
24
25
  case (2):
26
    if (rx_data[1] >= 64){ // --- invalid channel number
27
      channel = 0xE2;
28
      meanValue = 0;
29
    }
30
    else {
31
      channel = rx_data[1];
32
      meanValue = adc_data_buffer[channel];
33
    }
34
    txCan(meanValue, channel);
35
    break;
36
37
  } // switch (rx_data[0])    
38
39
  rxCan();
40
  sei();
41
}
42
43
void rxCan(void)
44
{
45
  can_msg rx_data_msg;
46
  
47
  rx_data_msg.status = 0;
48
  rx_data_msg.ext = 0;              // CAN 2.0A
49
  rx_data_msg.id = id_tag;          // CAN Identifier
50
  rx_data_msg.dlc = 2;              // Data Length
51
  rx_data_msg.cmd = RX_DATA_MASKED; // Receive Data frame
52
  
53
  // --- use first free MOb
54
  // --- if no MOb is available wait for one
55
  rx_data_msg.handle = 0x00;
56
57
  can_config_mob(&rx_data_msg);
58
}
59
60
void txCan(uint16_t tx_data, uint8_t channel)
61
{
62
  can_msg tx_data_msg;
63
  uint8_t tx_data_buffer[4];
64
  uint8_t chk = 0;
65
66
  tx_data_buffer[0] = channel;
67
  tx_data_buffer[1] = (uint8_t)(tx_data >> 8);
68
  tx_data_buffer[2] = (uint8_t)(tx_data);
69
70
  // --- calculate 8-bit LRC
71
  for (int i=0; i<3; i++)
72
    chk = chk^tx_data_buffer[i];
73
  tx_data_buffer[3] = chk;
74
75
  tx_data_msg.status = 0;
76
  tx_data_msg.pt_data = tx_data_buffer;
77
  tx_data_msg.ext = 0;        // CAN 2.0A
78
  tx_data_msg.id = id_tag;    // CAN Identifier
79
  tx_data_msg.dlc = 4;        // Data Length
80
  tx_data_msg.cmd = TX_DATA;  // Transmit
81
82
  // --- use first free MOb
83
  // --- if no MOb is available wait for one
84
  tx_data_msg.handle = can_get_free_mob();
85
  while(tx_data_msg.handle == NO_MOB)
86
    tx_data_msg.handle = can_get_free_mob_ext();
87
88
  can_config_mob(&tx_data_msg);
89
}
90
91
void can_clear_mob(void)
92
{
93
  // --- Set all MOb registers to 0
94
  CANIDM4 = 0x00; CANIDM3 = 0x00; CANIDM2 = 0x00; CANIDM1 = 0x00;
95
  CANIDT4 = 0x00; CANIDT3 = 0x00; CANIDT2 = 0x00; CANIDT1 = 0x00;
96
  CANSTMOB=0x00;
97
  CANCDMOB = 0;
98
  for (int num_data = 0; num_data < 8; num_data++)
99
    CANMSG = 0;
100
}
101
102
void can_config_mob (can_msg* mob_conf)
103
{
104
  CANPAGE = (mob_conf->handle << 4);
105
  can_clear_mob();   // to be sure MOb is cleared
106
107
  switch(mob_conf->cmd){
108
109
  case TX_DATA:    
110
    can_set_id(mob_conf->ext, mob_conf->id);
111
    for (int cpt=0; cpt<mob_conf->dlc; cpt++)
112
      CANMSG = *(mob_conf->pt_data + cpt);    
113
    CANCDMOB |= (mob_conf->dlc);
114
    CANCDMOB |= (1  << CONMOB0); }    
115
    break;
116
117
  case RX_DATA_MASKED:
118
    can_set_id(mob_conf->ext, mob_conf->id);
119
    CANIDM4=0xFD; CANIDM3=0xFF; CANIDM2=0xFF; CANIDM1=0xFF;
120
    CANIDT4  &= ~(1<<RTRTAG)
121
    CANCDMOB |= (mob_conf->dlc);
122
    CANCDMOB |= (2  << CONMOB0); }
123
    break;
124
}

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.