Hi! Ich mache erste Gehversuche mit Hardware-TWI und hätte gerne, dass mal jemand über meinen Code schaut, ob alles stimmt oder man etwas anders lösen sollte. Er funktioniert auf den ersten Blick, aber beim Lesen gibt es noch Ungereimtheiten. Es geht um das Auslesen eines 16 Bit ADCs (MCP 3426A0-E/SN) Datenblatt: http://www.reichelt.de/index.html?;ACTION=7;LA=3;OPEN=0;INDEX=0;FILENAME=A200%252FMCP3426-27-28.pdf;SID=15mbpbf6wQAQ8AAErTpj4f6a3708b2c9f2202a217a92c8223acf3 Zunächst das Senden. TWI-Takt ist auf 100khz eingestellt, data ist vom Typ uint8_t und die Konfiguration für den ADC. Der Code funktioniert, ich kann später das data-Byte wieder aus dem ADC lesen. Der Code entspricht im Wesentlichen dem aus dem Datenblatt vom Atmega.
1 | #define SLA_W 0b11010000; //4 Bits device code (1101), 3 Bits addres (factory programmed, hier 0), r/!w-Bit
|
2 | TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); //Start condition senden |
3 | while (!(TWCR & (1<<TWINT))); //Warten bis start condition gesendet wurde. |
4 | if ((TWSR & 0xF8) != TW_START) ERROR(1); //Fehler: Status ist nicht Start. |
5 | TWDR = SLA_W; //Master Transmitter (Slave-Write) |
6 | TWCR = (1<<TWINT) | (1<<TWEN); //TWINT-Bit löschen um Übertragung zu starten |
7 | while (!(TWCR & (1<<TWINT))); //Warten bis übertragen |
8 | if ((TWSR & 0xF8) != TW_MT_SLA_ACK) ERROR(2); //Fehler: Status ist nicht ACK. |
9 | |
10 | TWDR = data; //Nutzdaten laden |
11 | TWCR = (1<<TWINT) | (1<<TWEN); //Senden |
12 | while (!(TWCR & (1<<TWINT))); //Auf ack des Slaves warten |
13 | if ((TWSR & 0xF8) != TW_MT_DATA_ACK) ERROR(3); //Status ist nicht ACK |
14 | |
15 | TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); //Stop-Condition senden |
16 | //Muss ich die Stop-Condition senden, wenn ich nur einen Master und nur ein Slave auf dem Bus habe?
|