Hallo Leute Bin im Rahmen meiner Technikerarbeit dabei einen Datenlogger zu realisieren. Habe den AT89C51ED2 und folgende I2C Bausteine : DS1307 real-time-clock M24C64 EEPROM ADS7828 ADU und versuche schon seid 4 Wochen die Uhrzeit aus meinem DS1307 auszulesen. Ich bekomme es geregellt alle Bausteine anzusprechen (Bekomme von jedem Baustein ein Acknoledge) und auch das schreiben stellt kein problem dar. Aber ich bekomme es nicht geregelt aus dem EEProm oder dem DS1307 Daten auszulesen. Ich kenne die Datenblätter bereits sogut wie auswendig und bin auch der Meinung alles verstanden zu haben. Aber sobald ich Daten auslesen will bekomme ich nur Müll. Es hängt genau an der Stelle an der ich eine neue Start-Bedingung herstelle die slave-adresse + read auf den Bus lege.Dann bekomme ich noch ein Acknoledge dieses bestätige ich und takte dann die Daten raus Ich hoffe das ich nur einen kleinen Denkfehler mache, hat jemand eine Idee was ich falsch machen könnte ? Ich versuche das ganze noch zu Fuß über ein spezielles Board mit dem ich die high oder low Zustände über zwei Schalter auf SDA und SCL legen kann. Da über den Atmel und meine I2c routinen auch noch nichts geht. Hiiiilllllllllllllffffffffffffee Ihr seid meine letzte Hoffnung Ciao Benny
Hallo Leidensgenosse ;-), also erst mal ich habe eben mal meine DS1307 Uhr rausgekrammt und nach etwas Gefummel tut die nu auch. Das erste wo vielleicht der Fehler liegen könnte ist das, dass raustakten mit der Hand, wie Du es im Moment machst, für den I2C zu langsamm ist. Ich weiß zwar das er bis max 400kHz kann aber wie es nach unten aussieht weiß ich leider nicht(also ob es sowas wie ne Mindestgeschwindigkeit gibt) Andere Möglichkeit wäre noch das Du die HW vielleicht falsch verschaltet hast. Grüßle Jochen
Hallo, wenn Du eine andere real-time-clock nehmen kannst, so besuch mal http://www.cc2net.de. Dort gibt es viele I2C - Lösungen. Als real-time-clock nimmt man da den PCF8583. I2C Treiber stehen unter http://www.cc2net.de/Module/module.html. Vielleicht hilft es weiter. Gruss Klaus.
Erst mal vielen Danke für eure Hilfe !!! Also das mit der mindest Geschwindigkeit hatte ich schon abgeklärt. Da gibt es keine Probleme das ist den Bausteinen völlig Wurst. Und den Baustein zu wechseln bringt mir auch nichts da ich den schon im Pflichtenheft stehen habe und es leider mit dem eeprom auch nicht klappt (das aller gleiche Problem) deshalb glaube ich das ich einen Grundsätzlichen Fehler mache. Beim ADU bei dem ich keine Speicheradressen ansprechen muss klappt´s übrigens. Beschaltung wurde auch schon von mehreren unbeteiligten überprüft, die haben auch keinen Fehler gefunden. Wir machen die Technikerarbeit zu zweit und haben daher die Bauteile doppelt bestellt die müssten also auch ok sein. Könnte vieleicht einer ein C-Programm posten das bei Ihm funktioniert hat ? Ganz simpel ohne Ihrgendwelche funktionen wie z.B. I2C (da wir die funktionen vieleicht nicht haben) alles per hand SDA =1 SCL=1 "schreiben in eine Speicherzeile und wider auslesen mit Start-Bedingung usw" auslesen je einfacher desto besser. Hoffe das wir wenns funzt dann unseren Fehler aus diesem Programm rauslesen können Ciao Benny
Huhu Benny, Also ganz so Low-Level hab ich keinen Code. Kann Dir aber hier mal Posten was ich mit I2C Funktionen verwende. Die I2C funktionen machen dann aber auf Low-Level Ebene auch nur das was im Datenblatt steht. unsigned int ret; //Senden der I2C Startbedienung mit der Addresse des EEPROMs //chip_adr = 0xA0 für EEPROM 0xD0 Für RTC //mem_adr = Die Adresse die gelesen werden soll ret = i2c_start(chip_adr+WRITE); if ( !ret ) { //Senden der zu lesenden Speicherstelle i2c_write(mem_adr); //Senden der I2C Wiederholten-Startbedienung mit der Addresse des EEPROMs ret = i2c_rep_start(chip_adr+READ); if ( !ret ) { //Einlesen der Daten back = i2c_readNak(); } else { //Fehler Routine wenn Chip nicht erreicht werden kann } } else { //Fehler Routine wenn Chip nicht erreicht werden kann } Also wenn Du mit der obigen Code z.B. die Speicherstelle 0x0000 des EEPROMS lesen willst musst du als chip_adr 0XA0 und als mem_adr 0x00 übergeben. Für die Speicherstelle 0x027F wäre es analog dazu chip_adr = 0xA4 und mem_adr= 0x7F. Hoffe das hilft Dir vielleicht weiter. Grüßle Jochen P.S. auf meiner HP http://www.rurlaender.net/ Habe ich eine Library zum auslesen bzw. schreiben eines I2C EEPROMS liegen. Ist allerdings auf Basis des i2cmasters und für ein atmega.
Hallo Leute Die Library funktioniert leider nicht mit unserem compiler (Ride Version 6.10.15) bringt meldung das das nur mit einem ATM GCC compiler funzt Mit diesen Funktionen arbeiten wir bis jetzt RTC.h ************************************************************************ ***********/ /* */ /* Funktionen zur Ansteuerung des DS1307 RealTimeClocks */ /* ---------------------------------------------------- */ /* */ */ /* Version 1.0 */ /* */ /*********************************************************************** ************/ //********************** Definitionen *************** //#define adr_lies 0xD1 // Adresse ueber die auf den DS1307 geschr. wird //#define adr_schreib 0xD0 // Adresse ueber die auf den DS1307 geschr. wird char system_time_ss; char system_time_mm; char system_time_hh; char system_time_dayofweek; char system_time_day; char system_time_month; char system_time_year; //****************************** Funktionen **************************************** /*********************************************************************** ************/ /* Fkt. rtc_bcd_to_hex: wandelt BCE zu HEX Zahl um */ /* */ /*********************************************************************** ************/ char rtc_bcd_to_hex(char v) { char n; n=v; n=n & 0xF0; n=n/16; v =v & 0x0F; n=n*10+v; return(n); } /*********************************************************************** ************/ /* Fkt. rtc_hex_to_bcd: wandelt HEX zu BCD Zahl um */ /* */ /*********************************************************************** ************/ char rtc_hex_to_bcd(char v) { char n; n=v; n=n/10; n=n*16; v =v % 10; n=n+v; return(n); } /*********************************************************************** ************/ /* Fkt. write_rtc_ram: Schreibt ein Byte ueber I2C auf den DS1307 */ /* */ /*********************************************************************** ************/ char write_rtc_ram(char ad,char d) { d=rtc_hex_to_bcd(d); starti2c(); ausgabei2c(adr_schreib); ausgabei2c(ad); ausgabei2c(d); stoppi2c(); //delay_ms(11); _nop_(); } /*********************************************************************** ************/ /* Fkt. read_rtc_ram: Liest ein Byte ueber I2C aus dem DS1307 */ /* */ /*********************************************************************** ************/ char read_rtc_ram(char ad) { char d; starti2c(); ausgabei2c(adr_schreib); ausgabei2c(ad); starti2c(); ausgabei2c(adr_lies); d= einleseni2c(1); stoppi2c(); d=rtc_bcd_to_hex(d); return(d); } /*********************************************************************** ************/ /* Fkt. gettime: Liest Sekunden, Minuten und Stunden ein */ /* */ /*********************************************************************** ************/ void gettime() { system_time_ss = read_rtc_ram(0); _nop_();//5 system_time_mm = read_rtc_ram(1); _nop_();//5 system_time_hh = read_rtc_ram(2); _nop_();//5 system_time_dayofweek = read_rtc_ram(3); _nop_();//5 system_time_day = read_rtc_ram(4); _nop_();//5 system_time_month = read_rtc_ram(5); _nop_();//5 system_time_year = read_rtc_ram(6); } /*********************************************************************** ************/ /* Fkt. init_uhr: Initialisiert den DS1307 */ /* Achtung nach einem Stromausfall wird init_uhr() aufgerufen, da der DS1307*/ /* Batterie gepuffer ist darf nicht alles geresettet werden!! */ /*********************************************************************** ************/ void init_uhr() { system_time_mm = read_rtc_ram(0); // alten Minutenwert vor dem ueberschreiben Lesen write_rtc_ram(0x00,00); // CH=0 write_rtc_ram(0,system_time_mm); // alten Minutenwert wieder speichern system_time_hh = read_rtc_ram(2); // alten Stundenwert vor dem ueberschreiben Lesen write_rtc_ram(0x02,00); // auf 24h Mode stellen write_rtc_ram(2,system_time_hh); // alten Stundenwert wieder speichern write_rtc_ram(0x07,00); //OSC ON } /*********************************************************************** ************/ /* Fkt. set-Funktionen: um alle Parameter zu schreiben. */ /* */ /*********************************************************************** ************/ void setsecond(char d) {write_rtc_ram(0,d);} void setminute(char d) {write_rtc_ram(1,d);} void sethour(char d) {write_rtc_ram(2,d);} void setdayofweek(char d){write_rtc_ram(3,d);} void setday(char d) {write_rtc_ram(4,d);} void setmonth(char d) {write_rtc_ram(5,d);} void setyear(char d) {write_rtc_ram(6,d);} void sqw(char d) {write_rtc_ram(7,d);} und mit der header Datei I2C.h #include <c51rd2.h> /* Registerdefinitionen */ #include <intrins.h> /* für Rotationsfunktion */ #include <stdio.h> /*Standart Ein/Ausgabe Funktionen*/ /****** verwendete Adressen und Kontrollbyte für den AD- und DA-Umsetzter ******************/ unsigned char adr_lies = 0xD1; /* 10010001 -> 11010001 */ unsigned char adr_schreib = 0xD0; /* 10010000 -> 11010000 */ /****** verwendete I2C-Leitungen **********************************************************/ sbit daten = P3^5; /* 0xB5 P3.5 = SDA, i2c-Datenleitung */ sbit clock = P3^4; /* 0xB4 P3.4 = SCL, i2c-Taktleitung */ /*********************************************************************** *******************/ sbit acc7 = ACC^7; /* für Aus- und Eingabe eines Bits des Akkus */ /*********************************************************************** ******************* * I2C-Bus-Funktionen initi2c, starti2c, stoppi2c, ausgabei2c, einleseni2c auch für andere * I2C-Bus-ICs verwendbar ************************************************************************ ****************** /****** Startbedingung I2C-Bus ************************************************************/ void starti2c (void) { daten = 1; clock = 1; daten = 0; clock = 0; } /****** Stoppbedingung I2C-Bus ************************************************************/ void stoppi2c (void) { clock = 1; daten = 1; } /*********************************************************************** ******************* * Byte ausgeben an I2C-Bus , Rückgabewert = Acknoledgebit = 1 wenn erfolgreich ************************************************************************ ******************/ bit ausgabei2c (unsigned char byte) { unsigned char z; /* Zähler */ bit ack; /* Acknoledge-Bit */ ACC = byte; /* Rotationsregister Akku */ for (z = 8; z != 0; z --) /* Zähler: serielle Ausgabe von 8 Bit */ { daten = acc7; /* Bit7 des Akku ausgeben */ nop (); clock = 1; /* Daten sind gültig */ ACC = crol (ACC,1); /* links rotieren, Funktion von intrins.h */ clock = 0; /* Datenausabe beendet */ } daten = 1; /* Leitung freigeben für Acknoledge-Bit */ nop (); clock = 1; /* Slave kann bestätigen */ nop (); /* warten */ ack = daten; /* Acknoledge-Bit lesen */ clock = 0; /* Slave soll Ackn-Ausgabe beenden */ return (ack); /* Acknoledge-Bit ist Rückgabewert der Funktion */ } /*********************************************************************** ******************* * Byte einlesen vom I2C-Bus. Bei Ack=1 wird Acknoledgebit gesendet, sonst nicht ************************************************************************ ******************/ unsigned char einleseni2c (bit ack) { unsigned char z,byte; daten = 1; /* Leitung freigeben (high) für Daten */ for (z = 8; z != 0; z --) /* Zähler: serielles Einlesen von 8 Bit */ { clock = 1; /* Daten sind gültig */ nop (); acc7 = daten; /* Datenbit in den Akku */ ACC = crol (ACC,1); /* links rotieren, Funktion von intrins.h */ clock = 0; /* Daten lesen beendet */ } byte = ACC; /* Eingelesenes Byte */ if (ack == 1) {daten = 0;} /* Acknowledge-Bit senden */ else {daten = 1;} /* kein Acknowledge-Bit */ nop (); clock = 1; /* Ackn. gültig */ clock = 0; /* Ackn. beendet */ nop (); daten = 0; /* Leitung nicht mehr frei für Daten */ return (byte); /* eingelesenes Byte = Rückgabewert */ } /*********************************************************************** ******************* /* _nop_() /*********************************************************************** *******************/ void nop (void) { int i; for(i=1;i=30000;i++) { } } Wenn Ihr es in den compiler kopiert müsste es lesbar sein
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.