Forum: Mikrocontroller und Digitale Elektronik Probleme mit falschen Daten bei TWI


von Benjamin W. (baumwolli)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich verzweifel langsam an TWI. Ich versuche eine Kommunikation zwischen 
einem Raspberry (Master) und einem Atmega8 (Slave) auf 12Mhz zu 
realisieren. Habe dafür die Variante von jtronics adoptiert.
Ich möchte aber mehrere Kommandos verarbeiten können und die Daten je 
nach erhaltenen Kommando im Buffer aufbereiten (siehe IO.rar).
Und genau das scheint das Problem zu sein. Denn die Daten die ich 
erhalte stimmen nicht. Meistens ist das erste Bit des 2ten Bytes 
fehlerhaft.
In meiner Testversion klappt es noch gerade so das ich die richtigen 
Daten erhalte.
Ich vermute das ich den Interrupt zu viel abverlange. Weiß aber leider 
nicht wie ich das umgehen kann.
Vielleicht mache ich aber auch was ganz anderes falsch.
Ich hoffe einer von euch kann mir helfen. Vielen Dank schon mal für eure 
Mühe.

Liebe Grüße Baumwolli

von Christian M. (Gast)


Lesenswert?

Benjamin W. schrieb:
> IO.rar (9,41 KB, 0 Downloads)
> test.rar (6,93 KB, 0 Downloads)

Wie soll ich das mobil öffnen?

Benjamin W. schrieb:
> 12Mhz

MHz! Willst Du nicht mal ein bisschen langsamer probieren? Nach 
Wikipedia ist TWI (I2C) bis 5Mb/s spezifiziert. Habe selber noch nie 
mehr als 100kb/s angewendet.
Schafft das der Atmega überhaupt?

Gruss Chregu

von Stefan F. (Gast)


Lesenswert?

Ein Schaltplan und ein Foto wäre jetzt nicht schlecht, besonders was den 
TWI Bus angeht. Denn oberhalb von 100kHz wird es anspruchsvoll.

von Benjamin W. (baumwolli)


Lesenswert?

Sorry da habe ich mich falsch ausgedrückt. Der atmega läuft auf 12mhz. 
An der twi/i2c Geschwindigkeit habe ich nichts geändert.

von Stefan F. (Gast)


Lesenswert?

> An der twi/i2c Geschwindigkeit habe ich nichts geändert.

Was soll das heißen? Mit irgend einem Wert musst du die Schnittstelle ja 
initialisieren.

Der Default ist FCPU/16, also in deinem Fall fast 1MHz!

von Benjamin W. (baumwolli)


Lesenswert?

Sobald ich wieder zuhause bin werde ich auch den Schaltplan online 
stellen.

von Benjamin W. (baumwolli)


Lesenswert?

Stefan U. schrieb:
>> An der twi/i2c Geschwindigkeit habe ich nichts geändert.
>
> Was soll das heißen? Mit irgend einem Wert musst du die Schnittstelle ja
> initialisieren.
>
> Der Default ist FCPU/16, also in deinem Fall fast 1MHz!

Korrigiere mich wenn ich falsch liege aber gibt der Master nicht den 
takt an? Für den nutze ich einen Raspberry an dem ich nichts weiter 
gemacht habe als i2c zu aktivieren und die python libary zu 
installieren.
Mein python Skript werde ich gleich dann auch online stellen.

von Stefan F. (Gast)


Lesenswert?

Ich denke, da liegst du nicht falsch. Das der AVR dein Slave ist, war 
mir entgangen.

von Benjamin W. (baumwolli)


Angehängte Dateien:

Lesenswert?

Hallöchen!

Hab jetzt endlich die Zeit gefunden noch ein paar Daten nachzureichen.
Zum einen das Python Skript mit dem ich die Daten auslese.
Außerdem einen aktuellen Schaltplan.

Und noch ein paar Erkenntnisse die ich gemacht habe.
Mein TWI Interrupt sieht folgendermaßen aus.
1
ISR(TWI_vect)  
2
{
3
  switch (TW_STATUS) {              // TWI-Statusregister prüfen und nötige Aktion bestimmen 
4
    case TW_SR_SLA_ACK:             // 0x60 Slave Receiver, wurde adressiert
5
      #ifdef HC_TRANSRECEIVE_LED_PIN
6
        sbi(HC_TRANSRECEIVE_LED_PORT, HC_TRANSRECEIVE_LED_PIN);
7
      #endif
8
      #ifdef HC_RECEIVE_LED_PIN
9
        sbi(HC_RECEIVE_LED_PORT, HC_RECEIVE_LED_PIN);
10
      #endif
11
      #ifdef HC_RGB_LED_PORT
12
        hcRgbLedColor.red = hcRgbLedColorCodes.receiveRed;
13
        hcRgbLedColor.green = hcRgbLedColorCodes.receiveGreen;
14
        hcRgbLedColor.blue = hcRgbLedColorCodes.receiveBlue;
15
      #endif
16
    
17
      TWCR_ACK;                 // nächstes Datenbyte empfangen, ACK danach
18
      hcI2cBufferPosition = 0;             // hcI2cBufferposition ist undefiniert
19
      break;
20
    case TW_SR_DATA_ACK:             // 0x80 Slave Receiver,Daten empfangen
21
      hcI2cBuffer[hcI2cBufferPosition++] = TWDR;
22
      
23
      if (hcI2cBufferPosition < hcI2cBufferSize) { // im Buffer ist noch Platz für mehr als ein Byte
24
        TWCR_ACK;            // nächstes Datenbyte empfangen, ACK danach, um nächstes Byte anzufordern
25
      } else {                 // es kann nur noch ein Byte kommen, dann ist der Buffer voll
26
        TWCR_NACK;            // letztes Byte lesen, dann NACK, um vollen Buffer zu signaliseren
27
        
28
        #ifdef HC_TRANSRECEIVE_LED_PIN
29
          cbi(HC_TRANSRECEIVE_LED_PORT, HC_TRANSRECEIVE_LED_PIN);
30
        #endif
31
        #ifdef HC_TRANSCEIVE_LED_PIN
32
          cbi(HC_TRANSCEIVE_LED_PORT, HC_TRANSCEIVE_LED_PIN);
33
        #endif
34
        #ifdef HC_RGB_LED_PORT
35
          if ((TWAR>>1) == HC_I2C_DEFAULT_ADDRESS) {
36
            hcRgbLedColor.red = hcRgbLedColorCodes.connectRed;
37
            hcRgbLedColor.green = hcRgbLedColorCodes.connectGreen;
38
            hcRgbLedColor.blue = hcRgbLedColorCodes.connectBlue;
39
          } else {
40
            hcRgbLedColor.red = hcRgbLedColorCodes.powerRed;
41
            hcRgbLedColor.green = hcRgbLedColorCodes.powerGreen;
42
            hcRgbLedColor.blue = hcRgbLedColorCodes.powerBlue;
43
          }
44
        #endif
45
      }
46
      break;
47
    case TW_ST_SLA_ACK:             //
48
      #ifdef HC_TRANSRECEIVE_LED_PIN
49
        sbi(HC_TRANSRECEIVE_LED_PORT, HC_TRANSRECEIVE_LED_PIN);
50
      #endif
51
      #ifdef HC_TRANSCEIVE_LED_PIN
52
        sbi(HC_TRANSCEIVE_LED_PORT, HC_TRANSCEIVE_LED_PIN);
53
      #endif
54
      #ifdef HC_RGB_LED_PORT
55
        hcRgbLedColor.red = hcRgbLedColorCodes.transceiveRed;
56
        hcRgbLedColor.green = hcRgbLedColorCodes.transceiveGreen;
57
        hcRgbLedColor.blue = hcRgbLedColorCodes.transceiveBlue;
58
      #endif
59
      
60
      hcI2cBufferPosition = 0;             // Bufferposition ist undefiniert
61
      hcI2cSendDataLength = hcWriteToI2c();
62
    case TW_ST_DATA_ACK:             // 0xB8 Slave Transmitter, weitere Daten wurden angefordert    
63
      if (!hcI2cSendDataLength) {
64
        TWDR = 0;
65
        TWCR_NACK;
66
        break;
67
      }
68
      
69
      TWDR = hcI2cBuffer[hcI2cBufferPosition++];       // Datenbyte senden 
70
      
71
      if (hcI2cBufferPosition < hcI2cSendDataLength) {    // im Buffer ist mehr als ein Byte, das gesendet werden kann
72
        TWCR_ACK;               // nächstes Byte senden, danach ACK erwarten
73
      } else {
74
        TWCR_NACK;               // letztes Byte senden, danach NACK erwarten
75
        
76
        #ifdef HC_TRANSRECEIVE_LED_PIN
77
          cbi(HC_TRANSRECEIVE_LED_PORT, HC_TRANSRECEIVE_LED_PIN);
78
        #endif
79
        #ifdef HC_TRANSCEIVE_LED_PIN
80
          cbi(HC_TRANSCEIVE_LED_PORT, HC_TRANSCEIVE_LED_PIN);
81
        #endif
82
        #ifdef HC_RGB_LED_PORT
83
          if ((TWAR>>1) == HC_I2C_DEFAULT_ADDRESS) {
84
            hcRgbLedColor.red = hcRgbLedColorCodes.connectRed;
85
            hcRgbLedColor.green = hcRgbLedColorCodes.connectGreen;
86
            hcRgbLedColor.blue = hcRgbLedColorCodes.connectBlue;
87
          } else {
88
            hcRgbLedColor.red = hcRgbLedColorCodes.powerRed;
89
            hcRgbLedColor.green = hcRgbLedColorCodes.powerGreen;
90
            hcRgbLedColor.blue = hcRgbLedColorCodes.powerBlue;
91
          }
92
        #endif
93
      }
94
      break;
95
    case TW_SR_STOP:               // 0xA0 STOP empfangen      
96
      hcReadFromI2c();
97
    //case TW_SR_DATA_NACK:             // 0x88
98
    //case TW_ST_DATA_NACK:             // 0xC0 Keine Daten mehr gefordert 
99
    //case TW_ST_LAST_DATA:             // 0xC8  Last data byte in TWDR has been transmitted (TWEA = “0”); ACK has been received
100
    default:
101
      TWCR_RESET;               // Übertragung beenden, warten bis zur nächsten Adressierung
102
      break;  
103
    }
104
}

