www.mikrocontroller.net

Forum: Mikrocontroller und Elektronik Problem beim auslesen den IIC


Autor: TemperaturDS1621 am LCD ausgeben mit ATmega644 (Gast)
Datum:
Angehängte Dateien:

Hallo alle zusammen

Ich bin mir sicher dass das problem bei mir ein kleines ist jedoch bitte
ich euch mir zu helfen da ich noch recht neu bin hier:

Ich will mir meinem ATmega 644 die Temperatur mittel DS1621 am LCD
ausgeben( in C)

Wenn ihr denkt das ich mich noch niergends durchgegoogelt hab stimmt das
nicht:
Hab schon alles probiert was ich meiner macht steht und halte mich jetzt
an peter fleury libary auserdem hatte einer schon mal ein ähnliches
problem:


Beitrag "Atmega8 - DS1621 auslesen ( über TWI[ i2c])"

Bei mir hängt das Programm wenn er auf einen Interrupt wartet (TWI)
Von dort geht das Programm nicht mehr weiter.
Außerdem hab ich probeirt die Pins für meinen ATMGEA zu denfinieren
damit er ja weiß wo ich die SDA UND SDL hab. auserdem sind die Adress
Pins A0-A4 alle auf GND was heißt das ich die BiTS SDA und SDL mit 0x90
und 0x91 defnier...

Ich bitte euch mir zu helfen weil ich echt nicht merh weiter weiß, wieso
er bei der routinen warte hängen bleibt...

Das Projekt kann ich gerne per Email schicken
Autor: Stefan B. (stefan) Benutzerseite
Datum:

> auserdem sind die Adress
> Pins A0-A4 alle auf GND was heißt das ich die BiTS SDA und SDL mit 0x90
> und 0x91 defnier...

Der DS1621 hat keine Adresspins A3 und A4. Er hat nur A0, A1 und A2.
http://www.datasheetdir.com/DS1621+Temperature-Sensors
Wie ist der Sensor wirklich angeschlossen, wo und wie groß sind die
Pullups (Schaltplan)?

Widersprüchlicher Kommentar in main.c
#define SDA       1    // SDA Port D, Pin 1
#define SCL    0    // SCL Port D, Pin 0
#define SDA_PORT        PORTC           // SDA Port C
#define SCL_PORT        PORTC           // SCL Port C       

Du musst SDA an PC1 hängen und SCL an PC0 und NICHT an Port D wie im
Kommentar oben.

