Hi, Hier mal der code, den ich mit dem 24AA1025 verwendet habe:
Code:
#define ADR_EEPROM1_TX b'10100000'
#define ADR_EEPROM1_RX b'10100001'
eeprom Lesen
DATEN_LESEN_B2
; bcf INTCON,GIE
call I2C_WAIT_EEPROM_NOT_BUSY_B2 ; Weiter, wenn eeprom nicht busy
call I2C_ON_B2
movlw ADR_EEPROM1_TX ; EEPROM zum Schreiben Adressieren
call I2C_TX_B2
movfw EEPROM_ADR_HBYTE ; Speicheradresse Senden
call I2C_TX_B2
movfw EEPROM_ADR_LBYTE
call I2C_TX_B2
call I2C_RESTART_B2 ; Restart
movlw ADR_EEPROM1_RX ; EEPROM zum Lesen Adressieren
call I2C_TX_B2
call I2C_RX_B2 ; Datenbyte Empfangen
movfw SSPBUF ; speichern
movwf STARTBYTE;1
call I2C_ACK_B2 ; ACK Senden
.
.hier lese ich eigentlich noch ca.30 weitere bytes ein
.
.
call I2C_RX_B2 ; Datenbyte Empfangen
movfw SSPBUF ; speichern
movwf KRAFT_BCD_Z;32
call I2C_ACK_B2 ; ACK Senden
call I2C_RX_B2 ; Datenbyte Empfangen
movfw SSPBUF ; speichern
movwf KRAFT_BCD_E;33
call I2C_NACK_B2 ; NOT- ACK Senden
call I2C_OFF_B2 ; Bus freigeben
return
;**********************************************************************************************************
; eeprom beschreiben
;Datensatz Speichern
call I2C_WAIT_EEPROM_NOT_BUSY_B2 ; Weiter, wenn eeprom nicht busy
call I2C_ON_B2
movlw ADR_EEPROM1_TX ; EEPROM zum Schreiben Adressieren
call I2C_TX_B2
movfw EEPROM_ADR_HBYTE ; Speicheradresse Senden
call I2C_TX_B2
movfw EEPROM_ADR_LBYTE
call I2C_TX_B2 ;datensatz senden
movfw DATUM_BCD_Z
call I2C_TX_B2
movfw DATUM_BCD_E
call I2C_TX_B2
movfw MONAT_BCD_Z
call I2C_TX_B2
movfw MONAT_BCD_E
call I2C_TX_B2
movfw JAHR_BCD_Z
call I2C_TX_B2
movfw JAHR_BCD_E
call I2C_TX_B2
.
.
.
.
movfw KRAFT_BCD_ZT
call I2C_TX_B2
movfw KRAFT_BCD_T
call I2C_TX_B2
movfw KRAFT_BCD_H
call I2C_TX_B2
movfw KRAFT_BCD_Z
call I2C_TX_B2
movfw KRAFT_BCD_E
call I2C_TX_B2
call I2C_OFF_B2 ; Busfreigabe
call I2C_WAIT_EEPROM_NOT_BUSY_B2 ; Warten, bis speichervorgang abgeschlossen ist
return
;**********************************************************************************************************
;**********************************************************************************************************
; I2C Unterprogramme
;
; I2C Bus im Master Mode Übernehmen
I2C_ON_B2
bcf PIR1, SSPIF ; Interrupt flag löschen
bsf STATUS, RP0
bsf SSPCON2, SEN ; Bus übernahme anweisen
bcf STATUS, RP0
goto I2C_WARTE_B2
; I2C Bus Restart
I2C_RESTART_B2
bcf PIR1, SSPIF ; Interrupt flag löschen
bsf STATUS, RP0
bsf SSPCON2, RSEN ; Bus Restart anweisen
bcf STATUS, RP0
goto I2C_WARTE_B2
; ein Byte aus W senden
I2C_TX_B2
movwf SSPBUF ; -> zum I2C-Slave übertragen
goto I2C_WARTE_B2
;ein Byte vom Slave empfangen (nach SSPBUF)
I2C_RX_B2
bsf STATUS, RP0
bsf SSPCON2, RCEN ; Daten Empfang einschalten
bcf STATUS, RP0
goto I2C_WARTE_B2
; Warte, bis eeprom nicht busy
I2C_WAIT_EEPROM_NOT_BUSY_B2
bcf STATUS,RP0
call I2C_RESTART_B2
movlw ADR_EEPROM1_TX
call I2C_TX_B2
bsf STATUS,RP0
btfsc SSPCON2,ACKSTAT ; Wenn ACK empfangen: BEENDEN
goto I2C_WAIT_EEPROM_NOT_BUSY_B2
bcf STATUS,RP0
call I2C_OFF_B2
nop
nop
nop
nop
return
;ein Byte vom Slave empfangen (nach SSPBUF)
I2C_ACK_B2
bsf STATUS, RP0
bcf SSPCON2, ACKDT
bsf SSPCON2, ACKEN ; ACK senden
bcf STATUS, RP0
goto I2C_WARTE_B2
;ein Byte vom Slave empfangen (nach SSPBUF)
I2C_NACK_B2
bsf STATUS, RP0
bsf SSPCON2, ACKDT ; NOTACK senden
bsf SSPCON2, ACKEN
I2C_NACK1_B2
btfsc SSPSTAT,R_W
goto I2C_NACK1_B2
bcf STATUS, RP0
goto I2C_WARTE_B2
; I2C-Bus wieder freigeben
I2C_OFF_B2
bsf STATUS, RP0
bsf SSPCON2, PEN ; Bus Freigabe anweisen
bcf STATUS, RP0
I2C_WARTE_B2
btfss PIR1, SSPIF ; SSPIF == 1 ?
goto I2C_WARTE_B2 ; nein->sprung
bcf PIR1, SSPIF ; SSPIF =0
return
;**********************************************************************************************************
wichtig ist, dass du beim lesen nach dem senden der Speicheradresse einen RESTART sendest das ist zwar prinzipiell das gleiche wie ein STOP gefolgt von einem START aber der zeitliche ablauf ist dabei einzuhalten. also: restart verwenden.
ausserdem verwende ich vor jedem Zugriff eine funktion, die das ACHNOWLEDGE Polling durchführt und damit sicherstellt, dass das eeprom nicht noch mit schreiben beschäftigt ist.
Ich dachte auch erst, dass mein eeprom def ist, lag aber dann doch an der ansteuerung meinerseits.... so wie das doch meistens ist...
habe auch noch ein PDF von microchip angehängt, in dem der umgang mit pic und eeprom über I2C erklärt anschaulich mit code-beispielen weklärt wird. -- doch nicht. das pdf ist mit ~650kb zu gross aber ich sende es dir per e-mail, wenn du mir deine Adresse zukommen lässt...
Lesezeichen