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
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
Ein Schaltplan und ein Foto wäre jetzt nicht schlecht, besonders was den TWI Bus angeht. Denn oberhalb von 100kHz wird es anspruchsvoll.
Sorry da habe ich mich falsch ausgedrückt. Der atmega läuft auf 12mhz. An der twi/i2c Geschwindigkeit habe ich nichts geändert.
> 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!
Sobald ich wieder zuhause bin werde ich auch den Schaltplan online stellen.
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.
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
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.
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.
Achso, und nienienieniemals aus einem Empfangs-int heraus senden und warten bis Sendung abgeschlossen ist
vielen Dank Weinbauer! Dann werde ich wohl um den Workaround nicht rumkommen. Gestern konnte ich damit aber schon einige Erfolge feiern.
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.