Autor Tema: Ejemplo utilización 25AA/LC 1024 en modo master SPI  (Leído 3013 veces)

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

Desconectado pibe

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 635
Ejemplo utilización 25AA/LC 1024 en modo master SPI
« en: 29 de Enero de 2009, 06:47:23 »
Que pesadilla el Pibe y sus memorias SPI !!  :mrgreen:

Aqui les dejo un ejemplo sencillo y eficáz de usar la memoria serie más grande de microchip: La 25AA1024 o 25LC1024 con un PIC16f877A
El siguiente código fue probado en una protoboard y funciona 10 puntos.
Lo que hace es grabar 3 bytes consecutivos en modo burst y luego leerlos de la misma manera y mostrarlos por el PORTD
He optimizado el tiempo de grabación haciendo un WIP polling, que no es ni mas ni menos que la lectura del registro de estado de la memoria para saber si ha terminado de escribir y se pueden enviar/leer más datos, logrando así no tener que esperar un tiempo fijo de demora (generalmente en el peor de los casos es de 5ms) y que a la larga si escribimos muchos datos se agradece.

25AA1024

WP y HOLD con una R de 10k a positivo
CS a RC6 del micro
SO a SDI del micro
SI a SDO del micro
SCK a SCK del micro

No tiene mayores complicaciones a la hora de conectarla, como podrais ver. Pero no cometais la estupidéz que hice yo: Me tiré toda una mañana descifrando por qué no funcionaba. Mandaba datos, reloj, CS pero no grababa. Cuando me doy cuenta que me había olvidado de conectar el pin positivo de la eeprom :P
Bueno, gases del oficio.

Aquí va el código



  LIST P=16F877A
; Port C pin descriptions
; SCK    bit = 3
; SDI    bit = 4
; SDO    bit = 5
; CS      bit =6
;
; 20MHz crystal is being used, thus each instruction cycle = 1600nS
;
;*******************RAM register definitions**********************

cblock 0x20
rxdata    
txdata    
addrL   
loops    
outbyte
temp1
temp2
PDel0
PDel1
PDel2
addrM   
addrH   
d1
d2
d3
endc

;*******************Bit definitions*******************************
CS         equ 6

  include "p16f877A.inc"           ; this is the include file for a PIC16F877
  errorlevel  -302                ; suppress message 302 from list file
    __CONFIG   _CP_OFF &  _WDT_OFF & _PWRTE_OFF & _HS_OSC

  org 0x000                       ; set the reset vector
  goto start                      ; go to the beginning of main



start
  bcf      STATUS,RP0                ; set to bank 0
  clrf      PORTC                   ; initialize portc to 0
  bsf      STATUS,RP0              ; set to bank 1
  movlw   0x10                    ; all bits are outputs except SDI
  movwf   TRISC                   ; move the value to TRIS portc
  clrw
  movwf   TRISD
  bcf     STATUS,RP0              ; set to bank0
  bsf     PORTC,CS                ; make the chip select is high
  clrf    PIE1                    ; disable peripheral interrupts
  clrf    INTCON                  ; disables all interrupts
  bcf     STATUS,RP0              ; set to bank 0
  clrf    SSPCON                  ; clear SSP control register
  movlw   0x31                    ; set up spi port, SPI master,
  movwf   SSPCON                  ; clk/16, ckp=1 (mode 1,1)
  bsf      STATUS,RP0              ; set to bank 1
  clrf    SSPSTAT                 ; clear SSP status register
  movlw   0x80                    ; set up spi port, SPI master,
  movwf   SSPSTAT                 ; cke = 0 (mode 1,1)
  bcf      STATUS,RP0                ; set to bank 0

;Dirección de inicio será 00 00 00h
  movlw   0x00                    ; put starting address 55 in
  movwf   addrL                    ; addr for later use
  movwf   addrM                    ; addr for later use
  movwf   addrH                    ; addr for later use

