I2C Einstieg PCF8583

Gast #182563
Lesenswert?

Ich hab hier ne PCF8583 Echtzeituhr und würde die gerne an meinem AVR
betreiben.

Ich habe aber leider keine Ahnung von I2C, und möchte fragen ob jemand
infos für einsteiger hat, die Infos sollte halt schon auf der Library
von Peter Fleury basieren.

Ein gut kommentierter Sourcecode tuts auch schon. Halt irgend was mit
dem ich die Funktionsweise begreifen kann.
Gast #182564
Lesenswert?

Hab mir mal folgendes zusammengeschrieben:

uint8_t a;

i2c_start_wait(0xA0);
i2c_write(2);
i2c_rep_start(0xA1);
for (a=0;a<2;a++){
    i2ctime[a] = i2c_readAck();
}
i2c_stop();

Die DCB Werte wandle ich mit folgender Funktion um:

int bcdtobin(int a)
{
    int erg1;
    erg1 = a/16;
    a = a-(erg1 << 4);
    a = (erg1*10)+a;
    return a;
}

Das scheint alles so weit zu funktionieren, bis auf folgendes problem
zwischen den richtigen Werten die von der echtzeituhr kommen, ist immer
mal wieder ne 3 drin. Woran kann das liegen?
Gast #182565
Lesenswert?

Kann mir keiner helfen, bin hier so langsam am verzweifeln. Das komische
ist, ein Speicher der am selben Bus hängt geht ohne Probleme und auch
der Ram Bereich von der Uhr lässt sich ohne fehlerhafte werte auslesen.
Nur bei der Uhrzeit ist immer abwechselnd der Richtige wert und dann ein
anderer(immer der selbe) drinn.
Gast #182567
Lesenswert?

Mhhhh hab das jetzt so erweitert:

void gettime(void)
{

  uint8_t a;

  i2c_start_wait(0xA0);
  i2c_write(0);
  i2c_write(0x40);
  i2c_stop();

  i2c_start_wait(0xA0);
    i2c_write(2);
    i2c_rep_start(0xA1);
  for (a=0;a<3;a++){
    i2ctime[a] = i2c_readAck();
  }
  i2c_stop();

  i2c_start_wait(0xA0);
  i2c_write(0);
  i2c_write(0);
  i2c_stop();
}

es besteht aber leider immer noch das Problem:

Beim ersten auslesen ist die Uhrzeit (Stunden) z.B.

0 (richtig)

beim 2.Mal

45

dann wieder

0

und dann wieder

45

(könnte auch 145 sein hab da ich meine Urzeit auf 2 Stellen begrenze
damit ich ggf ne 0 ranhängen kann)

Kann das villeicht an dem Timing von der i2c Library liegen die hab ich
durch ein "paar" nops provesorisch an meinen 16Mhz Quarz angepasst:

;*********************************************************************** 
**
; delay half period
; For I2C in normal mode (100kHz), use T/2 > 5us
; For I2C in fast mode (400kHz),   use T/2 > 1.3us
;*********************************************************************** 
**
  .stabs  "",100,0,0,i2c_delay_T2
  .stabs  "i2cmaster.S",100,0,0,i2c_delay_T2
  .func i2c_delay_T2  ; delay 5.0 microsec with 4 Mhz crystal
i2c_delay_T2:        ; 4 cycles
  rjmp 1f      ; 2   "
1:  rjmp 2f      ; 2   "
2:  rjmp 3f      ; 2   "
3:  rjmp 4f      ; 2   "
4:  rjmp 5f      ; 2   "
5:   rjmp 6f      ; 2   "
6:  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  nop          ; 1   "
  ret          ; 3   "
  .endfunc     ; total 80 cyles = 5.0 microsec with 16 Mhz crystal * 4 =
80

Es gibt doch bestimmt noch andere i2c Routinen von einem anderen
programmierer oder?
Gast #182569
Lesenswert?

>>for (a=0;a<3;a++){
>>    i2ctime[a] = i2c_readAck();
>>  }

Das letzte read muss ein i2c_readNak() sein:

i2ctime[0] = i2c_readAck();
i2ctime[1] = i2c_readAck();
i2ctime[2] = i2c_readNak();

Falls du einen ATmega mit hardware-TWI verwendest, kann du auch gegen
meine twimaster library linken.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren