Forum: Mikrocontroller und Digitale Elektronik DS1337 mittels "AVR TWI/I2C MASTER in C" abfragen


von D a v i d K. (oekel) Benutzerseite


Lesenswert?

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
von D a v i d K. (oekel) Benutzerseite


Lesenswert?

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

von Joachim B. (jar)


Lesenswert?

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
Noch kein Account? Hier anmelden.