Dort machen die Aufrufe von hcWriteToI2c und hcReadFromI2c Probleme.
1
void hcReadFromI2c()
2
{
3
  if (hcI2cBufferPosition == 0) {
4
  } else if (hcI2cBuffer[1] != hcI2cBufferPosition-2) {
5
    #ifdef HC_ERROR_LED_PIN
6
      cbi(HC_ERROR_LED_DDR, HC_ERROR_LED_PIN);
7
      cbi(HC_ERROR_LED_PORT, HC_ERROR_LED_PIN);
8
    #endif
9
    #ifdef HC_RGB_LED_PORT
10
      hcRgbLedColor.red = hcRgbLedColorCodes.errorRed;
11
      hcRgbLedColor.green = hcRgbLedColorCodes.errorGreen;
12
      hcRgbLedColor.blue = hcRgbLedColorCodes.errorBlue;
13
    #endif
14
  } else if (hcI2cBuffer[0] > 199) {
15
    #ifdef HC_TRANSRECEIVE_LED_PIN
16
      cbi(HC_TRANSRECEIVE_LED_PORT, HC_TRANSRECEIVE_LED_PIN);
17
    #endif
18
    #ifdef HC_RECEIVE_LED_PIN
19
      cbi(HC_RECEIVE_LED_PORT, HC_RECEIVE_LED_PIN);
20
    #endif
21
    #ifdef HC_RGB_LED_PORT
22
      if ((TWAR>>1) == HC_I2C_DEFAULT_ADDRESS) {
23
        hcRgbLedColor.red = hcRgbLedColorCodes.connectRed;
24
        hcRgbLedColor.green = hcRgbLedColorCodes.connectGreen;
25
        hcRgbLedColor.blue = hcRgbLedColorCodes.connectBlue;
26
      } else {
27
        hcRgbLedColor.red = hcRgbLedColorCodes.powerRed;
28
        hcRgbLedColor.green = hcRgbLedColorCodes.powerGreen;
29
        hcRgbLedColor.blue = hcRgbLedColorCodes.powerBlue;
30
      }
31
    #endif
32
    
33
    switch (hcI2cBuffer[0]) {
34
      case HC_I2C_COMMAND_DEVICE_ID:
35
        eeprom_write_byte(&hcI2cDeviceId[0], hcI2cBuffer[2]);
36
        eeprom_write_byte(&hcI2cDeviceId[1], hcI2cBuffer[3]);
37
        break;
38
      case HC_I2C_COMMAND_TYPE:
39
        eeprom_write_byte(&hcI2cType, hcI2cBuffer[2]);
40
        break;
41
      case HC_I2C_COMMAND_ADDRESS:
42
        if (
43
          hcI2cBuffer[2] == eeprom_read_byte(&hcI2cDeviceId[0]) &&
44
          hcI2cBuffer[3] == eeprom_read_byte(&hcI2cDeviceId[1])
45
        ) {
46
          eeprom_write_byte(&hcI2cAddress, hcI2cBuffer[4]);
47
          
48
          while(1) {}
49
        }
50
        break;
51
      case HC_I2C_COMMAND_EEPROM_POSITION:
52
        hcI2cEepromPosition = ((hcI2cBuffer[2]<<8) | hcI2cBuffer[3]);
53
        break;
54
      case HC_I2C_COMMAND_EEPROM_ERASE:
55
        for (uint16_t i = 0; i < hcI2cEepromDataSize; i++) {
56
          hcI2cUpdateByteInEeprom(i, 255);
57
          wdt_reset();
58
        }
59
        
60
        hcI2cEepromPosition = 0;
61
        break;
62
      #ifdef HC_POWER_LED_PIN
63
      case HC_I2C_COMMAND_POWER_LED:
64
          if (hcI2cBuffer[2] == 0) {
65
            cbi(HC_POWER_LED_PORT, HC_POWER_LED_PIN);
66
          } else {
67
            sbi(HC_POWER_LED_PORT, HC_POWER_LED_PIN);
68
          }
69
        break;
70
      #endif
71
      #ifdef HC_ERROR_LED_PORT
72
      case HC_I2C_COMMAND_ERROR_LED:
73
        if (hcI2cBuffer[2] == 0) {
74
          cbi(HC_ERROR_LED_PORT, HC_ERROR_LED_PIN);
75
        } else {
76
          sbi(HC_ERROR_LED_PORT, HC_ERROR_LED_PIN);
77
        }
78
        break;
79
      #endif
80
      #ifdef HC_CONNECT_LED_PIN
81
      case HC_I2C_COMMAND_CONNECT_LED:
82
        if (hcI2cBuffer[2] == 0) {
83
          cbi(HC_CONNECT_LED_PORT, HC_CONNECT_LED_PIN);
84
        } else {
85
          sbi(HC_CONNECT_LED_PORT, HC_CONNECT_LED_PIN);
86
        }
87
        break;
88
      #endif
89
      #ifdef HC_TRANSRECEIVE_LED_PIN
90
      case HC_I2C_COMMAND_TRANSRECEIVE_LED:
91
        if (hcI2cBuffer[2] == 0) {
92
          cbi(HC_TRANSRECEIVE_LED_PORT, HC_TRANSRECEIVE_LED_PIN);
93
        } else {
94
          sbi(HC_TRANSRECEIVE_LED_PORT, HC_TRANSRECEIVE_LED_PIN);
95
        }
96
        break;
97
      #endif
98
      #ifdef HC_TRANSCEIVE_LED_PIN
99
      case HC_I2C_COMMAND_TRANSCEIVE_LED:
100
        if (hcI2cBuffer[2] == 0) {
101
          cbi(HC_TRANSCEIVE_LED_PORT, HC_TRANSCEIVE_LED_PIN);
102
        } else {
103
          sbi(HC_TRANSCEIVE_LED_PORT, HC_TRANSCEIVE_LED_PIN);
104
        }
105
        break;
106
      #endif
107
      #ifdef HC_RECEIVE_LED_PIN
108
      case HC_I2C_COMMAND_RECEIVE_LED:
109
        if (hcI2cBuffer[2] == 0) {
110
          cbi(HC_RECEIVE_LED_PORT, HC_RECEIVE_LED_PIN);
111
        } else {
112
          sbi(HC_RECEIVE_LED_PORT, HC_RECEIVE_LED_PIN);
113
        }
114
        break;
115
      #endif
116
      #ifdef HC_CUSTOM_LED_PIN
117
      case HC_I2C_COMMAND_CUSTOM_LED:
118
        if (hcI2cBuffer[2] == 0) {
119
          cbi(HC_CUSTOM_LED_PORT, HC_CUSTOM_LED_PIN);
120
        } else {
121
          sbi(HC_CUSTOM_LED_PORT, HC_CUSTOM_LED_PIN);
122
        }
123
        break;
124
      #endif
125
      #ifdef HC_RGB_LED_PORT
126
      case HC_I2C_COMMAND_RGB_LED:
127
        hcRgbLedColorCodes.powerRed = (hcI2cBuffer[2]>>4);
128
        hcRgbLedColorCodes.powerGreen = hcI2cBuffer[2];
129
        hcRgbLedColorCodes.powerBlue = (hcI2cBuffer[3]>>4);
130
        hcRgbLedColorCodes.errorRed = hcI2cBuffer[3];
131
        hcRgbLedColorCodes.errorGreen = (hcI2cBuffer[4]>>4);
132
        hcRgbLedColorCodes.errorBlue = hcI2cBuffer[4];
133
        hcRgbLedColorCodes.connectRed = (hcI2cBuffer[5]>>4);
134
        hcRgbLedColorCodes.connectGreen = hcI2cBuffer[5];
135
        hcRgbLedColorCodes.connectBlue = (hcI2cBuffer[6]>>4);
136
        hcRgbLedColorCodes.transceiveRed = hcI2cBuffer[6];
137
        hcRgbLedColorCodes.transceiveGreen = (hcI2cBuffer[7]>>4);
138
        hcRgbLedColorCodes.transceiveBlue = hcI2cBuffer[7];
139
        hcRgbLedColorCodes.receiveRed = (hcI2cBuffer[8]>>4);
140
        hcRgbLedColorCodes.receiveGreen = hcI2cBuffer[8];
141
        hcRgbLedColorCodes.receiveBlue = (hcI2cBuffer[9]>>4);
142
        hcRgbLedColorCodes.customRed = hcI2cBuffer[9];
143
        hcRgbLedColorCodes.customGreen = (hcI2cBuffer[10]>>4);
144
        hcRgbLedColorCodes.customBlue = hcI2cBuffer[10];
145
        break;
146
      #endif
147
      case HC_I2C_COMMAND_ALL_LEDS:
148
        break;
149
    }
150
  } else {
151
    #ifdef HC_I2C_SET_CUSTOM_DATA_FUNCTION
152
      HC_I2C_SET_CUSTOM_DATA_FUNCTION();
153
    #endif
154
  }
155
}
1
uint8_t hcWriteToI2c()
2
{
3
  if (hcI2cBuffer[0] > 199) {
4
    switch (hcI2cBuffer[0]) {
5
      case HC_I2C_COMMAND_DATA_CHANGED:
6
        hcI2cBuffer[0] = hcI2cDataChangedLength;
7
        return 1;
8
      case HC_I2C_COMMAND_CHANGED_DATA:
9
        #ifdef HC_I2C_DATA_CHANGED_FUNCTION
10
          return HC_I2C_DATA_CHANGED_FUNCTION();
11
        #else
12
          return 0;
13
        #endif
14
      case HC_I2C_COMMAND_STATUS:
15
        #ifdef HC_I2C_STATUS_FUNCTION
16
          return HC_I2C_STATUS_FUNCTION();
17
        #else
18
          return 0;
19
        #endif
20
      case HC_I2C_COMMAND_DEVICE_ID:
21
        hcI2cBuffer[0] = eeprom_read_byte(&hcI2cDeviceId[0]);
22
        hcI2cBuffer[1] = eeprom_read_byte(&hcI2cDeviceId[1]);
23
        return 2;
24
      case HC_I2C_COMMAND_TYPE:
25
        hcI2cBuffer[0] = eeprom_read_byte(&hcI2cType);
26
        hcI2cBuffer[1] = eeprom_read_byte(&hcI2cDeviceId[0]);
27
        hcI2cBuffer[2] = eeprom_read_byte(&hcI2cDeviceId[1]);
28
        return 3;
29
      case HC_I2C_COMMAND_CONFIGURATION:
30
        #ifdef HC_I2C_GET_CONFIGURATION_FUNCTION
31
          return HC_I2C_GET_CONFIGURATION_FUNCTION();
32
        #else
33
          return 0;
34
        #endif
35
      case HC_I2C_COMMAND_MHZ:
36
        hcI2cBuffer[0] = ((F_CPU >> 24) & 0xff);
37
        hcI2cBuffer[1] = ((F_CPU >> 16) & 0xff);
38
        hcI2cBuffer[2] = HIGH_BYTE(F_CPU);
39
        hcI2cBuffer[3] = LOW_BYTE(F_CPU);
40
        return 4;
41
        break;
42
      case HC_I2C_COMMAND_EEPROM_SIZE:
43
        hcI2cBuffer[0] = HIGH_BYTE((hcI2cEepromDataSize));
44
        hcI2cBuffer[1] = LOW_BYTE((hcI2cEepromDataSize));
45
        return 2;
46
      case HC_I2C_COMMAND_EEPROM_FREE:
47
        hcI2cBuffer[0] = HIGH_BYTE((hcI2cEepromDataSize-hcI2cEepromPosition));
48
        hcI2cBuffer[1] = LOW_BYTE((hcI2cEepromDataSize-hcI2cEepromPosition));
49
        return 2;
50
      case HC_I2C_COMMAND_EEPROM_POSITION:
51
        hcI2cBuffer[0] = HIGH_BYTE(hcI2cEepromPosition);
52
        hcI2cBuffer[1] = LOW_BYTE(hcI2cEepromPosition);
53
        return 2;
54
      case HC_I2C_COMMAND_BUFFER_SIZE:
55
        hcI2cBuffer[0] = HIGH_BYTE(hcI2cBufferSize);
56
        hcI2cBuffer[1] = LOW_BYTE(hcI2cBufferSize);
57
        return 2;
58
      case HC_I2C_COMMAND_LEDS:
59
        hcI2cBuffer[0] = 0;
60
        #ifdef HC_POWER_LED_PIN
61
          sbi(hcI2cBuffer[0], HC_POWER_LED_BIT);
62
        #endif
63
        #ifdef HC_ERROR_LED_PIN
64
          sbi(hcI2cBuffer[0], HC_ERROR_LED_BIT);
65
        #endif
66
        #ifdef HC_CONNECT_LED_PIN
67
          sbi(hcI2cBuffer[0], HC_CONNECT_LED_BIT);
68
        #endif
69
        #ifdef HC_TRANSRECEIVE_LED_PIN
70
          sbi(hcI2cBuffer[0], HC_TRANSRECEIVE_LED_BIT);
71
        #endif
72
        #ifdef HC_TRANSCEIVE_LED_PIN
73
          sbi(hcI2cBuffer[0], HC_TRANSCEIVE_LED_BIT);
74
        #endif
75
        #ifdef HC_RECEIVE_LED_PIN
76
          sbi(hcI2cBuffer[0], HC_RECEIVE_LED_BIT);
77
        #endif
78
        #ifdef HC_CUSTOM_LED_PIN
79
          sbi(hcI2cBuffer[0], HC_CUSTOM_LED_BIT);
80
        #endif
81
        #ifdef HC_RGB_LED_PORT
82
          sbi(hcI2cBuffer[0], HC_RGB_LED_BIT);
83
        #endif
84
        return 1;
85
      case HC_I2C_COMMAND_POWER_LED:
86
        #ifdef HC_POWER_LED_PIN
87
          hcI2cBuffer[0] = bis(HC_POWER_LED_PORT, HC_POWER_LED_PIN);
88
        #else
89
          hcI2cBuffer[0] = 0;
90
        #endif
91
        return 1;
92
      case HC_I2C_COMMAND_ERROR_LED:
93
        #ifdef HC_ERROR_LED_PIN
94
          hcI2cBuffer[0] = bis(HC_ERROR_LED_PORT, HC_ERROR_LED_PIN);
95
        #else
96
          hcI2cBuffer[0] = 0;
97
        #endif
98
        return 1;
99
      case HC_I2C_COMMAND_CONNECT_LED:
100
        #ifdef HC_I2C_CONNECT_LED_PIN
101
          hcI2cBuffer[0] = bis(HC_CONNECT_LED_PORT, HC_CONNECT_LED_PIN);
102
        #else
103
          hcI2cBuffer[0] = 0;
104
        #endif
105
        return 1;
106
      case HC_I2C_COMMAND_TRANSRECEIVE_LED:
107
        #ifdef HC_TRANSRECEIVE_LED_PIN
108
          hcI2cBuffer[0] = bis(HC_TRANSRECEIVE_LED_PORT, HC_TRANSRECEIVE_LED_PIN);
109
        #else
110
          hcI2cBuffer[0] = 0;
111
        #endif
112
        return 1;
113
      case HC_I2C_COMMAND_TRANSCEIVE_LED:
114
        #ifdef HC_TRANSRECEIVE_LED_PIN
115
          hcI2cBuffer[0] = bis(HC_TRANSCEIVE_LED_PORT, HC_TRANSCEIVE_LED_PIN);
116
        #else
117
          hcI2cBuffer[0] = 0;
118
        #endif
119
        return 1;
120
      case HC_I2C_COMMAND_RECEIVE_LED:
121
        #ifdef HC_RECEIVE_LED_PIN
122
          hcI2cBuffer[0] = bis(HC_RECEIVE_LED_PORT, HC_RECEIVE_LED_PIN);
123
        #else
124
          hcI2cBuffer[0] = 0;
125
        #endif
126
        return 1;
127
      case HC_I2C_COMMAND_CUSTOM_LED:
128
        #ifdef HC_CUSTOM_LED_PIN
129
          hcI2cBuffer[0] = bis(HC_CUSTOM_LED_PORT, HC_CUSTOM_LED_PIN);
130
        #else
131
          hcI2cBuffer[0] = 0;
132
        #endif
133
        return 1;
134
      case HC_I2C_COMMAND_RGB_LED:
135
        hcI2cBuffer[0] = (hcRgbLedColorCodes.powerRed<<4) | hcRgbLedColorCodes.powerGreen;
136
        hcI2cBuffer[1] = (hcRgbLedColorCodes.powerBlue<<4) | hcRgbLedColorCodes.errorRed;
137
        hcI2cBuffer[2] = (hcRgbLedColorCodes.errorGreen<<4) | hcRgbLedColorCodes.errorBlue;
138
        hcI2cBuffer[3] = (hcRgbLedColorCodes.connectRed<<4) | hcRgbLedColorCodes.connectGreen;
139
        hcI2cBuffer[4] = (hcRgbLedColorCodes.connectBlue<<4) | hcRgbLedColorCodes.transceiveRed;
140
        hcI2cBuffer[5] = (hcRgbLedColorCodes.transceiveGreen<<4) | hcRgbLedColorCodes.transceiveBlue;
141
        hcI2cBuffer[6] = (hcRgbLedColorCodes.receiveRed<<4) | hcRgbLedColorCodes.receiveGreen;
142
        hcI2cBuffer[7] = (hcRgbLedColorCodes.receiveBlue<<4) | hcRgbLedColorCodes.customRed;
143
        hcI2cBuffer[8] = (hcRgbLedColorCodes.customGreen<<4) | hcRgbLedColorCodes.customBlue;
144
        return 9;
145
        break;
146
      case HC_I2C_COMMAND_ALL_LEDS:
147
        hcI2cBuffer[0] = 0;
148
        #ifdef HC_POWER_LED_PIN
149
          hcI2cBuffer[0] = bis(HC_POWER_LED_PORT, HC_POWER_LED_PIN);
150
        #endif
151
        #ifdef HC_ERROR_LED_PIN
152
          hcI2cBuffer[0] = bis(HC_ERROR_LED_PORT, HC_ERROR_LED_PIN);
153
        #endif
154
        #ifdef HC_I2C_CONNECT_LED_PIN
155
          hcI2cBuffer[0] = bis(HC_CONNECT_LED_PORT, HC_CONNECT_LED_PIN);
156
        #endif
157
        #ifdef HC_TRANSRECEIVE_LED_PIN
158
          hcI2cBuffer[0] = bis(HC_TRANSRECEIVE_LED_PORT, HC_TRANSRECEIVE_LED_PIN);
159
        #endif
160
        #ifdef HC_TRANSRECEIVE_LED_PIN
161
          hcI2cBuffer[0] = bis(HC_TRANSCEIVE_LED_PORT, HC_TRANSCEIVE_LED_PIN);
162
        #endif
163
        #ifdef HC_RECEIVE_LED_PIN
164
          hcI2cBuffer[0] = bis(HC_RECEIVE_LED_PORT, HC_RECEIVE_LED_PIN);
165
        #endif
166
        #ifdef HC_CUSTOM_LED_PIN
167
          hcI2cBuffer[0] = bis(HC_CUSTOM_LED_PORT, HC_CUSTOM_LED_PIN);
168
        #endif
169
        return 1;
170
    }
171
  } else  {
172
    #ifdef HC_I2C_GET_CUSTOM_DATA_FUNCTION
173
      return HC_I2C_GET_CUSTOM_DATA_FUNCTION();
174
    #else
175
      return 0;
176
    #endif
177
  }
178
  
179
  return 0;
180
}

