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
> 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
1 | #define SDA 1 // SDA Port D, Pin 1
|
2 | #define SCL 0 // SCL Port D, Pin 0
|
3 | #define SDA_PORT PORTC // SDA Port C
|
4 | #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()???
1 | int main(void) { |
2 | |
3 | sei(); |
4 | ...
|
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...?
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
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?
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..
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.
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/
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...
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.
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 =)
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_kann_ich_Zahlen_auf_LCD.2FUART_ausgeben.3F. In meinem Link Zum Pollin-Funkboard oben kannst du das Prinzip auch erkennen.
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.
Hab mir den Artikel hier durchgelesen den du mir gepostet hast. http://www.mikrocontroller.net/articles/FAQ#Wie_kann_ich_Zahlen_auf_LCD.2FUART_ausgeben.3F 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
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).
So: hab das jetzt ales so programmiert...und es funktioniert einwandfrei!!! Danke für deine sehr schnelle und tolle und ausführliche Hilfe Stefan!!!
1 | tempa[0]=(char)Temp/100+'0'; //Umwandlung der 16Bit in ASCII Zeichen |
2 | tempa[1]=(char)(Temp-(tempa[0]-'0')*100)/10+'0'; |
3 | tempa[2]=(char)Temp-(tempa[0]-'0')*100-(tempa[1]-'0')*10+'0'; |
4 | |
5 | |
6 | |
7 | |
8 | set_cursor(1,3); //Setzte Cursor des LCD's in Zeile 3 Balken 1 |
9 | |
10 | if(tempa[0]!='0') //Stellenabfrage |
11 | {
|
12 | lcd_data(tempa[0]); |
13 | }
|
14 | |
15 | |
16 | lcd_data(tempa[1]); //Ausgabe der Umgewandelten Zeichen an des LCD-Display |
17 | lcd_data(tempa[2]); |
18 | lcd_data(','); |
19 | |
20 | if(data==0x80) |
21 | { //Abfrage des Kommawertes |
22 | lcd_data('5'); |
23 | }
|
24 | |
25 | else
|
26 | lcd_data('0'); |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | set_cursor(7,3); |
33 | lcd_string("Grad Celsius"); |
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.