EEPROM I2c e PIC16f84A

Ciao a tutti, sto provando ad interfacciare una eeprom 24C02B con un PIC16f84A, cercando di implementare il protocollo I2C in ASM. Ho guardato questo documento di microchip:

formatting link

e ho basato il mio codice su di esso, cambiando un pochino di cose, per adattarlo al codice che avevo già iniziato a scrivere. Io devo scrivere un unico byte, prefissato, all'indirizzo 0 dell'eeprom. Ho collegato così i due integrati:

PIC: RB0 --> SDA, Linea dati EEPROM (con resistore di pull up da 10k) PIC: RB1 --> SCL, Clock EEPROM

Poi ho messo due led, uno verde ed uno rosso, per "debug": PIC: RB3 --> led verde = TUTTO ok PIC: RB4 --> led ROSSO = errore (non ho ricevuto l'ack sostanzialmente...)

Ora... quando alimento il circuito, ottengo come risultato che il programma arriva alla fine correttamente, ed il led verde (che indica appunto l'arrivo della fine del programma), si accende. Vado a leggere l'eeprom sul PC con il multipippo ma.. nulla è stato scritto... Il led rosso, che indicherebbe la non corretta ricezione del ack e la terminazione immediata del programma, non si accende, e ho verificato che l'ack viene ricevuto correttamente... provo a postare il codice, anche se è un po lungo... spero qualcuno mi possa aiutare lo stesso! Sono un principiante, quindi non "spaventavi" per il codice... ho cercato di mettere qualche commento per rendere le cose un po' più chiare.

Grazie! Nick

;-----------------BOF---------------------

PROCESSOR 16F84 RADIX DEC INCLUDE "P16F84.INC" ERRORLEVEL -302

;Setup of PIC configuration flags ;XT oscillator ;Disable watch dog timer ;Enable power up timer ;Disable code protect ;

__CONFIG 0x3FF1

SDA EQU 0 ;RB0 = SDA linea DATI SCL EQU 1 ;RB1 = sCL linea CLOCK LEDr EQU 4 ;led rosso errore = RB4 LEDv EQU 3 ; led verde: tutto ok = RB3

ORG 0X0C

DATABYTE RES 1 ; memorizzo byte da spedire COUNTER RES 1 ; contatore per la spedizone di 8 bit BUFF RES 1 ; buffer di output temporaneo INBUFF RES 1 ; buffer di input temporaneo

ORG 0X00

bsf STATUS, RP0 ;Setto RB0, RB1, RB3 e RB4 come uscite movlw B'11100100' movwf TRISB bCf STATUS,RP0

MainLoop

Call START ;Procedura di Start I2C movlw B'10100000' ; carico stringa di init scrittura movwf DATABYTE call tx ; trasmetto la stringa di inizializzazione

movlw B'0000000' ; carico indirizzo di prova movwf DATABYTE call tx ; trasmetto indirizzo dove scrivere

movlw B'10101010'; carico byte di prova da spedire movwf DATABYTE call tx Call stop

goto OK ; se tutto fila liscio si accende il led verde

START bsf PORTB,SDA ; data alta nop nop bcf PORTB,SCL ;ck basso nop ; bsf PORTB,SCL ;CK alto nop nop nop nop nop

bcf PORTB,SDA ; Ecco che inizia lo start... SCL=1, porto giù SDA nop nop nop nop nop

bcf PORTB,SCL ; Ck basso nop nop return

STOP

bcf PORTB, SDA ; SDA basso... condizione iniziale

nop nop nop ;Quanti NOP a 4 MHZ? da calcolare.... bsf PORTB,SCL ;CK alto

nop nop nop ; ma non sarebbe meglio una wait? Direi di si...

bsf PORTB, SDA ; Ecco che inizia lo stop... SCL=1, porto su SDA nop nop

bcf PORTB, SCL; nop nop nop

return

BITOUT movlw b'11100100' ; set data,clock as outputs tris portb btfss buff,7; Confronto sempre il bit più significativo goto bitlow ; bsf portb,sda ; set data line high goto clkout ; go toggle the clock

bitlow bcf portb,sda ; output a low bit

clkout bsf portb,scl ; set clock line high nop nop nop nop bcf portb,scl ; return clock line low return

BITIN bsf inbuff,0 ; assume input bit is high movlw b'11100101' ; make sdata an input line tris portb bsf portb,sda ; set sdata line for input bsf portb,scl ; set clock line high nop nop nop btfss portb,sda ; read the data bit bcf inbuff,0; input bit was low bcf portb,scl ; set clock line low return

TX ; trasmissione di un byte contenuto in databyte movlw .8 movwf counter ; set the #bits to 8

TXLP bcf buff,7 ; assume bit out is low btfsc databyte,7 ; is bit out really low? bsf buff, 7 ; otherwise data bit =1 call BITOUT ; serial data out rlf databyte,f ; rotate txbuf left decfsz counter,f ; 8 bits done? goto TXLP ;no - go again call BITIN ; read ack bit btfsc INBUFF,0 ; check ack bit

goto fine; se l'ack è a 1 allora errore: finisco e accendo il led rosso

return ; altrimenti ritorno e tutto ok!

Fine bsf PORTB, LEDr ; FINE con ERRORE, led rosso acceso goto fine;

OK bsf PORTB, LEDv ; Fine .. TUTTO ok led verde acceso. goto ok;

;---EOF-------------------

Reply to
Nick
Loading thread data ...

"Nick" ha scritto nel messaggio news:3UTRa.51328$ snipped-for-privacy@news1.tin.it...

[CUT]

Ho risolto... l'errore era nella procedura di stop, ci entravo con SDA ancora settato come ingresso.... Nick

Reply to
Nick

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.