mikrocontroller.net

Forum: Compiler & IDEs DS1621 ueber I2C ansteuern


Autor: Robert (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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:
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();
  
  i2c_start();
  i2c_transmit_byte(0x90);
  i2c_transmit_byte(0xAA); // Sensor soll die Temperatur zurueckgeben
  _delay_ms(10);
  while(1)
  {
    i2c_start();
    i2c_transmit_byte(0x91);
    temp1=i2c_receive_byte();
    temp2=i2c_receive_byte();
    i2c_stop();
    USART_String_Transmit(itoa(temp1,s,10));
    USART_String_Transmit(itoa(temp2,s,10));
    _delay_ms(100);
  }
  
}

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

Autor: holger (Gast)
Datum:

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


Fehlt da nicht ein Stop?

Autor: Robert (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Gerhard. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Robert (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Robert (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Gerhard. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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__pfle...

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

Autor: Robert (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.