Forum: Compiler & IDEs DS1621 ueber I2C ansteuern


von Robert (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Mikrocontroller-Fans,
ich versuche seit kurzem einen I2C-Sensor anzusteuern, leider scheint 
das einfach nicht zu funktionieren. Hab schon mal gegoogelt und auch 
hier im Forum ein bisschen gestöbert und geschaut, wie andere das gelöst 
haben - nur scheint es immer noch nicht zu funktionieren. Hier ein 
Ausschnitt aus der main.c:
1
int main(void)
2
{
3
  USART_init();
4
  i2c_init();
5
  unsigned char temp1, temp2;
6
  char s[7];
7
  
8
  i2c_start();             // setzt ein Start-Kommando
9
  i2c_transmit_byte(0x90); // uebermittelt Adresse+Write (1001000)
10
  i2c_transmit_byte(0xEE); // Startet mit der Temperaturkonversion
11
  i2c_stop();
12
  
13
  i2c_start();
14
  i2c_transmit_byte(0x90);
15
  i2c_transmit_byte(0xAA); // Sensor soll die Temperatur zurueckgeben
16
  _delay_ms(10);
17
  while(1)
18
  {
19
    i2c_start();
20
    i2c_transmit_byte(0x91);
21
    temp1=i2c_receive_byte();
22
    temp2=i2c_receive_byte();
23
    i2c_stop();
24
    USART_String_Transmit(itoa(temp1,s,10));
25
    USART_String_Transmit(itoa(temp2,s,10));
26
    _delay_ms(100);
27
  }
28
  
29
}

Wenn ich das Programm ausführe, so sendet mir der Sensor nur Nullen, 
woran könnte das liegen? Habe schon versucht, die Sendezeiten zu ändern 
und habe auch schon die Includes geprüft - sieht eigentlich alles 
richtig aus. Ach ja, ich betreibe den Sensor am RnControl (da gibt es 
auch direkt einen I2C Anschluss). Die Includes habe ich auch mal mit 
angehangen - habe alles ein wenig auskommentiert.
Es gibt ähnliche Forenbeiträge mit Nutzung von Bibliotheken und Co. aber 
ich möchte keine fertige Bibliothek nutzen - würde es lieber selbst hin 
bekommen ;)
Vielleicht kann mir ja jemand helfen?

MfG,
Rob

von holger (Gast)


Lesenswert?

>  i2c_start();
>  i2c_transmit_byte(0x90);
>  i2c_transmit_byte(0xAA); // Sensor soll die Temperatur zurueckgeben
>  _delay_ms(10);


Fehlt da nicht ein Stop?

von Robert (Gast)


Lesenswert?

Naja, ich habe beide Versionen gesehen - einige schreiben dort ein Stop 
dazwischen, andere nicht. Laut Datenblatt gehört das ein Repeated Start 
hin - so gesehen kein Stop sondern nur ne neue Startbedingung, daran 
habe ich mich gehalten. Habe vorns noch eniges getestet, aber immer das 
Selbe Ergebnis. Werde mir demnächst einen zweiten DS1621 holen und mit 
dem neuen Exemplar noch einmal testen.
MfG, Robert

von Gerhard. (Gast)


Lesenswert?

Hallo Robert,

Die while () loop ist nicht notwendig. Du musst aber ACK und NACK beim 
Empfang der Daten vom MASTER aus senden. Sieh Dir den PIC Beispiels Code 
unten an:

int main(void)
{
  USART_init();
  i2c_init();
  unsigned char temp1, temp2;
  char s[7];

  i2c_start();             // setzt ein Start-Kommando
  i2c_transmit_byte(0x90); // uebermittelt Adresse+Write (1001000)
  i2c_transmit_byte(0xEE); // Startet mit der Temperaturkonversion
  i2c_stop();

  // Per Seite 9:

  // Ich kenne Deinen Compiler nicht:
  // Finde syntax raus wie man ACK und NACK hier senden soll
  // hier ein Beispiel mit CCS PIC Compiler:
  // Neue Abfrage der Daten:

  i2c_start();
  i2c_write(0x90);
  i2c_write(0xaa);
  _delay_ms(100);
  i2c_start();
  i2c2_write(0x91);
  temp2=i2c_read(ACK);  // MSB empangen, Master sendet ACK
  temp1=i2c_read(NACK); // LSB empfangen, Master sendet NACK
  i2c_stop;
  USART_String_Transmit(itoa(temp1,s,10));
  USART_String_Transmit(itoa(temp2,s,10));
  _delay_ms(100);

  // Dem Datenblatt nach muesste das funktionieren. Wenn das NACK nicht
  // gesendet wird, dann bleibt der DS1621 haengen. Ist ganz wichtig.
  // Die eingefuegten ACK/NACK gehen bei Dir vielelicht nicht so:
}


