LM75 an ATMega 8

OP #804636
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
Gast #804798
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
OP #806062
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();
Gast #806116
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
Angehängte Dateien:
OP #821174
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
Gast #1640845
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.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.