Hallo Christian,
komme leider, da noch bis nächste Woche im Urlaub, nicht dazu es genauer zu prüfen, da hier am Ort einfach alles fehlt.
Init habe ich mal geschaut, denke bist trotz errata deutlich unter 100 khz, da fehlen mir aber jetzt auch die Zugriffe auf die PDF's.
Eventuell kannst Du ja etwas ausschließen, deshalb mal als Vergleich eine Auszug aus dem Quellcode der 16F876 Steuerung 4 Mhz (XT)
- Init
- 1 Byte schreiben
- 10 Byte einzelnd lesen
- I²C Unterprogramme
Gruß André
Code:
;*************************************************************************************************
;Clock 4 Mhz 16F876 (XT)
#define Bank_0 bcf STATUS,RP0
#define Bank_1 bsf STATUS,RP0
;*************************************************************************************************
INIT
;PORT C initialisieren (RS232 TX als Ausgang)
bsf STATUS,RP0 ; Bank 1
movlw B'10111110' ; Pin als Eingänge/Ausgänge
movwf TRISC
bcf STATUS,RP0 ; Bank 0
clrf PORTC ; Pin loeschen
;******* I²C Takt einstellen
Bank_1
movlw d'4' ; clock=4000/4*(7+1) ohne Errata
movwf SSPADD ; für I²C
Bank_0
;******* I²C Bus aktivieren und einschalten
movlw B'00001000' ; master Mode, clock=Fosc/(4*(SSPADD+1))
movwf SSPCON
bsf SSPCON,SSPEN ; einschalten
;------------------------------------------------------------------------------------------------
;*************************************************************************
MAIN
;********* 1 Byte Info auf I²C Speicher-Karte schreiben
Info clrwdt
call i2c_on ; I²C Bus übernehmen
movlw b'10100000' ; adressieren für Karte
call i2c_tx ; zum schreiben
movlw d'0'
call i2c_tx ; high Adresse Speicherplatz
movlw d'9'
call i2c_tx ; low Adresse Speicherplatz
movlw h'35' ; Merker für Karte voll
call i2c_tx ; low Adresse Speicherplatz
call i2c_off ; BUS freigeben
call pause_02 ; fertig schreiben lassen (Pause 10ms - Karte)
return
;******** 10 Byte (einzelnd) von I²C Speicher-Karte lesen
Info_holen movlw d'0' ; Byte 1 beginnen
movwf z1
movlw d'10' ; 10 Byte lesen
movwf z
movlw 0x20 ; Adressierung wieder auf 20
movwf FSR ; Index
weiter_lesen clrwdt ; Watch-Dog löschen
call i2c_on ; I²C Bus übernehmen
movlw B'10100000' ; zum schreiben adressieren
call i2c_tx
movlw d'0' ; high Teil Adresse
call i2c_tx ; senden
movfw z1 ; low Teil Adresse
call i2c_tx ; senden
call i2c_off ; BUS freigeben
call i2c_on ; Bus wieder übernehmen
movlw B'10100001' ; zum lesen adressieren
call i2c_tx
call i2c_rx ; Byte lesen
bcf STATUS,IRP ; bit für Bank 1 und 0 bei FSR
movwf INDF ; sichern in adresse
call i2c_off ; BUS freigeben
decfsz z,1 ; schon 10 byte gelesen
goto ww_1
goto absprung ; -> ja weiter
ww_1 incf FSR,1 ; erhöhe Indexzeiger
incf z1,1 ; erhöhe low Adresse von Karte
goto weiter_lesen
absprung movfw ...
;----------------------------------------------------------------------------------------------
;*************************************************************************************
;******** I²C-Bus übernehmen
i2c_on bcf PIR1,SSPIF ; SSPIF BIT löschen
bsf STATUS,RP0
bsf SSPCON2,SEN ; Bus übernehmen anweisen
bcf STATUS,RP0
ok_1 btfss PIR1,SSPIF ; Testen ob BUS schon übernommen
goto ok_1
bcf PIR1,SSPIF ; ja der Bus ist übernommen
return
;******** I²C-BUS freigeben
i2c_off bsf STATUS,RP0
bsf SSPCON2,PEN ; Busfreigabe anweisen
bcf STATUS,RP0
ok_2 btfss PIR1,SSPIF ; Bus schon frei
goto ok_2 ; nochmal
bcf PIR1,SSPIF ; ja alles OK
return ; Rücksprung ohne Fehler
;******** I²C-Bus senden
i2c_tx movwf SSPBUF ; -> zum Slave übertragen
ok_3 btfss PIR1,SSPIF ; ACK schon empfangen
goto ok_3 ; nein noch nicht
bcf PIR1,SSPIF ; ja, nun rücksetzen
return
;******** I²C-Bus empfangen
i2c_rx bsf STATUS,RP0
bsf SSPCON2,RCEN ; Datenempfang einschalten
bcf STATUS,RP0
ok_4 btfss PIR1,SSPIF ; Datenempfang fertig?
goto ok_4 ; nein noch nicht
bcf PIR1,SSPIF ; ja, noch zurücksetzen
movfw SSPBUF ; Empfangsregister lesen
return
Lesezeichen