Rufe ich diese Funktionen nicht auf und belege hcI2cBuffer mit festen 
Daten habe ich keine Probleme. Daher habe ich die Vermutung das ich den 
Interrupt zu viel zumute. Aber ist das überhaupt möglich?
So wie ich I2C verstehe kann der Master einen Slave erst wieder 
ansprechen wenn dieser die Leitung frei gibt. Dafür muss er eine ACK 
oder NACK senden. Sehe ich das richtig? Wenn das so ist sollte der 
Interrupt nicht mehrfach gleichzeitig ausgeführt werden können. Ist das 
so oder habe ich da was ganz falsch verstanden?

Als Workaround habe ich jetzt die Idee das immer erst ein Write Befehl 
abgesetzt werden muss. Dieser bestimmt das Kommando. In der main 
Funktion möchte ich dann prüfen ob sich das Kommando geändert hat und 
dazu passenden Daten in den Buffer laden. Danach können diese über den 
Read Befehl abgeholt werden. Werde mich gleich mal daran setzen und 
hoffe das ich damit Erfolge feier.

Falls noch jemand eine Idee hat wie ich den Workaround umgehen kann 
würde ich mich sehr darüber freuen.

Liebe Grüße Baumwolli

von Regeln Erklärbär (Gast)


Angehängte Dateien:

