Forum: Mikrocontroller und Digitale Elektronik LM75 an ATMega 8


von René P. (speedy909)


Lesenswert?

Hallo,

Nach ein paar Monaten ohne Erfolg komme ich jetzt zu meinem 2. Versuch.
Ich will die Temperatur aus einem LM75 auslesen.

Software: AVR Studio 4.13 (GCC)
Hardware: ATMega 8

Programmausschnitt:
1
#define LM75_write  144
2
#define LM75_read 145
3
#define FAKTOR 44
4
#define TEILER 0
5
6
void init (unsigned char faktor, unsigned char teiler)
7
{
8
 TWBR = faktor;
9
 TWSR = teiler;
10
}
11
12
unsigned char empf (unsigned char adres)
13
{
14
 unsigned char daten;              //hilfsvariable
15
 TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);   //startbedingung
16
 loop_until_bit_is_set(TWCR, TWINT);      //warte bis fertig
17
18
 TWDR = adres;                  //adresse
19
 TWCR = (1<<TWINT) | (1<<TWEN);          //senden
20
 loop_until_bit_is_set(TWCR, TWINT);      //warten bis fertig
21
22
 TWCR = (1<<TWINT) | (1<<TWEN);          //empfang starten
23
 loop_until_bit_is_set(TWCR, TWINT);      //warte bis fertig
24
25
 daten = TWDR;                  //daten abholen
26
 TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN);    //ack impuls senden
27
 loop_until_bit_is_set(TWCR, TWINT);      //warte bis fertig
28
29
 TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN);  //stoppbedingung
30
 return daten;
31
}
32
33
init(FAKTOR,TEILER);
34
35
wert1 = empf(LM75_read);
36
wert2 = empf(LM75_read);

Die Werte lasse ich mir direkt von einem LCD anzeigen.
leider sind beide Werte immer gleich (ca. 247) und Schwanken nur leicht

von Jörg X. (Gast)


Lesenswert?

Beim TWI-Interface der AVRs musst du schon vor dem lesen wissen, ob der 
Master ACK'en soll:
1
    //empfang starten, mit ACK antworten:
2
    TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
3
    loop_until_bit_is_set(TWCR, TWINT); //warte bis fertig
4
5
    daten = TWDR;                       //daten abholen
6
    TWCR = (1<<TWINT) | (1<<TWEN);      // KEIN ack impuls senden
7
    loop_until_bit_is_set(TWCR, TWINT); //warte bis fertig

hth. Jörg

von René P. (speedy909)


Angehängte Dateien:

Lesenswert?

Danke für die Antwort,

Jetzt habe ich das GANZE Datenblatt durchgelesen und komme immer noch zu 
keinem Ergebnis!

hat keiner einen funktionierende Code um einen LM75 auszulesen?

von Jörg X. (Gast)


Lesenswert?


von René P. (speedy909)


Lesenswert?

Ich habe es jetzt soweit hinbekommen das Ich die Temperatur (1. Byte) 
anzeigen kann, aber wie kann ich jetzt das 2. Byte auslesen?
1
void init (unsigned char faktor, unsigned char teiler)
2
{
3
 TWBR = faktor;
4
 TWSR = teiler;
5
}
6
7
8
void i2c_start (unsigned char adres)
9
{
10
 TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);    //start
11
 loop_until_bit_is_set(TWCR, TWINT);
12
 TWDR = adres;                    //adresse eingeben
13
 TWCR = (1<<TWINT) | (1<<TWEN);            //freigeben (senden)
14
 loop_until_bit_is_set(TWCR, TWINT);
15
}
16
17
void i2c_stopp (void)
18
{
19
 TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN);    //stopp 
20
}
21
22
23
void ack (void)
24
{
25
 TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN);      //ack senden
26
 loop_until_bit_is_set(TWCR, TWINT);
27
}
28
29
30
unsigned char empf (void)
31
{
32
 unsigned char daten;
33
34
 TWCR = (1<<TWINT) | (1<<TWEN);            //freigeben (empfangen)
35
 loop_until_bit_is_set(TWCR, TWINT);
36
 daten = TWDR;                    //daten empfangen
37
 return daten;
38
}
39
40
 init(44,1);
41
42
 i2c_start(0x91);
43
 ewert = empf();
44
 ack();
45
 //ewert2 = empf();
46
 i2c_stopp();

von Olaf (Gast)


Lesenswert?

Hallo René.

Jörg sagte ja bereits, daß du das ACK flag setzen mußt. Also ein empfang 
mit TWEA und eins ohne.
1
   i2c_start(0x91);
2
   event1=empf_ACK();
3
   event2=empf_NACK();
4
   i2c_stop();

Olaf

von Jörg X. (Gast)


Angehängte Dateien:

Lesenswert?

Ich hätte dann noch eine 'etwas' weiter entwickelte Version (im Anhang).
Aber sobald du richtig begriffen hast wie das TWI funktioniert, schau 
dir mal die TWI-Library von P. Fleury an (http://jump.to/fleury), die 
funktioniert dann mit Interrupts -- ohne jedesmal das ganze Programm 
aufzuhalten.
Außerdem gibt's für den Interruptbetrieb noch zwei (Master/Slave) 
Appnotes von Atmel (u.a. AVR315, IIRC).

hth. Jörg

von René P. (speedy909)


Lesenswert?

Danke, jetzt funktionierts!
habe wohl zu kompliziert darüber nachgedacht ;-)

von René P. (speedy909)


Lesenswert?

Habe ich noch vergessen zu erwähnen!

in deinem Code hat sich ein Fehler eingeschlichen! (aber trotsdem Danke 
für den Code!)

und zwar bei dieser zeile:
1
uint8_t ret_val, status;    //return-wert, temp. Variable fuer TWSR

sollte so aussehen:
1
uint16_t ret_val, status;    //return-wert, temp. Variable fuer TWSR

von dom_lech (Gast)


Lesenswert?

IMHO müsste folgende Zeile auch anders sein:
1
#define TW_ERROR_MSK 0x1F
sollte
1
#define TW_ERROR_MSK 0x7F
sein

weil die untersten 7 bit des Temperaturwerte undefiniert (siehe 
Datenblatt) sind. Damit die Abfrage auf Kommunikationsfehler 
funktioniert muss man ausserdem beim Lesen diese letzten 7bit def. auf 0 
setzen.
1
return ret_val & ~0x7f;
statt
1
return ret_val;

Das nur so am Rande... wenn mans nicht so macht kanns funktionieren... 
muss aber nicht. Hat bei mir zu Beginn in 90% der Fälle funktioniert, 
dann hab ich ein paar Änderungen an meiner Schaltung gemacht und dann 
war desshalb ein kompletter Ausfall.

von Kurt (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,
ich probier den Ledtreiber TLC59116 zu beschreiben, klapt aber nicht so 
ganz mit dem I2C Bus:
Könnt Ihr mir bitte sagen was da nicht stimmt?
Mit dem Oszilloskop mess ich keinen Takt an SCL und auch nichts an SDA.

lg Kurt

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.