Erste Anweisung in main() ein sei()???
int main(void)  {

    sei();
...    

Das brauchst du sicher nicht.

Vielleicht magst du mal auf die Seite
Pollin Funk-AVR-Evaluationsboard: Temperaturmessung mit DS1621 gehen.
Dort sind Debugausgaben eingebaut. So etwas könntest du in deinen Code
einfügen und berichten wo genau das Programm hängt - vor while(1) oder
danach...?
Autor: TemperaturDS1621 am LCD ausgeben mit ATmega644 (Gast)
Datum:
Angehängte Dateien:

Danke erst mal für deine schnelle antwort

Das mit SDA und SDL ist einer miener hauptprobleme denke ich denn ich
habe ja die libary übernommen non peter f und das kommentar mit port D
hab nur nicht geändert tut mir leid...nur wo stell ich eben ein das sich
alles auf port c abspielt ???
Ich denke mein Hauptproblem besthet darin, dass sich der Tempsensor
nicht angesprochen füllt..

die zeilen
#define SDA_PORT        PORTC           // SDA Port C
#define SCL_PORT        PORTC           // SCL Port C
hab ich aus peter f´s i2cmaster.S rauskopiert weil ich snst niergends im
programm auser in der datei i2cmaster.S eine deklaration für den Port
gefunden habe Brauch ich die überhaupt..??

Da mein Programm beim debuggen bei  der zeile im twimaster.c bei der
programzeile
  // wait until transmission completed
  while(!(TWCR & (1<<TWINT)));
unendlich lange warte dahcte ich mir die interrupts sind nicht
eingeschaltet was ich mit sei() machen wollte...

Im Anhang siehst du meine Pinbelegung für den Tempsensor in Eagle
Pullups mit 4,7 kohm wurdn berücksichtigt
Autor: Stefan B. (stefan) Benutzerseite
Datum:

TemperaturDS1621 am LCD ausgeben mit ATmega644 schrieb im Beitrag
#1679615:

> Das mit SDA und SDL ist einer miener hauptprobleme denke ich denn ich
> habe ja die libary übernommen non peter f und das kommentar mit port D
> hab nur nicht geändert tut mir leid...nur wo stell ich eben ein das sich
> alles auf port c abspielt ???

Das wird von der Library automatisch gemacht. In der Library werden die
entsprechenden Makros aus dem AVR spezifischen Includefile verwendet,
die an dem jeweiligen AVR auf die SDA und SCL Pins im Datenblatt gehen.
Die Library ist nicht dafür gemacht den I2C auf zwei beliebige Pins zu
legen. Der Anwender (du) muss dafür sorgen, dass das I2C Bauteil an den
TWI Pins SDA/SCL richtig angeschlossen ist.

> Ich denke mein Hauptproblem besthet darin, dass sich der Tempsensor
> nicht angesprochen füllt..

Sehe ich auch so und deshalb auch die Frage nach dem Schaltplan. Leider
kann ich das proprietäre Format *.SCH nicht lesen. Ein Screenshot wäre
für mich einfacher zu betrachten (Bildformate beachten).

> die zeilen
> #define SDA_PORT        PORTC           // SDA Port C
> #define SCL_PORT        PORTC           // SCL Port C
> hab ich aus peter f´s i2cmaster.S rauskopiert weil ich snst niergends im
> programm auser in der datei i2cmaster.S eine deklaration für den Port
> gefunden habe Brauch ich die überhaupt..??

Ich denke die brauchst du nicht.

> Da mein Programm beim debuggen bei  der zeile im twimaster.c bei der
> programzeile
>   // wait until transmission completed
>   while(!(TWCR & (1<<TWINT)));
> unendlich lange warte dahcte ich mir die interrupts sind nicht
> eingeschaltet was ich mit sei() machen wollte...

Mit was debuggst du?
Autor: TemperaturDS1621 am LCD ausgeben mit ATmega644 (Gast)
Datum:
Angehängte Dateien:

ok bilddatei is im anhang

Hardwaremäßig sollte aber wirklich alles korrekt sein...
sprich: SDA und SDL gehen auf PC0 bzw PC1 des AVR's.
Also müsste ich wohl auch noch die iom644.h Datei einfügen oder reicht
die normale avr/io.h?
Desweiteren bin ich mir auch nicht wirklich sicher ob ich auch die
interrupt.h brauche!?

Die Zeilen
#define SDA_PORT        PORTC           // SDA Port C
#define SCL_PORT        PORTC           // SCL Port C
habe ich rausgelöscht

Ich verwende AVR Studio4 mit Gnucc und habe mria uch jetzt nochmal genau
das Datenblatt den ATmegas durchgelesen und hab das programm jetzt im
debugger zum laufen gebracht. Dazu habe ich einfach das Interrupt Bit
des TWI gesetzt. Das Programm leif dann Weiter bis zr Zeile:

  // wait until stop condition is executed and bus released
  while(TWCR & (1<<TWSTO));

Laut Datenblatt muss TWSTO auf Null Rückgesetzt werden( ob das von der
Hardware oder Software erledigt wird, weiß ich nicht)

Also läuft das Programm jetzt doch...eben nur Hardwaremßig geht nix weil
eben  denke das das Interrupt Flag nicht gesetzt wird..
Vielleicht endeckst du ja zufällig was bei der Beschaltung..
Autor: stephan_ (Gast)
Datum:

Zum Schaltplan TempDS1621.GIF

I2C_Regel: SDA und SCL brauchen je einen 1k8 (ggf. auch 2k2) Pullup nach
+5V, sind die auf dem µC-Board schon drauf? Der 5k6 ist kontraproduktiv.
Autor: Stefan B. (stefan) Benutzerseite
Datum:

Die "Pullups" R1 und R2 sind falsch installiert. Das durfen keine
Serienwiderstände sein wie im Bild gezeigt. Richtig installiert gehen
die von der SDA (bzw. SCL) Leitung zu Vcc.
http://www.i2c-bus.org/i2c-primer/
Autor: TemperaturDS1621 am LCD ausgeben mit ATmega644 (Gast)
Datum:
Angehängte Dateien:

Danke Stephan_ und Stefan =)
Habe jetzt die Widerstände wie es gehört umgezeichnet
Siehe Anhang
Nur kann ich nicht verstehen wieso ich jetzt einen 2k2 Widerstand nehmen
soll und nicht so wie in PeterF Libary beschriebenen 4,7 ohm nehmen
soll,Im Datenblatt des DS1621 hab ich nirgends über den Widerstand
gelesen. Welche auswirkung hat den ein falscher Widerstandswert?