Lesenswert?

Benjamin W. schrieb:
> Mein TWI Interrupt sieht folgendermaßen aus.

Du bist lang genug hier angemeldet um zu wissen wie längere
Sourcen hier zu posten sind. Oder bist du soooooo schwer von
Begriff? Keine Übersicht? Oder vielleicht beratungsresistent?

Zum besseren Verständnis habe ich dir im Anhang die Regeln
nochmal mitgegeben. Solltest du sie nicht verstehen und/oder
nicht danach handeln können dann solltest du auch das
Programmieren sein lassen. Es hat schon Sinn hier nicht das
grosse Chaos ausbrechen zu lassen.

Wenn es nicht anders geht kann man auch von Respektlosigkeit
sprechen .... gegenüber der Community.

von Weinbauer (Gast)


Lesenswert?

Uiuiui aus meiner Sicht hast Du da viel zuviel Zeit in der ISR ... Man 
kann die Ints in der ISR freigeben, SEI, man kann sich damit aber auch 
viel Ärger einhandeln und ja, im Allgemeinen kann der Atmega nicht 
gleichzeitig mehrere ISR abarbeiten.
Deswegen versucht man die ISR kurz zu halten.

von Weinbauer (Gast)


Lesenswert?

Achso, und nienienieniemals aus einem Empfangs-int heraus senden und 
warten bis Sendung abgeschlossen ist

von Benjamin W. (baumwolli)


Lesenswert?

vielen Dank Weinbauer! Dann werde ich wohl um den Workaround nicht 
rumkommen.
Gestern konnte ich damit aber schon einige Erfolge feiern.

von Peter D. (peda)


Lesenswert?

Sobald man als I2C-Slave einen MC einsetzt, braucht dieser Zeit, um in 
den Interrupt zu springen und ihn abzuarbeiten. Während dieser Zeit hält 
er SCL auf low, um dem Master zu sagen, daß er heschäftigt ist.
D.h. der I2C-Master muß Clock-Stretching unterstützen. Tut Deine 
Master-CPU dies?

: Bearbeitet durch User
von Benjamin W. (baumwolli)


Lesenswert?

Danke peda für den heißen Typ! Hab nach kurzem googlen raus gefunden das 
der Broadcomm BCM2835 Prozessor auf dem Raspberry einen Bug hat und das 
Clock Stretching nicht funktioniert 
http://www.advamation.de/technik/raspberrypi/rpi-i2c-bug.html.
Hab die Baudrate mal auf 10kHz gestellt. Jetzt klappt mein Code!

Beitrag #5374494 wurde von einem Moderator gelöscht.
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.