Hallo,
ich versuche mit einem ATmega32 einen HYT 221
(Feuchte-/Temperatursensor) über i2c anzusprechen/ auszulesen.
Das ist das erste Mal, dass ich etwas mit i2c mache, bin also völlig
unerfahren.
Da das für die erste Frage reichen sollte, und um es übersichtlich zu
halten, poste ich erst mal nur den Teil, bei dem das erste Problem
auftritt.
Ich benutze die i2c lib von Peter Fleury.
Leider bleibt das Programm schon beim setzen der „start condition“
hängen. Und zwar in der Zeile:
1
while(!(TWCR&(1<<TWINT)));
Hat jemand eine Idee was da schief läuft?
Grüße,
Tobi
Komlette Methode "i2c_start":
Ansich ist die Funktion richtig so. Benutze sie 1:1 ohne Probleme.
Es gibt eigentlich nur drei Möglichkeiten, wenn sie hängen bleibt:
1. Falscher I2C-Clock (meist zu schnell)
2. Fehler in der Schaltung
3. I2C-Adresse nicht nach links geschiftet (ist wohl der häufigste
Fehler, da die Adresse nur 7-Bit lang ist und in den Datenblättern
"ungeshiftet" dargestellt wird).
Wenn im Datenblatt also steht dass die Adresse des ICs "0x0100100" (also
0x48) dann darf man sich senden "i2c_start(0x48+I2C_READ);" sondern
"i2c_start(0x90+I2C_READ);
Achja und die untersten/das unterste Bit der Adresse kann ja oftmals
noch über Adress-Pins verändert werden (je nach Sensor, bei manchen
gehts auch gar nicht)
Deine Init sieht dann vermutlich so aus
Vielen Dank für die Antwort!
Punkt 3. habe ich bedacht. Ich werde mir die Punkte 1 und 2 noch mal
genau angucken.
Eigentlich wird ja bis zu der betreffenden Zeile der Slave noch garnicht
direkt angesprochen. Also bleiben so wie so nur die Punkte 1 und 2.
Ich werde mir bei der nächsten Bestellung nochmal einen neuen uC
bestellen. Vielleicht ist ja der Kanal aus irgendeinem Grund defekt.
Grüße
Hallo,
ich habe es noch mal probiert, ohne ein angeschlossenes i2c Gerät.
Trotzdem bleibt er an besagter Stelle hängen.
Ich denke mal, der uC ist defekt????
Oder gibt es noch andere Möglichkeiten?
Hier nochmal meine Init: Ist ja komplett geklaut...und mein Quarz macht
12.288MHz
1
#include<inttypes.h>
2
#include<compat/twi.h>
3
#include"i2cmaster.h"
4
#include"rtc.h"
5
6
7
/* define CPU frequency in Mhz here if not defined in Makefile */
Hallo,
hier die Ausschnitte aus meinem Programm, die mit dem i2c zu tun haben:
Wie gesagt, ich nutze die i2c lib von Peter Fleury, die poste ich jetzt
nicht komplett...die Header fehlen auch und das ganz Unwichtige habe ich
aus der Main gestrichen.
Ich habe mir die Signale von SDA und SCL mit dem OSZI angeschaut. Falls
sinnvoll, kann ich gerne Bilder Posten.
Die Signale sahen recht vernünftig aus. Nur der geringe Pegel von SDA
hat mich etwas gewundert. (nur 1,5 V bei 5V VCC; SCL ist sauber auf 5V)
Wie schon vermutet, ist der Controller also wohl doch nicht im Eimer.
Zu den Wiederständen: Ich hatte bisher 10k angeschlossen und habe es
jetzt nochmal mit 5k versucht...leider ohne Erfolg. Kondensatoren sind
nicht im Bus.
Die Verbindung zwischen uC und Sensor ist mit normalen Einzeladern
verdrahtet. Dafür aber auch nur ca. 5cm lang. (Testboard)
***i2c_hyd_temp***
1
#include<avr/io.h>
2
#include"i2cmaster.h"
3
#include"i2c_hyd_temp.h"
4
#include"rtc.h"
5
#define ADR_HYD 0x50
6
7
//volatile unsigned char TempCurrent;
8
//volatile unsigned char RLFCurrent;
9
10
11
_BoolgetSensVal(void)
12
{
13
intreceive[4];//receive-array
14
intRLF_raw;
15
intTemp_raw;
16
17
i2c_start(ADR_HYD+I2C_SEND);
18
19
//delay einfügen? TODO: schauen ob warten notwendig evtl. wait_i2c(1); implementieren
20
time_out_i2c=0;
21
while(time_out_i2c<150){}//150ms warten (versuch bei debugging)
22
23
24
i2c_start(ADR_HYD+I2C_READ);
25
26
receive[0]=i2c_readAck();
27
if(receive[0]&=0x40==0)
28
{
29
30
receive[1]=i2c_readAck();
31
receive[2]=i2c_readAck();
32
receive[3]=i2c_readNak();
33
i2c_stop();
34
35
RLF_raw=(receive[1]&(receive[0]<<8));
36
RLFCurrent=(RLF_raw>>2)/163.83;
37
Temp_raw=(receive[3]&(receive[2]<<8));
38
TempCurrent=(Temp_raw>>2)/99.2909-40;
39
returnTRUE;
40
41
42
43
}
44
else
45
{
46
i2c_stop();
47
returnFALSE;
48
}
49
50
}
Da ich erst heute ein Display integriert habe, wird in dieser Version
nur über LEDs angezeigt, ob der Messwert (i2c) ungleich oder gleich null
ist.
***main***
Ein Fest a. schrieb:> Die Signale sahen recht vernünftig aus. Nur der geringe Pegel von SDA> hat mich etwas gewundert. (nur 1,5 V bei 5V VCC; SCL ist sauber auf 5V)
Dann stimmt da wohl was an der Hardware nicht. Vielleicht hast du den
falschen Pin für SDA erwischt oder so. Wie sieht der Pegel denn aus,
wenn du das IC abklemmst?
Vielleicht hast du auch irgendwo einen Kurzschluss. Da würde ich erstmal
genau drüber schauen, den 1,5V kann nicht sein. Vielleicht hast du den
IC auch gar nicht richtig mit Spannung versorgt, dann kann sowas auch
passieren.
Ob nun 10k oder 4,7k ist dann auch egal. 4,7k ist so der Standardwert,
vorallem wenn du mit einem schnellen I2C Clock arbeitest, sollte man den
Pullup nicht zu hochohmig machen (was aber ja bei dir nicht der Fall
ist)
Hallo,
vielen Dank für die Antwort!
Ich bin erst jetzt dazu gekommen, mir die Schaltung nochmal anzugucken.
Die Verdrahtung stimmt definitiv.
Wenn ich die Pins SCL und SDA komplett offen habe, lässt sich kein
vernünftiges Signal messen, nur ein paar Störungen.
Wenn ich keinen Slave angeschlossen habe, nur die Widerstände, messe ich
an beiden Pins dauerhaft VCC. (Was dann ja auch nicht verwunderlich
ist.)
Wenn der Sensor nur an die Versorgungsspannung angeschlossen ist, messe
ich an SCL VCC(5V) und an SDA ca. 0.5V.
Ich habe danach den Sensor wieder angeschlossen, und Die Signale wieder
gemessen, wie im letzten Beitrag beschrieben.
Also sollte ich es doch mal mit einem neuen uC und evtl . auch neuen
Sensor versuchen?