Prata med I2C EEPROM

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
PaNiC
Inlägg: 2610
Blev medlem: 15 augusti 2003, 22:16:15
Ort: Skånelandet

Prata med I2C EEPROM

Inlägg av PaNiC »

Har ett 24C16 EEPROM som jag behöver prata med. Jag har lite kod som påstås kunna göra just detta men jag får det inte att fungera. Har aldrig sysslat med I2C innan.
Möjligen behöver det bara petas in lite delayer någonstans, men jag har nog stirrat mig blind på det hela.

Måste man förresten skriva hela words eller man kan skriva en byte i taget bara?

Kod: Markera allt

;******************************************************************************
;'epwrite'
;*********
;Aim
;       Complete function to write a word into EEPROM.
;Registers used
;       datbyt          : contains data to be written to EEPROM          
;       rtemp           : temporary register
;       epaddr1,epaddr0 : address registers (msb,lsb)
;       datlsb,datmsb   : values passed from main (lsb,msb)
;       modeflg         : 01 indicates function is called from menu
;                         07 indicates memory is full
;Functions called
;       ack
;       txep
;*****************************************************************************

epwrite: cpi modeflg,$01        ; write data w/o checking for end of       
         breq epnxt3            ; memory if func called from menu

         ldi rtemp,$00          ; checking for end of memory
         cpse epaddr1,rtemp     ; if higher addr = 00       
         rjmp epnxt3            
         ldi rtemp,$00          
         cpse epaddr0,rtemp     ;      then, if lower addr = 00
         rjmp epnxt3
         ldi modeflg,$07        ;               then modeflg = 07 & ret
         rjmp epnxt4            ;            else write data

epnxt3:  sbi DDRB,DDB4          ; configure PINB4 as output
         sbi PORTB,PINB4        ; start bit: set SDA
         sbi PORTB,PINB5        ;            set SCL
         cbi PORTB,PINB4        ;            clear SDA
         ldi rtemp,0b10100000   ; load device address of EEPROM
         mov datbyt,rtemp
         rcall txep
         rcall ack
         mov datbyt,epaddr1     ; load memory location 1 
         rcall txep
         rcall ack
         mov datbyt,epaddr0     ; load memory location 2
         rcall txep
         rcall ack
         mov datbyt,datmsb      ; write first byte to EEPROM
         rcall txep
         rcall ack
         mov datbyt,datlsb      ; write second byte to EEPROM
         rcall txep
         rcall ack
         cbi PORTB,PINB4        ; stop bit:clear SDA
         sbi PORTB,PINB5        ;          set SCL
         sbi PORTB,PINB4        ;          set SDA

         cpi modeflg,$01        ; jump to end if function called from menu        
         breq epnxt4

         ldi rtemp,$FE          ; if lower addr = FE
         cp epaddr0,rtemp
         brne epnxt5
         inc epaddr1            ;       then inc higher & lower addr twice
epnxt5:  inc epaddr0            ; else only inc lower addr twice                                              
         inc epaddr0
epnxt4:  ret

;****************************************************************************
;'txep'
;******
;Aim
;       Function to write a byte to EEPROM. Value to be written is passed from
;       calling function in register datbyt.      
;Registers used
;       cnt     : to store no of bits
;       datbyt  : to store the data 
;Functions called
;       none       
;*****************************************************************************

txep:   ldi cnt, $08            ; load counter 
tebck:  rol datbyt              ; rotate data left through carry
        cbi PORTB,PINB5         ; clear SCL
        brcc tenxt              ; if carry set
        sbi PORTB,PINB4         ;    set SDA
        rjmp tenxt1             ; else
tenxt:  cbi PORTB,PINB4         ;    clear SDA
tenxt1: sbi PORTB,PINB5         ; set SCL
        dec cnt                 ; decrement counter
        brne tebck              ; if counter not zero, go back
        nop
        cbi PORTB,PINB5         ; clear SCL
        ret

;****************************************************************************
;'ack'
;*****
;Aim
;       To get the acknowledge signal from the EEPROM.       
;Registers used
;       none
;Functions used
;       none
;****************************************************************************

