Autor Tema: Escribiendo una 25AA512 o 25LC512 SPI con 877A (NO ES I2C)  (Leído 3001 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado pibe

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 635
Escribiendo una 25AA512 o 25LC512 SPI con 877A (NO ES I2C)
« en: 22 de Enero de 2009, 15:58:08 »
Y vuelve Pibe a la carga con sus memorias SPI !  :mrgreen:


 En este caso llenamos TODA la memoria con un dato (AA) desde la posicion 00 00 a la FF FF
Si lo simulamos en el Proteus, le damos a pausa y luego click derecho sobre la 25lc512 y seleccionamos la ultima opción (creo que es "ver memoria")
podremos ver como va llenando la memoria.

 Lo interesante es ver como escribe por páginas, solo dándole la dirección de comienzo en
 los dos bytes ADDRHIGH y ADDRLOW y haciendo un conteo hasta 128 (cada página contiene 128 bytes)
 si el contador llega a cero entonces pasa a la próxima página (sumando 128 al ADDRLOW y acarreo al ADDRHIGH)
 y así hasta el final de la memoria. Simulado en Proteus tarda aproximadamente 17,5 segundos.

 Hay que tener especial cuidado de llamar a la rutina write_in donde inicializamos la memoria externa, enviándole
 comandos de habilitación de escritura, etc.
 Luego se envia el dato o datos llamando a la rutina data_in por cada
 dato que cargamos (solo cargar W con el dato y llamar a data_in) para al final de la escritura (aunque no hayamos llenado
 toda la página ) llamamos a la rutina write_out que le indica que hemos acabado de escribir en esa página.
 De no indicarle el fin de escritura seguiría escribiendo datos y al llegar a 128 volvería a escribir desde 00 en la
 misma página , sobreescribiendo los datos ya guardados.
 El programa hace una pausita de 5ms por página en la cual escribe los 128 bytes que tiene en su propio buffer en el array


Aqui os dejo el esquema Proteus
prueba512.DSN
y el HEX para los más vagos :P
PRII.HEX


;ESCRITURA de una 25LC512 o 25AA512

      LIST p=16f877A      ;definimos micro
      #include <p16f877A.inc>   ;definiciones del micro
       __config  _CP_OFF & _XT_OSC & _WDT_OFF & _PWRTE_OFF & _LVP_OFF & _BODEN_OFF ; configuraciones del micro

;La idea es trabajar con un cristal/resonador ceramico de 10 mhz para el micro

   ERRORLEVEL -302      ;suppress "not in bank 0" message
   ERRORLEVEL -203      ;suppress  message
   ERRORLEVEL -305      ;suppress  message
   ERRORLEVEL -205      ;suppress  message

;****************************************************
;Definición de pines del micro
;****************************************************
#define     SCK         PORTC,3   ; OUT Salida SCLK del periférico SPI
#define     SDI         PORTC,4   ; IN Entrada SDI del periférico SPI
#define     SDO         PORTC,5   ; OUT Salida  SDO del periférico SPI
#define     CSMEM      PORTC,6   ; OUT Salida  CS para seleccionar la 25AA512

;******************************************************************************
; Definición de variables del programa
;******************************************************************************

CBLOCK 0X20
tmp1
cont
rxdata   ; buffer del dato recibido
ADDRHIGH ; byte de dirección alta
ADDRLOW   ; byte de dirección baja

;Variables misceláneas 
PDel0;   equ 0x51    ; variable para demora
PDel1;   equ 0x52    ; variable para demora
loops;   equ 0x54    ; variable para demora
ENDC

; Macros de cambio de bancos
BANK0 MACRO
bcf STATUS, RP0
bcf STATUS, RP1
ENDM
BANK1 MACRO
bsf STATUS, RP0
bcf STATUS, RP1
ENDM
BANK2 MACRO
bcf STATUS, RP0
bsf STATUS, RP1
ENDM
BANK3 MACRO
bsf STATUS, RP0
bsf STATUS, RP1
ENDM
 
ORG 00h
goto Inicio


Inicio

   BANK1
movlw b'00010000'   
movwf   TRISC     ;
movlw   0x80                    ; set up spi port, SPI master,
movwf   SSPSTAT                 ; cke = 0 (mode 1,1)
clrf    PIE1                    ; disable peripheral interrupts
clrf    INTCON                  ; disables all interrupts
   BANK0
clrf  PCLATH             ; nos aseguramos que el bit 3 de PCLATH sea 0
CLRF PORTA ; inicializamos puertos
CLRF PORTB
CLRF PORTC ;
CLRF PORTD
CLRF PORTE
bsf  CSMEM                ; nos aseguramos que el CS de la memoria esté en nivel alto
movlw 0x07
movwf CMCON      ; apagamos el módulo comparador
movlw 0x31        ; SPI master, clk/16, ckp=1
movwf SSPCON      ; SSPEN enabled



Principal
MOVLW 0XAA ;dato a escribir en toda la memoria
MOVWF tmp1

movlw .128
movwf cont   ; un contador para saber que llegamos a final de página

Envio_datos
;Ya podemos iniciar el envio de datos, inicializando el modulo SPI
call write_in

;Y rápidamente ir metiéndole los datos a rxdata
movf tmp1,w
call data_in   ; llamamos a la carga de dato
decfsz cont
goto $-3

movlw .128
movwf cont   ;reiniciamos contador
;Hemos llenado una página de 128 bytes con AA como dato
call write_out      ; y salimos de la sesion de escritura de la memoria

call inc_pagina      ;incrementamos una página ( +128 )

movf ADDRHIGH,w      ;vamos a ver que no se haya pasado de vueltas y nos sobreescriba desde el principio
sublw   0x00      ;
btfss STATUS,Z      ;
goto Envio_datos
movf ADDRLOW,w      ;vamos a ver que no se haya pasado de vueltas
sublw   0x00      ;
btfss STATUS,Z      ;
goto Envio_datos

;Hemos llenado toda la memoria con AA
stop
bsf PORTC,7 ; encendemos led para saber que llegamos al final de la memoria
goto stop


;**************************************************************************
; Rutinas de acceso a la EEPROM externa 25AA512 por módulo SPI hardware
;**************************************************************************
;Cada página consta de 128 bytes
;512 páginas en total

;MAPA DE MEMORIA EXTERNA
;____________________________________________________________________________________________
;
;           01      --      --      --      --      --      --      --      FF
; 00 00

;
;                                                          FF FF
;__________________________________________________________________________________________


write_in
;Send the write enable sequence (WREN)
  bcf     CSMEM                ; clear the chip select (active)
  movlw   0x06                    ; load WREN sequence
  call    output                  ; call the SPI output routine
  bsf     CSMEM                ; set the chip select line

 ;Send the write status register sequence (WRSR)
;Deshabilitamos los bits protectores
  bcf     CSMEM                ; clear the chip select line
  movlw   0x01                    ; clear all status register
  call    output                  ; call the SPI output routine
  movlw   0x00                    ; load up zero to send
  call    output                  ; call the SPI output routine
  bsf     CSMEM                ; set the chip select line

  ;Wait the required 5mS for the write cycle timer Twc
  call    delay                   ; call the delay subroutine

  ;Send the write enable sequence (WREN)
  bcf     CSMEM                ; clear the chip select (active)
  movlw   0x06                    ; load WREN sequence
  call    output                  ; call the SPI output routine
  bsf     CSMEM                ; set the chip select line

  ;Send the read status register sequence (RDSR)
  bcf     CSMEM                ; clear the chip select line
  movlw   0x05                    ; load RDSR sequence
  call    output                  ; call the SPI output routine
  call    output                  ; read the data in status reg.
  bsf     CSMEM                ; set the chip select line

  ;Send the write sequence (WRITE)
  bcf     CSMEM                ; clear the chip select line
  movlw   0x02                    ; load WRITE sequence
  call    output                  ; call the SPI output routine
 
  ;****************************************************************
   movf   ADDRHIGH,W                   ; load high address byte
  call    output                  ; call the SPI output routine
  ;****************************************************************
  movf    ADDRLOW,W                  ; move the address into w
   call    output                  ; call the SPI output routine
  ;****************************************************************
return

 
data_in
  call    output                  ; call the SPI output routine
return

write_out
  bsf     CSMEM                ; set the chip select line
call delay
return

;*******************SPI output subroutine***********************
output
  movwf   SSPBUF                  ; place data in send buffer
loop1
  bsf     STATUS,RP0              ; set to bank 1
  btfss   SSPSTAT,BF              ; has data been received?
  goto    loop1                   ; loop if not received yet
  bcf     STATUS,RP0              ; set to bank 0
  movf    SSPBUF,W                ; empty the receive buffer
  movwf   rxdata;rxdata                  ; put received byte into rxdata
  retlw   0                       ; return from subroutine


; 250 x 400nS x 50 = 5mS (plus overhead)
delay
  movlw   0x32                    ; move 50 decimal into w
  movwf   PDel0                   ; move 50 decimal into temp1
dec1
  movlw   0xFA                    ; move 250 decimal into w
  movwf   PDel1                   ; move 250 decimal into temp2
dec2
  decfsz  PDel1,1                 ; decrement temp2, skip if zero
  goto    dec2                    ; goto decrement 2 if not zero
  decfsz  PDel0,1                 ; decrement temp1, skip if zero
  goto    dec1                    ; goto decrement 1 if not zero
  retlw   0                       ; return both locations = 0


inc_pagina
      movlw 0x80
        addwf   ADDRLOW
       btfsc   STATUS,C
        incf   ADDRHIGH,1
return

      
END


Mi jefe mirando el prototipo que estoy creando: "Y eso va a funcionar?"

Desconectado jmcs87

  • PIC10
  • *
  • Mensajes: 44
Re: Escribiendo una 25AA512 o 25LC512 SPI con 877A (NO ES I2C)
« Respuesta #1 en: 22 de Enero de 2009, 19:11:20 »
Superrrr.............. pibe un tema muy importante para cualquier electronico ......ya me esta dando ganas de comprarme uno y probar este ejemplo .... sobre todo porque es mas moderno q el 24lc256 ...........Saludos    :D :D :D :D :D

Desconectado pibe

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 635
Re: Escribiendo una 25AA512 o 25LC512 SPI con 877A (NO ES I2C)
« Respuesta #2 en: 22 de Enero de 2009, 19:57:25 »
SI?
No viste el ultimo eeprom de microchip que usa un solo pin para todo?

UNI creo que se llama, y es SMD de 3 patas, tipo transistor smd con
masa
positivo
datos in/out/clock/ack etc etc

eso si que es una pasada, pero paso de hacer un programa para semejante memoria
Mi jefe mirando el prototipo que estoy creando: "Y eso va a funcionar?"


 

anything