Dann werd ich mich heute noch gleich ans ätzen der Platine machen...und
mein Glück dann versuchen
Nur:
Auf was wolltest du den genau hinaus Stefan, wie du fragtest welchen
Debugger ich verwende. Und wie sieht es denn jetzt mit den Interrupts
aus?
Muss ich sie jetzt irgdnwie noch im Programm einbauen/verwenden?

Danke für eure schnellen Antworten...
Autor: Stefan B. (stefan) Benutzerseite
Datum:

Debugger

Ich fragte, weil ich wissen wollte, ob du überhaupt eine Chance hast,
einen Wechsel in TWCR zu sehen.

Wenn du nur den AVR Studio Debugger aka Simulator hast, hast du keine
Chance. Du simulierst nur die Software im PC und nicht im AVR. Die
konkrete Hardware hat darauf keinen Einfluß. Du könntest den weiteren
Programmablauf nur simulieren/debuggen, wenn du selbst die Registerwerte
änderst (manuell oder per Steuerdateien s. AVR Simulation).

Um die Wechselwirkung AVR <-> DS1621 real zu debuggen bräuchtest du
einen On-Chip-Debugger z.B. über JTAG (Kapitel 22 im Atmega644
Datenblatt).

Pullups

Die Größe der Pullups (min./max. Werte) ist in den Beschreibungen von
I2C diskutiert: http://www.nxp.com/documents/user_manual/UM10204.pdf

Man kann die dortigen Berechnungen machen oder in der Praxis bewährte
Werte nehmen. Peter Fleury nennt 4K7, anderswo findet man 2K2... IMHO
werden beide Werte funktionieren, das ist an der Stelle erstmal nicht
sooo kritisch. Selbst deine 5K6 werden wohl funktionieren. Wenn du dein
System auf "lange" Leitungen ausbaust und ein schnelle Übertragungsrate
haben willst... dann musst du dir an dieser Stelle wahrscheinlich
Gedanken machen.

Grob falsche Pullups im Verhältnis zum Signaltiming verschleifen dir die
Signale (s. PDF oben) und die Übertragung auf dem Bus wird unzuverlässig
bis unmöglich.

Platine ätzen

Baust du nicht zuerst den Prototypen auf dem Steckbrett oder frei
fliegend auf? Ätzen stünde bei mir erst am Ende der Entwicklung.

Interrupts

Brauchst du für den gezeigten Quellcode nicht. Sie stören aber die
Library auch nicht grundsätzlich, wenn du später dein Programm mit
Interrupts/Timern für andere Zwecke erweitern willst.
Autor: TemperaturDS1621 am LCD ausgeben mit ATmega644 (Gast)
Datum:

Debuggen
Beim Debuggen habe ich wie bereits erwähnt die  Registerwerte
einzeln verändert--> Resulatat war, dass das Programm lief..
Ob ich jetzt noch die Pogrammzeile zum Testen des TWI brauche?

Ausgabe an LCD
Desweiteren stellt sich mir die Frage ob, die Ausgabe des Inhalts der
Temperatur (siehe Programm-->variable data) ohne weiters so ausgeben
kann wie ich es im programm machen. Oder muss ich das Ergebnis noch
irgendwie umwandlen etc??
Da ich ja nur von plusgrade anzeigen möchte und auch auf komma zahlen
verzichten kann hab ich mir gedacht ich kann das eben so einfach machen
(siehe programm)

Werte der Widerstände
Da ich relative kurze Leitungen habe (6 cm) wird es wohl nicht ganz
ausschlaggegebnd sein wenn ich mal 4k/ nehme =)

Ätzen
Da ich ein wenig unter Zeitdruck stehe und diese Temperaturauslesen  in
wenigen tagen fertig sein sollte , und neben bei den ganzen tag schule
habe
werde ich nicht die zeit haben das aufn nem steckbrett zu testen...da
der materialaufwand mir auch nix kostet...den rest kannste die ja
denken...auserdem bin ich fast gelcih schnell =)
Autor: Stefan B. (stefan) Benutzerseite
Datum:

