Ho un grosso problema con il protocollo I2C. Sto leggendo da una eeprom 24LC02 con un PIC 16F84A che va a 4 Mhz. Anche se non ha il protocollo implementato, ho letto le specifiche MicroChip e le rel.notes con gli esempi e la libreria, che ho usato nel
mio prg. La scrittura =E8 ok, vale a dire che se gli impongo di scrivere un certo
byte ad un certo indirizzo poi leggendo la eeprom col programmatore del
PC vedo che ha scritto prorpio quel byte. La lettura invece da pic su EEPROM mi d=E0 tutti altri bytes. Ad es. c'=E8 scritto E9 e io leggo 7F, c'=E8 scritto 80 e io leggo C1, ecc. questi bytes che leggo sono sempre gli stessi. C'=E8 una correlazione? Per capire ho letto un indirizzo della eeprom e fatto scrivere in un altro indirizzo. Poi ho letto la eeprom col programmatore. Cosa pu=F2 essere? No Interrupt, No timer abilitati. Ecco il mio codice:
PROCESSOR 16F84A RADIX DEC INCLUDE "P16F84A.INC" LIST P=3D16F84A ;DIRETTIVA CONFIG ;Codice di protezione disabilitato ;Power-up abilitato ;WDT Disabilitato ;Oscillatore al quarzo __CONFIG 3FF1H
CBLOCK 0x20 APPOGGIO ; appoggio ENDC
errorlevel -302 ORG 00H ;Indirizzo di RESET del PIC goto MAIN include "p16f54_i2c.inc"
MAIN:
nop nop nop nop nop nop nop nop nop nop nop movlw .50 movwf loops ; Set delay time for 5 ms call WAIT ; Delay bsf STATUS,RP0 ;Selezione del Banco 1 movlw 00H ;Azzera W movwf TRISB ; Porta B come Output movwf TRISA ; Reset TRISA bsf TRISA,0 bcf TRISA,1 bcf TRISA,2 bcf STATUS,RP0 ;Selezione del Banco 0 movlw 00H movwf CONTATORE banksel PORTA
bcf PORTA,1 bcf PORTA,2
banksel PORTB
; ********************** ; legge da ind. 04 ; **********************
movlw SDA_IN ; Configure SDA to be an input tris PORTB ; Copy value to TRISB register
movlw H'04' movwf address ; Initialize byte address to 04 call BSTART ; Generate start bit ; Now send the control byte ; for a write, to set address movlw WRITE_ADDR movwf datao ; Copy control byte to buffer call TX ; Output control byte to device
; Next, the address pointer movf address,W ; Copy address to WREG movwf datao ; Copy address to buffer call TX ; Output address to device
call BSTART ; Generate another start bit ; to switch to read mode movlw READ_ADDR movwf datao ; Copy control byte to buffer call TX ; Output control byte to device
; Finally, read the data byte bcf buffer,ACKB ; Select to send NO ACK bit call RX ; Input data from device movf datai,W movwf APPOGGIO
call BSTOP
; ************** ; scrive in 00 ; **************
movlw H'00' movwf address ; Initialize byte address to 04
call BSTART ; Generate start bit ; Now we send the control byte movlw WRITE_ADDR movwf datao ; Copy control byte to buffer call TX ; Output control byte to device
; Next, the address pointer movf address,W ; Copy address to WREG movwf datao ; Copy address to buffer call TX ; Output address to device
; Finally, send the data byte movf APPOGGIO,W movwf datao ; Copy data to buffer call TX ; Output data to device
call BSTOP ; Generate stop bit movlw .5 movwf loops ; Set delay time for 5 ms call WAIT ; Delay for write operation
; *************************
fine: goto fine
END
Provato cambiando anche indirizzo. Il file citato include "p16f54_i2c.inc" =E8 quello preso dal sito Microchip, libreria di gestione I2C bus. Se c'=E8 scritto un byte (es. 80 leggo C1, ecc. ma sempre lo stesso , non =E8 una cosa spuria.) Pensavo tre cose e l'ho verificate.
1) Pu=F2 dipendere dalla freq. troppo elevata 4Mhz
2) Pu=F2 dipendere dalla conf.interrupt abilitata anche se non mi serve
3) Pu=F2 dipendere dal chip fallato (PIC)
Nessun risultato:
1) sostituendo il PIC con un altro
2) abbassando la frequenza del PIC da 4 Mhz. a 400 khz.
3) Disabilitando (non ce n'erano ma ho posto il relativo registro comunque a zero) interrupt e/o timers=20
Che posso fare?