ini
;Datos a escribir serán d1= AA, d2= BB, d3= CC
movlw 0xaa
movwf d1
movlw 0xbb
movwf d2
movlw 0xcc
movwf d3

;Primero hacemos wren y escribimos el status para habilitar escrituras
  bcf     PORTC,CS                ; clear the chip select (active)
  movlw   0x06                    ; load WREN sequence
  movwf   outbyte                 ; store in RAM location outbyte
  call    output                  ; call the SPI output routine
  bsf     PORTC,CS                ; set the chip select line

;Escribimos el registro status de la 1024
  bcf     PORTC,CS                ; clear the chip select line
  movlw   0x01                    ; clear all status register
  movwf   outbyte                 ; store in RAM location outbyte
  call    output                  ; call the SPI output routine
  movlw   0x00                    ; load up zero to send
  movwf   outbyte                 ; store in RAM location outbyte
  call    output                  ; call the SPI output routine
  bsf     PORTC,CS                ; set the chip select line

  call RDSR ; hacemos un WIP poll para ver si terminó de escribir

  ;Hacemos otro wren
  bcf     PORTC,CS                ; clear the chip select (active)
  movlw   0x06                    ; load WREN sequence
  movwf   outbyte                 ; store in RAM location outbyte
  call    output                  ; call the SPI output routine
  bsf     PORTC,CS                ; set the chip select line

  ;Y enviamos el comando de escritura
  bcf     PORTC,CS                ; clear the chip select line
  movlw   0x02                    ; load WRITE sequence
  movwf   outbyte                 ; store in RAM location outbyte
  call    output                  ; call the SPI output routine
;Enviamos direcciónes empezando por el byte mas alto
  movf    addrH,W                  ; move the address into w
  movwf   outbyte                 ; store in RAM location outbyte
  call    output                  ; call the SPI output routine
  movf    addrM,W                  ; move the address into w
  movwf   outbyte                 ; store in RAM location outbyte
  call    output                  ; call the SPI output routine
  movf    addrL,W                  ; move the address into w
  movwf   outbyte                 ; store in RAM location outbyte
  call    output                  ; call the SPI output routine
;Y grabamos la página con sólo 3 bytes: d1, d2, d3
  movf   d1,W                  ; load data AA into w
  movwf   outbyte                 ; store in RAM location outbyte
  call    output                  ; call the SPI output routine
  movf   d2,W                  ; load data AA into w
  movwf   outbyte                 ; store in RAM location outbyte
  call    output                  ; call the SPI output routine
  movf   d3,W                  ; load data AA into w
  movwf   outbyte                 ; store in RAM location outbyte
  call    output                  ; call the SPI output routine
  bsf     PORTC,CS                ; set the chip select line

call RDSR  ; hacemos un WIP poll para ver si terminó de escribir

  ;Ahora leemos lo que escribimos en la misma dirección
  bcf     PORTC,CS                ; clear the chip select line
  movlw   0x03                    ; load READ sequence
  movwf   outbyte                 ; store in RAM location outbyte
  call    output                  ; call the SPI output routine
  movf    addrH,W                  ; move the address into w
  movwf   outbyte                 ; store in RAM location outbyte
  call    output                  ; call the SPI output routine
  movf    addrM,W                  ; move the address into w
  movwf   outbyte                 ; store in RAM location outbyte
  call    output                  ; call the SPI output routine
  movf    addrL,W                  ; move the address into w
  movwf   outbyte                 ; store in RAM location outbyte
  call    output                  ; call the SPI output routine

;Y vamos leyendo los bytes en forma sucesiva y los guardamos en la misma variable donde salieron
  call    output                  ; call output to read 1 byte
  movf rxdata,w
  movwf d1
  call    output                  ; call output to read 1 byte
  movf rxdata,w
  movwf d2
  call    output                  ; call output to read 1 byte
  movf rxdata,w
  movwf d3
  bsf     PORTC,CS                ; set the chip select line