Selbstverständlich brauchst du die Zeile bei der echten Hardware. Die
Zeile ist ja dafür verantwortlich, dass die Daten komplett zwischen
dem DS1621 und dem Atmega644 übertragen werden.

> Ausgabe an LCD
> Desweiteren stellt sich mir die Frage ob, die Ausgabe des Inhalts der
> Temperatur (siehe Programm-->variable data) ohne weiters so ausgeben
> kann wie ich es im programm machen. Oder muss ich das Ergebnis noch
> irgendwie umwandlen etc??

Auf jeden Fall musst du das DS1621 Ergebnis noch aufarbeiten. Zunächst
liest du zwei 8-Bit Werte TempH und TempL. Anders als in deiner Source
musst du beide Bytes zu einem 16-Bit Wert zusammensetzen
(Temp=TempH*256+TempL) und anschliessend in ASCII umwandeln. Den
ASCII-Text kannst du dann ausgeben. Siehe dazu
http://www.mikrocontroller.net/articles/FAQ#Wie_ka....
In meinem Link Zum Pollin-Funkboard oben kannst du das Prinzip auch
erkennen.
Autor: Stefan B. (stefan) Benutzerseite
Datum:

Stefan B. schrieb:

> Zunächst
> liest du zwei 8-Bit Werte TempH und TempL. Anders als in deiner Source
> musst du beide Bytes zu einem 16-Bit Wert zusammensetzen
> (Temp=TempH*256+TempL)...

Korrektur: http://pdfserv.maxim-ic.com/en/ds/DS1621.pdf

Wenn du nur eine Auflösung von 1°C brauchst (der Sensor kann 0,5°C),
reicht es das Highbyte auszulesen. Das Lowbyte kannst du dann verwerfen,
so wie in deiner Source. Die Umwandlung in eine Dezimalzahl im
ASCII-Format brauchst du weiterhin.
Autor: Alex (Gast)
Datum:

Hab mir den Artikel hier durchgelesen den du mir gepostet hast.
http://www.mikrocontroller.net/articles/FAQ#Wie_ka...
Naja klingt garnicht so schwer nur beim schreiben habberts dann ein
wenig:

Ich mag mich auch ein wenig schlau gemacht und hab herausgefunden, dass
ich diese Ausgabe entweder mit der string.h-datei machen kann oder
nicht:

wenn nicht muss ich wie du gesagt hast sagen wir jetzt wenn ich
beispielweise25,5 grad ausgeben will Temp=TempH*256+TempL schreiben..

Um nun in ASCII zu formatieren muss ich auch noch "Temp" auf die
einzelnen Zahlen aufspalten und dann 32 dazuaddieren (zu jeder zahl da
im ASCII-Code Zahlen erst ab 32+n anfangen) danach jede Zahl
nachainander ausgeben dann sollte ich den Tempert haben oder?
Stellt sich mir auch noch die Frage wie was mit dem + bzw - passiert.
möchte das ja weg einfach lassen...

Oder ist es doch einfacher eine libary dazu zu verwenden wenn es die
gibt zb.: string.h?

MFG
Autor: Stefan B. (stefan) Benutzerseite
Datum:

Es ist im Prinzip wurscht, wie du es machst. Bei der Eigenkreation sieht
ein anderer halt eher, ob du das Prinzip verstanden hast :)

Wie sich die Varianten in Codegröße und Ausführungsgeschwindigkeit
unterscheiden kannst du ja einfach prüfen...

Das einfache "Aufaddieren" funktioniert nur, wenn du nur die
Ausgangswerte 0...9 hast, bei den Hexwerten A..F in den Rohdaten (z.B.
bei +125°C mit 0x7D in TempH) klappt das nicht ohne weiteres! Durch
Divisionen mit Zehnerpotenzen wie in meinem Pollinbeispiel kann man
diese Randbedingung sicherstellen.

Jetzt zu deinem konkreten Beispiel und zwei möglichen Herangehensweisen
(ohne Anspruch auf besondere Eleganz oder Effizienz)