ack:    sbi PORTB,PINB5         ; set SCL
        cbi DDRB,DDB4           ; configure PINB4 as input
acbck:  sbic PINB,PINB4         ; goto calling function if SDA clear
        rjmp acbck              ;      else go back to ack
        nop
        cbi PORTB,PINB5         ; clear SCL
        sbi DDRB,DDB4           ; configure PINB4 as output
        nop
        ret

;******************************************************************************
;'rxep'
;******
;Aim
;       Function to read a byte from EEPROM. Value read is returned in 
;       register datbyt.
;Registers used
;       cnt     : to store no of bits
;       datbyt  : to store the data read
;Functions called
;       none
;*****************************************************************************

rxep:   cbi DDRB,DDB4           ; configure PINB4 as input  
        sbi PORTB,PINB4
        ldi cnt,$08             ; load counter
        ldi datbyt,0
rxbck:  sbi PORTB,PINB5         ; set SCL 
        sbic PINB,PINB4         ; if SDA set then
        sec                     ;        set carry
        sbis PINB,PINB4         ; else 
        clc                     ;       clear carry
        rol datbyt              ; rotate data received from EEPROM left
        cbi PORTB,PINB5         ; clear SCL
        dec cnt                 ; decrement counter
        brne rxbck              ; if counter equals zero, goto main
        ret                     ;    else jump back

;******************************************************************************
;'epread'
;********
;Aim
;       Complete function to read a byte from EEPROM. 
;Registers used
;       datbyt         : register in which data read is stored
;       rtemp          : temporary register
;       epaddr1,epaddr0: address registers (msb,lsb)
;Functions called
;       ack
;       txep
;       rxep
;*****************************************************************************

epread: sbi DDRB,DDB4           ; configure PINB4 as output  
        sbi PORTB,PINB4         ; start bit: set SDA
        sbi PORTB,PINB5         ;            set SCL
        cbi PORTB,PINB4         ;            clear SDA
        ldi datbyt,0b10100000   ; load device address
        rcall txep
        rcall ack
        mov datbyt,epaddr1      ; load memory location 1 
        rcall txep
        rcall ack
        mov datbyt,epaddr0      ; load memory location 2
        rcall txep
        rcall ack
        sbi PORTB,PINB4         ; start bit: set SDA
        sbi PORTB,PINB5         ;            set SCL
        cbi PORTB,PINB4         ;            clear SDA
        ldi datbyt,0b10100001   ; load device address
        rcall txep
        rcall ack
        rcall rxep              ; read data from EEPROM
        sbi PORTB,PINB5         ; give clock pulse: set SCL
        nop
        cbi PORTB,PINB5         ;                   clear SCL
        cbi DDRB,DDB4           ; configure PINB4 as output
        cbi PORTB,PINB4         ; stop bit: clear SDA 
        sbi PORTB,PINB5         ;           set SCL
        sbi PORTB,PINB4         ;           set SDA
        ret      
Om någon har annan kod skulle jag uppskatta att få ta del av den.
Användarvisningsbild
Rohan
Inlägg: 1063
Blev medlem: 7 april 2004, 08:24:39
Ort: Eksjö, Småland
Kontakt:

Inlägg av Rohan »

Kan tyvärr inte svara på varför koden inte funkar. Kanske du inte skickar rätt storlek på adressen? Skummade lite i databladet och din krets är indelad i 16 bytes pages men man ska kunna skriva delar av en page så att skriva en byte i taget ska gå.
Läs igenom databladet är mitt tips.

Här finns lite information om standarden och om eepromet.

EEPROMets datablad:
http://www.atmel.com/dyn/resources/prod ... oc0180.pdf

Om I2C och standardens specifikationer:
http://www.semiconductors.philips.com/m ... index.html
http://www.semiconductors.philips.com/a ... 340011.pdf
lasseo
Inlägg: 9
Blev medlem: 6 maj 2005, 11:24:20

Titta på...

Inlägg av lasseo »

http://www.winpicprog.co.uk/pic_tutorial.htm


Fick detta att fungera OK på et 24LC16 EEPROM
Skriv svar