;Y luego los mostramos por el puerto D
  movf d1,w
  movwf PORTD
  call DEMORA1s
  clrf PORTD
  call DEMORA1s
  movf d2,w
  movwf PORTD
  call DEMORA1s
  clrf PORTD
  call DEMORA1s
  movf d3,w
  movwf PORTD
  call DEMORA1s
  clrf PORTD
  call DEMORA1s

;Y volvemos
  goto    ini


;*******************SPI output subroutine***********************
output
  movf    outbyte,W               ; move outbyte into w
  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                  ; put received byte into rxdata
  retlw   0                       ; return from subroutine

;Demora de 1 segundo
DEMORA1s  movlw     .22       ; 1 set numero de repeticion  (C)
        movwf     PDel0     ; 1 |
PLoop0  movlw     .134      ; 1 set numero de repeticion  (B)
        movwf     PDel1     ; 1 |
PLoop1  movlw     .211      ; 1 set numero de repeticion  (A)
        movwf     PDel2     ; 1 |
PLoop2  clrwdt              ; 1 clear watchdog
        decfsz    PDel2, 1  ; 1 + (1) es el tiempo 0  ? (A)
        goto      PLoop2    ; 2 no, loop
        decfsz    PDel1,  1 ; 1 + (1) es el tiempo 0  ? (B)
        goto      PLoop1    ; 2 no, loop
        decfsz    PDel0,  1 ; 1 + (1) es el tiempo 0  ? (C)
        goto      PLoop0    ; 2 no, loop
PDelL1  goto PDelL2         ; 2 ciclos delay
PDelL2  clrwdt              ; 1 ciclo delay
        return              ; 2+2 Fin.

RDSR
 ;Perform data polling (RDSR bit 0)
  bcf     PORTC,CS                ; clear the chip select line
  movlw   0x05                    ; load RDSR sequence
  movwf   outbyte                 ; store in RAM location outbyte
  call    output                  ; call the SPI output routine
  movlw   0x10                    ; give the spi device time to;
  movwf   loops                   ; set the WIP bit in the;
wait
  decfsz  loops,f                   ; status register before coming;
  goto    wait                    ; back and doing data polling;
polling
  bcf     PORTC,CS                ; clear the chip select line
  call    output                     ; read the data in status reg.
  call    output                     ; read the data in status reg.
  bsf     PORTC,CS                ; set the chip select line
  btfsc   rxdata,0                ; test the WIP bit in status reg.
  goto    polling                 ; WIP set, loop until WIP clear
  bsf     PORTC,CS                ; set the chip select line
return

  END
« Última modificación: 29 de Enero de 2009, 06:53:04 por pibe »
Mi jefe mirando el prototipo que estoy creando: "Y eso va a funcionar?"

Desconectado jmcs87

  • PIC10
  • *
  • Mensajes: 44
Re: Ejemplo utilización 25AA/LC 1024 en modo master SPI
« Respuesta #1 en: 29 de Enero de 2009, 16:01:36 »
muy bueno y que bien que ya este probado ...voy a ver cuanto me cuesta uno de esos para meterle mano......

saludos :mrgreen: :mrgreen:

Desconectado jimmyto

  • PIC10
  • *
  • Mensajes: 5
Re: Ejemplo utilización 25AA/LC 1024 en modo master SPI
« Respuesta #2 en: 30 de Enero de 2009, 10:55:57 »
Hola. probaste esta memoria en el proteus?. el 25lc512 me funciona correctamente pero este no y todavía no encuentro la razón.

Desconectado pibe

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 635
Re: Ejemplo utilización 25AA/LC 1024 en modo master SPI
« Respuesta #3 en: 30 de Enero de 2009, 14:09:54 »
Si, la he probado y hay un error.
Direcciona con 2 bytes, cuando tendría que ser con 3 bytes y por lo tanto el tercer byte te lo toma como dato.
Mi jefe mirando el prototipo que estoy creando: "Y eso va a funcionar?"


 

anything