Bei 25,5°C liefert der DS1621 ja dieses Bitmuster:
(http://pdfserv.maxim-ic.com/en/ds/DS1621.pdf Tabelle 2)

1. Byte  2. Byte
00011001 10000000

Dein 1. ausgelesenes Byte könnte TempH zugewiesen werden und ist
0b00011001 in Binärdarstellung (bzw. 0x19 in Hexdarstellung und 25 in
Dezimaldarstellung)

Das 2. ausgelesenes Byte könnte TempL zugewiesen werden und ist
0b10000000 in Binärdarstellung (bzw. 0x80 in Hexdarstellung und 128 in
Dezimaldarstellung)

Du hast jetzt mehrere Möglichkeiten wie du weitergehen kannst. Hier ein
Weg für den Umgang mit platzsparender Ganzzahlrechnung:

Fixkommarechnung

1. Byte  2. Byte
00011001 10000000
^

Das markierte Bit sagt dir, welches Vorzeichen auszugeben ist: 1 dann
negative Zahl, 0 dann positive Zahl.

if ( TempH & 0x80 )
{
  lcd_data('-');
  TempH = -TempH; // negative Zahl ins positive wandeln
}
else
  lcd_data('+'); // oder nix ausgeben. "Geschmackssache sagt der Affe"

1. Byte  2. Byte
00011001 10000000
^^^^^^^^

Das 1. Byte sagt dir, welche Vorkommazahl auszugeben ist.

// % siehe modulo Operator
lcd_data( (TempH / 100) + '0' ); // Hunderterstelle ausgeben
TempH %= 100;                    // Hunderterstelle entfernen
lcd_data( (TempH / 10) + '0' );  // Zehnerstelle ausgeben
TempH %= 10;                     // Zehnerstelle entfernen
lcd_data( TempH + '0' );         // Einerstelle ausgeben

1. Byte  2. Byte
00011001 10000000
         ^

Das markierte Bit sagt dir, ob du eine .5 oder eine .0 als
Nachkommazahl ausgeben sollst. 1 dann .5, 0 dann .0

lcd_data( ',' );         // Komma ausgeben
if ( TempL & 0x80 )
  lcd_data('5');
else
  lcd_data('0');

Fertisch mit Vorzeichen und Nachkomma. Wenn du Feinheiten einbauen
willst, kannst du dir überlegen, wie du führende Nullen bei der
Hunderterstelle und Zehnerstelle unterdrücken kannst.

Fließkommarechnung

Hier wird der Wert aus dem 1. und 2. Byte zusammengesetzt, in eine
Gleitkommazahl umgewandelt und durch Division so rechtsbündig gemacht.

{
  float Temp = (float)(TempH*256 + TempL) / 256;
  char puffer[42]; // Länge geschätzt
  sprintf(puffer, "Temperatur %f Grad C", Temp);
  lcd_string(puffer);
}

Diese Variante benötigt besondere Projekteinstellungen für die
Fließkomma-Libraries (s. FAQ).
Autor: Alex (Gast)
Datum:

So: hab das jetzt ales so programmiert...und es funktioniert
einwandfrei!!!

Danke für deine sehr schnelle und tolle und ausführliche Hilfe Stefan!!!

tempa[0]=(char)Temp/100+'0';                  //Umwandlung der 16Bit in ASCII Zeichen
                  tempa[1]=(char)(Temp-(tempa[0]-'0')*100)/10+'0';
                  tempa[2]=(char)Temp-(tempa[0]-'0')*100-(tempa[1]-'0')*10+'0';
                  
                  

        
                  set_cursor(1,3);      //Setzte Cursor des LCD's in Zeile 3 Balken 1

                  if(tempa[0]!='0')      //Stellenabfrage 
                    {  
                      lcd_data(tempa[0]);
                    }


                    lcd_data(tempa[1]);      //Ausgabe der Umgewandelten Zeichen an des LCD-Display
                  lcd_data(tempa[2]);
                  lcd_data(',');
                  
                  if(data==0x80)  
                    {            //Abfrage des Kommawertes 
                      lcd_data('5');
                    }

                  else 
                    lcd_data('0');
                    
                  
      


                  set_cursor(7,3);
                  lcd_string("Grad Celsius");

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




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 erkennst du die Nutzungsbedingungen an.

webmaster@mikrocontroller.netImpressumNutzungsbedingungenWerbung auf Mikrocontroller.net