Hallo liebes Forum, ich versuch mich seit ein paar Tagen mit einem kleinen Übungsprojekt. Es geht darum den LM75 Temperatursensor zum laufen zu bekommen und mir das Ergebnis über UART auf dem PC Anzeigen zu lassen. Als µC verwende ich einen Atmega8, ich habe kein bestimmtes Versuchsboard sondern verwende alle Hardware im Eigenbau. Durch das Wälzen zahlreicher Beitränge und Stunden die ich mit dem Versuch herrumschlage das TWI zu verstehen bin ich mittlerweile so weit das ich das erste Byte das der LM75 sendet tatsächlich auslesen kann. Nur für das zweite Byte, in dem die Kommastelle steht bekomme ich nicht richtig ausgelesen. Ü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: #define TAKT 4000000UL #define ADRESSE_R 0b10010001 //Lesen #define ADRESSE_W 0b10010000 //Schreiben #define FAKTOR 32 #define TEILER 1 void TWI_init(unsigned char faktor, unsigned char teiler) { TWBR = faktor; TWSR = teiler; } char dat1, dat2; char TWI_empf(unsigned char adres) { 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 ; TWCR = (1<<TWINT)|(1<<TWEN); //Datenpaket 2 geladen while (!(TWCR & (1<<TWINT))); dat2 = TWDR ; while (!(TWCR & (1<<TWINT))); TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN); //Stop return dat1; } Vlt hat jemand eine Idee und kann mir weiterhelfen. LG Martin
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.
:
Bearbeitet durch User
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.