mfg,
Gerhard

von Robert (Gast)


Angehängte Dateien:

Lesenswert?

Danke für die Sache mit dem Ack und Nack Gerhard, ich wusste doch, da 
fehlt was ;)
Habs jetzt umgeschrieben (ich hoffe richtig) und jetzt bekomme ich von 
dem Sensor 255 255 zurück (alles Einsen), wenn ich eine Messung starte - 
also stimmt wahrscheinlich noch etwas nicht.
Werd nochmal alles durch schauen, vielleicht finde ich ja noch einen 
Fehler.
Gibt es eigentlich Festlegungen, wie lange eine Pause bei den 
I2C-Kommandos sein muss?
Ich hänge den momentanen Code als Anhang mit ran.
MfG,
Robert

von Robert (Gast)


Lesenswert?

Kommando zurück - hab jetzt doppelt nacheinander das ack drinnen, wie 
ich gerade sehe. Hab ich wieder verändert - dennoch tut sich nichts 
weiter.
MfG, Robert

von Gerhard. (Gast)


Lesenswert?

Hallo Robert,

mir ist die Library von Dir nicht bekannt. Ich habe mir mal die 
Beispiele von Peter Fleury angesehen und in seiner Library verwendet er 
integrierte I2CREAD Funktion mit ACK oder NACK Eigenschaft. Allerdings 
verwendet er im Vergleich zu Dir die TWI-Hardware des AVRs.

Nur glaube ich nicht dass das im Augenblick Dein Problem ist, da ein 
falscher Gebrauch des ACK/NACK nur den DS1621 verwirrt. Zumindestens ein 
gueltiges Datenpaket muesste durchkommen.

Villeicht stimmt auch irgendwas noch nicht mit Deiner Hardware. 
Ueberpruef noch einmal die Einstellungen der I2C Port pins, pull-up 
Widerstaende. Kurzschluss nach Vdd bei der SDA Leitung, etz.

Schau Dir mal auch die library von Peter Fleury an zum Vergleich:

http://homepage.hispeed.ch/peterfleury/group__pfleury__ic2master.html

Ich habe mir Deine I2c.c library angesehen und bin der Ansicht dass da 
massive Fehler drin sind.

Zum Beispiel in der i2c_start() werden nur die Direction Registers 
manipuliert und nicht der Zustand der SCL/SDA pins. Dafuer ist PORTC da.

Um SDA auf Low zu setzen, muesste man schreiben:

PORTC &= (0 << SDA);

den Pin wieder auf H zu setzen: PORTC |= (1 << SDA);

Die 10ms delay ist nicht notwendig und kann mit NOPS erzielt werden.

Nimm besser die Library von Peter wenn Du TWI Hardware zur Verfuegung 
hast. Wenn es mit emulation gehen muss, dann musst die Deine Library 
verbessern. (Ist die vom Internet? Von wem? ) Welchen Compiler nimmst Du 
her? Dein Quellcode gibt leider keine Auskunft welchen AVR Du 
verwendest.

Vielleicht kann Dir jemand vom Forum besser helfen da ich AVRs nur mit 
CodeVision programmiere und dort gibt es integrierte I2C Libraries die 
garantiert funktionieren.

mfg,
Gerhard

von Robert (Gast)


Lesenswert?

Hallo an alle.
Habe den Fehler gefunden - der Sensor ist defekt. Hab mir ein neues 
Sample schicken lassen und mit dem gehts^^
Den Code hatte ich selbst geschrieben mit WinAVR, ich verwende einen 
Atmega32. Hab noch einiges verändert - aber im Grundprinzip ist der Code 
ähnlich geblieben.
Aber ihr habt natürlich recht - Libraries sind besser, vor allem, wenn 
man das später mal auf nem anderen Mc haben möchte. Wollte jedoch einmal 
selbst probieren und die Basics lernen - was nun zum Glück auch 
funktioniert hat.
Danke nochmal,
Robert

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.