Newsgroup: it.hobby.elettronica.riparazioni
Titolo: Problema lettura EEPROM 24LC02 da PIC. Scrittura OK

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 è 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à tutti altri bytes.
Ad es. c'è scritto E9 e io leggo 7F, c'è scritto 80 e io leggo C1,
ecc.
questi bytes che leggo sono sempre gli stessi. C'è 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ò essere? No Interrupt, No timer abilitati.
Ecco il mio codice:
PROCESSOR 16F84A
        RADIX DEC
        INCLUDE "P16F84A.INC"
        LIST P=16F84A
        ;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"
è quello preso dal sito Microchip, libreria di gestione I2C bus.
Se c'è scritto un byte (es. 80 leggo C1, ecc. ma sempre lo stesso ,
non è una cosa spuria.)
Pensavo tre cose e l'ho verificate.
1) Può dipendere dalla freq. troppo elevata 4Mhz
2) Può dipendere dalla conf.interrupt abilitata anche se non mi serve
3) Può 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 
Che posso fare?

comunque a zero) interrupt e/o timers
Sono arriginito con l'assembler dei PIC, ma per rinfrescarmi la memoria uso
dei listati che ho (parzialmente) commentato ai tempi d'oro e che adatto ale
mie esigenze. Questi listati sono per le applicazioni più note dei PIC a
livello di "massa": il sathacking di qualche anno fa. Quei listati eseguono
in modo massiccio lettura&scrittura su bus I2C su EEPROM esterna (24C16, in
generale).
Io li ho usati per scrivere una applicazione di gestione ingressi,
eliminando le parti superflue. Se pensi che ti possano essere utili, tieni
conto che l'indirizzo mail che uso deve essere "pulito" dall'antispam...
Saluti
Fulcro