Martin S. schrieb:
> Über ein Terminal Programm lass ich mir das zweite Byte ausgeben. Es hat
> in jedem Fall den Wert 11111111. Ich vermute mein Problem liegt daran
> das ich den TWI Falsch anspreche hier mal ein Auszug aus meinem Code:
>
Tu dir ganz schnell selbst einen Gefallen und schreib dir Funktionen für
einzelne immer wieder kehrende Teilfunktionalitäten!
So etwas
> TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); //Start
> while (!(TWCR & (1<<TWINT))); //Bestätigung dass Start gesetzt
> TWDR = adres; //setzen der Adresse
> TWCR = (1<<TWINT)|(1<<TWEN); //Adresse
> while (!(TWCR & (1<<TWINT)));
>
> TWCR = (1<<TWINT)|(1<<TWEN); //Datenpaket 1
> while (!(TWCR & (1<<TWINT)));
> dat1 = TWDR ;
> ....
ist doch grober Unfug.
Da wird man doch vor lauter Bit-Kontrolle hinten und vorne nicht mehr
fertig.
Schreib dir 2(!) EMpfangsfunktionen. Eine die ein eingegangenes Byte mit
einem ACK quittiert und eine die mit einem NAK quittiert.
Nach dem Start werden alle erwarteten Bytes mit der Read-Ack Funktion
geholt. Bis auf das letzte Byte, für die du die Read-Nak Funktion
verwendest.
Sieh dir dir Fleury Implementierung der TWI (I2C) Schnittstelle an. Dann
siehst du, welche Funktionen da sinnvoll sind.
http://homepage.hispeed.ch/peterfleury/avr-software.html
Aufbauend auf diesen Basisfunktionen ist der Rest dann ein 'piece of
cake', wie die Amerikaner sagen würden.
1 | int16_t readValue()
|
2 | {
|
3 | uint8_t high, low;
|
4 |
|
5 | if( i2c_start( ADRESSE_R ) )
|
6 | return -9999; // Fehler. Baustein hat sich nicht gemeldet
|
7 |
|
8 | high = i2c_readAck();
|
9 | low = i2c_readNak();
|
10 | i2c_stop();
|
11 |
|
12 | return ( high << 8 ) + low ;
|
13 | }
|
wenn du auch noch das zu lesende Register einstellen musst, dann eben
mit der Sequenz:
start mit der Write Adresse
Registernummer schreiben
Repeated Start mit der Read Adresse
High Byte lesen (ACK)
Low Byte lesen (NAK)
Stop
Aber mach dir entsprechende Hifsfunktionen damit du dich bei der
Implementierung des 'Protokolls' nicht auch noch um den
Hardware-Kleinkram kümmern musst. Der ist Sache einer anderen
Softwareschicht. In der geht es darum, wie man der Hardware bestimme
Dinge klar macht. Das machen zb die Fleury Funktionen. Auf der Ebene
hier geht es dann schon darum, wie man aus diesen Basisfunktionalitäten
die vom Baustein vorgeschriebenen Sequenzen zusammensetzt.
Aber was du nicht tun willst, das ist die beiden Software Ebenen wild
durcheinander würfeln. Du musst dir nicht unnötig selbst Prügel zwischen
die Beine werfen.