Hi, ich versuche gerade die Funktionen einer veralteten BASCOM Programmierung in C umzuformen. Dabei beginne ich von ganz vorne :) Die Hardware steht in 3-Facher Ausführung zur Verfügung und lief bereits einige Jahre erfolgreich (Fehler an dieser Stelle können also augeschlossen werden). Ich habe mit den Tastern, LEDs und dem SAA1064 angefangen, auf welchem nun bereits ein 4stelliger Counter seine Endlosrunden dreht. Ich habe mir erlaubt von hier http://www.mikrocontroller.net/articles/I²C#Bibliotheken die http://homepage.hispeed.ch/peterfleury/avr-software.html zu verwenden. Nun zum Problem: Was mit dem SAA1064 und beim Senden noch problemlos funktioniert, lässt mich beim DS1337 ein wenig verzweifeln. Laut Datenblatt Seite 8 Tabelle2, sollte die Adresse für Sekunden doch 0x00 lauten!? Wieso könnte der folgende Code dennoch falsch sein? void receiveClock(){ i2c_start_wait(0x00+I2C_READ);// set device address and write mode seconds = i2c_readNak();// read one byte minutes = i2c_readNak(); hours = i2c_readNak(); i2c_stop(); } Weihnachtsliche Grüße Oekel PS: etwas Offtopic, aber der SAA1064 ist ja ausgelaufen, daher suche ich bereits ein Mehrzeilendisplay mit I2C Ansteuerung , welches in etwa die gleiche Baugröße hat wie die 4x7-Segmentanzeige und nicht wesentlich mehr kostet. Wenn da Jemand eine Idee hat wäre ich über einen Hinweis sehr dankbar.
:
Verschoben durch User
Ok, habs mittels BruteForce erledigt ;P void findTWI(){ for(uint8_t i = 0; i<=255; i++){ uint8_t ret = i2c_start(i+I2C_READ); if ( ret ) { /* failed to issue start condition, possibly no device found */ i2c_stop(); send4x7(BRIGHT1, MINUS, MINUS, MINUS, MINUS); _delay_ms(30); }else { ret = i2c_readNak(); i2c_stop(); display1234(i);// uses send4x7(...) _delay_ms(3000); } } } Das result auf meinem Display ist nicht 42 ;) sondern 208 (0xD0). Trotzdem bin ich noch nicht 100% klar im Kopf, denn ich dachte die Slave Adresse fürs lesen und schreiben wäre eine separate? jedoch muss ich in scheinbar beiden fällen die gleiche Adresse verwenden: 0xD0+I2C_READ//==1 0xD0+I2C_WRITE//==0 So und wenn ich NUN noch mal ins Datenblatt des DS1337 schaue endecke ich auch ein 0b1101000(0) (==208==0xD0). Nicht ganz fair dies als 7Bit Muster darzustellen und nur mitten in einer Grafik zu erwähnen. Bin da echt besseren Stil (z.B. gleich am Anfang des Datenblattes) bei I2C-Komponenten gewöhnt. Grüße Oekel
D a v i d K. schrieb: > Wieso könnte der folgende Code dennoch falsch sein? > > void receiveClock(){ > i2c_start_wait(0x00+I2C_READ);// set device address and write mode > seconds = i2c_readNak();// read one byte > minutes = i2c_readNak(); > hours = i2c_readNak(); > i2c_stop(); > } weil: wenn du noch weitere Bytes lesen willst darf kein _readNAK() sein
1 | while(_i2c_busy); |
2 | if(!i2c_start(DS3231+I2C_WRITE)) // set device address and write mode |
3 | {
|
4 | do
|
5 | { i2c_write(SECONDS); // write address = SECONDS |
6 | i2c_rep_start(DS3231+I2C_READ); // set device address and read mode |
7 | _rtc_t[2]=bcdtoint(i2c_readAck()&0x7f); // sekunden |
8 | _rtc_t[1]=bcdtoint(i2c_readAck()&0x7f); // minuten |
9 | _rtc_t[0]=bcdtoint(i2c_readAck()&0x3f); // stunden |
10 | _rtc_d[4]=i2c_readAck()&7; // wt |
11 | _rtc_d[0]=bcdtoint(i2c_readAck()&0x3f); // tag |
12 | _rtc_d[1]=i2c_readAck(); // monat mit CENTURY |
13 | _rtc_d[2]=i2c_readNak(); // jahr |
14 | i2c_stop(); |
15 | |
16 | if(_rtc_d[1] & (1<<CENTURY)) |
17 | _rtc_d[3]=1; |
18 | else
|
19 | _rtc_d[3]=0; |
20 | |
21 | _rtc_d[2] &= ~(1<<CENTURY); |
22 | _rtc_d[2] = bcdtoint(_rtc_d[2]); |
23 | _rtc_d[1]=bcdtoint(_rtc_d[1]&0x1f); // monat nach CENTURY |
24 | }while(_rtc_t[2]==59); // sicherheitshalber nicht in Sekunde 59 ! |
25 | }
|
i2c_readNak(); kommt immer zum Schluss
:
Bearbeitet durch User
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.