Forum: Mikrocontroller und Digitale Elektronik LM75 und TWI


von Martin S. (prayer90)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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
Noch kein Account? Hier anmelden.