Autor Tema: Ejemplo utilización SPI master del 877 con una 25LC256  (Leído 7090 veces)

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

Desconectado pibe

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 635
Ejemplo utilización SPI master del 877 con una 25LC256
« en: 22 de Diciembre de 2008, 05:52:49 »
Aqui os dejo el código que he encontrado en la página de microchip y que probado en PROTEUS funciona perfectamente.

       
;Ejemplo utilización del módulo SPI en modo master del 877
; grabando / leyendo de una memoria 25LC256
; y mostrando lo leído por el puerto D
; utiliza un xtal de 10mhz


  list  p=16F877A

; PORTC PIN DESCRIPTION
; SCK bit 3, SDI bit 4, SDO bit 5, CS bit 7
; Fosc = 10.0 MHz, thus each instr. cycle = 400ns


;***************Ram Register Definitions*******************************
;Aqui definimos los registros de variables
 cblock  0x20
   rxdata   
   addr     
   loops
PDel0
PDel1
PDel2   
 endc

;***************Bit Definitions****************************************
;Aqui definimos los pines del micro
#define   CS    PORTC,7           ; SPI chip select bit definition

;**********************************************************************


;***************25Cxxx command definitions
;Aqui definimos los bits de comando
#define     wren  6                 ;write enable latch
#define     WRDI  4                 ;reset the write enable latch
#define     RDSR  5                 ;read status register
#define     WRSR  1                 ;write status register
#define     READ  3                 ;read data from memory
#define     WRITE 2                 ;write data to memory

; Bit defines within status register
;Aqui definimos los bits del registro STATUS
#define     WIP   0                 ;write in progress
#define     WEL   1                 ;write enable latch
#define     BP0   2                 ;block protection bit
#define     BP1   3                 ;block protection bit
;**********************************************************************

         include "p16F877A.inc"     ; 16F877A include file
   __CONFIG   _CP_OFF &  _WDT_OFF & _PWRTE_ON & _XT_OSC
 
;**********************************************************************
;Aqui definimos el comienzo de los vectores, no usamos interrupciones 
  page
         org   0x000              ; Reset Vector
         clrf  PCLATH             ; ensure PCLATH bit 3 is cleared
         clrf  INTCON             ; ensure all interrupts are disabled
         goto  start              ; jump to the beginning of the program
         org   0x004              ; interrupt vector, do nothing
isr      retfie ;goto  isr                ; do nothing, location just
                                  ; identified in code
;***************BEGIN MAIN PROGRAM*************************************
;Aqui comienza el programa, definimos las entradas y salidas y habilitamos el módulo de comunicación SPI
start    bcf   STATUS,RP0         ; need to set bank 0
         clrf  PORTC              ; initialize port c
clrf PORTD
         bsf   CS                 ; make sure cs is set high

         bsf   STATUS,RP0         ; need to set bank 1
         movlw 0x10               ; all bits are outputs except SDI
         movwf TRISC              ; for SPI setup
movlw 0x00
      movwf TRISD               ;show on port D
         bcf   STATUS,RP0         ; need to set bank 0
         movlw 0x31               ; SPI master, clk/16, ckp=1
         movwf SSPCON             ; SSPEN enabled
         movlw 0x00               ; *** put beginning address in addr**
         movwf addr               ; for later use

Main
;Lo primero que hacemos es un WREN

         call  Wren               ; call the write enable routine
;Luego escribimos el registro status para limpiar los bits de protección de bloque
         call  wrsr               ; call the write status routine
;Hacemos un test de ocupado
         call  busy_test          ; test WIP bit in status register
;Y hacemos un WREN antes de escribir en la memoria
         call  Wren               ; call the write enable command
;Después escribimos 0xA5 (o cualquier otro valor ) en 0x10

         bcf   CS                 ; set chip select line low
         movlw WRITE              ; WRITE control byte
         call  output             ; call the output subroutine
         movlw b'00000000'        ; high addr byte is all 0's
         call  output             ; call the output subroutine
         movf  addr,w             ; low addr byte
         call  output             ; call the output subroutine
         movlw b'10100101'        ; load 0xA5 as data to be sent out
         call  output             ; call the output subroutine
         bcf   SSPCON,CKP         ; set clock idle low, mode 0,1
         bsf   CS                 ; set chip select, begin write cycle
         bsf   SSPCON,CKP         ; set clock idle high, mode 1,1
         call  busy_test 
         call  rdsr               ; call the read status subroutine

;Ahora leemos la direccion 0x10 y guardamos el dato en rxdata

         bcf   CS                 ; set chip select line low
         movlw READ               ; READ control byte
         call  output             ; call the output subroutine
         movlw b'00000000'        ; high addr byte is all 0's
         call  output             ; call the output subroutine
         movf  addr,w             ; get ready to send next byte
         call  output             ; call the output subroutine
         movlw b'01011010'        ; move don't care byte of 0x5A into
         call  output             ; call the output subroutine
         bsf   CS                 ; bring chip select high end
                                  ; terminate read command

; Y lo mostramos por puerto D
movf rxdata,w
movwf PORTD

;El programa hace un loop continuo, así que si lo que muestra por el puerto D es el valor 0xA5 en binario entonces
;es que ha leido correctamente

         call  wait               ; little delay between SPI sequence
call DEMORA1s
         goto  Main              ; do it all over again
                                  ; loop can be used to evaluate SPI
                                  ; signals on oscilloscope
         

;********************* BEGIN SUBROUTINES*******************************
;*** DELAY ROUTINE - 400uS ***
; Subrutina de espera 400us
wait     movlw .200               ; timing adjustment variable
         movwf loops              ; move variable into loops
top      nop                      ; sit and wait
         nop                      ; no operation
         decfsz loops,f           ; loop complete?
         goto   top               ; no, go again
         return                   ; yes, return from sub


;****** This is the OUTPUT transmit/receive subroutine. ***************
;Esta es la subrutina OUTPUT que recive/transmite
 
output   movwf SSPBUF             ; place data in buffer to send
loop1    bsf   STATUS,RP0         ; specify bank 1
         btfss SSPSTAT,BF         ; has data been received (xmit done)?
         goto  loop1              ; not done yet, keep trying
         bcf   STATUS,RP0         ; specify bank 0
         movf  SSPBUF,W           ; empty receive buffer
         movwf rxdata             ; put received byte into rxdata
         return                   ; return from subroutine

;*******Write Enable Subroutine****************************************
;Subrutina de habilitación de escritura
 
Wren     bcf   CS                 ; set chip select line low
         movlw wren               ; WREN control byte
         call  output             ; Call the output subroutine
         bcf   SSPCON,CKP         ; set clock idle low, mode 0,1
         bsf   CS                 ; set chip select, begin write
         bsf   SSPCON,CKP         ; set clock idle high, mode 1,1
         return                   ; return from subroutine

;*******Read Status Register Subroutine********************************
;Subrutina de lectura del registro status
 
rdsr     movlw RDSR               ; RDSR control byte
         call  output             ; Call the output subroutine
         movlw b'00000101'        ; this byte is a don't care byte
         call  output             ; status reg data will be in rxdata
         bsf   CS                 ; set chip select
         return                   ; return from subroutine

;*******Write Status Register Subroutine*******************************
;Subrutina de escritura del registro status
wrsr     bcf    CS                ; set chip select line low
         movlw  WRSR              ; WRSR control byte
         call   output            ; Call the output subroutine
         movlw  b'00001000'       ; set BP1 bit in status register 
         call   output            ; this will clear block protect bits
         bcf    SSPCON,CKP        ; set clock idle low, mode 0,1
         bsf    CS                ; set chip select
         bsf    SSPCON,CKP        ; set clock idle high, mode 1,1
         return                   ; return from subroutine

;*******Busy Test - WIP bit in Status Register*************************
;Testeo del bit WIP del registro status
busy_test
         bcf    CS                ; set chip select line low
         movlw  RDSR              ; RDSR control byte
         call   output            ; Call the output subroutine
         movlw  b'00000000'       ; send dummy byte
         call   output            ; to initiate clock sequence for read
         bsf    CS                ; else, set chip select high
         btfsc  rxdata,WIP        ; test WIP bit read from status register
         goto   busy_test         ; repeat busy test
         return                   ; 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.

         end
« Última modificación: 11 de Enero de 2009, 08:20:38 por pibe »
Mi jefe mirando el prototipo que estoy creando: "Y eso va a funcionar?"

Desconectado antimason

  • PIC12
  • **
  • Mensajes: 81
Re: Ejemplo utilización SPI master del 877 con una 25LC256
« Respuesta #1 en: 22 de Diciembre de 2008, 21:09:15 »
Código muy interesante. :-/

Desconectado antimason

  • PIC12
  • **
  • Mensajes: 81
Re: Ejemplo utilización SPI master del 877 con una 25LC256
« Respuesta #2 en: 04 de Enero de 2009, 08:43:01 »
¿Como se conectaría a una memoría un pic con este protocolo?, tengo entendido que es a tres hilos, ¿se ponen resistencias pull-up al igual que en modo I2C?.

Desconectado pibe

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 635
Re: Ejemplo utilización SPI master del 877 con una 25LC256
« Respuesta #3 en: 04 de Enero de 2009, 15:54:14 »
Son 4:
SDI (entrada de datos desde el micro )
SDO (salida de datos hacia el micro )
SCK (o SCLK) (entrada desde el micro )
CS (entrada, desde cualquier pin del micro seleccionas el chip con resistencia 10 k pullup a positivo)
WP a positivo
HOLD a positivo

Y no, no lleva resistencias de pullups

La desventaja del SPI es que tenga 4 hilos.
Las ventajas son la velocidad de comunicación y la simplicidad del software ya que no tienes que esperar por el maldito ACK :P
« Última modificación: 09 de Enero de 2009, 04:15:31 por pibe »
Mi jefe mirando el prototipo que estoy creando: "Y eso va a funcionar?"

Desconectado antimason

  • PIC12
  • **
  • Mensajes: 81
Re: Ejemplo utilización SPI master del 877 con una 25LC256
« Respuesta #4 en: 06 de Enero de 2009, 22:09:39 »
Ya, pero la memoria 24lc256 ¿donde tiene SDO?, tiene 8 pines, VCC, VSS, WP, SCK, SCL, Y LOS 3 PINES DE SELECCIÓN DE CHIP.

Desconectado pibe

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 635
Re: Ejemplo utilización SPI master del 877 con una 25LC256
« Respuesta #5 en: 07 de Enero de 2009, 07:17:36 »
Es que la 24LC/AA es I2c.
La 25LC/AA es SPI.  :)
Mi jefe mirando el prototipo que estoy creando: "Y eso va a funcionar?"

Desconectado antimason

  • PIC12
  • **
  • Mensajes: 81
Re: Ejemplo utilización SPI master del 877 con una 25LC256
« Respuesta #6 en: 07 de Enero de 2009, 12:09:53 »
Es que la 24LC/AA es I2c.
La 25LC/AA es SPI.  :)


!AAAAAAAAAHHHHHHHHHH¡

Desconectado jmcs87

  • PIC10
  • *
  • Mensajes: 44
Re: Ejemplo utilización SPI master del 877 con una 25LC256
« Respuesta #7 en: 08 de Enero de 2009, 03:28:00 »
Hola Pibe que tal es estado chequeando el codigo y todo me compila bien el problema que tengo es al simularlor en el proteus ...es decir como conecto la 25lc256 al 16f877 no se que hacer con los pines WP , HOLD a donde los pongo .....y si me pudieras responder que tanta diferencia hay entere este y el 24lc256 con respecto a la velocidad gracias :-) :-) :-)

Desconectado pibe

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 635
Re: Ejemplo utilización SPI master del 877 con una 25LC256
« Respuesta #8 en: 08 de Enero de 2009, 06:29:00 »
WP y HOLD a positivo.
Por lo que veo en la hoja de datos la diferencia entre las memorias SPI con las I2c es la velocidad de transferencia de datos. Cuando la I2c soporta una frecuencia de reloj de 0.4mhz maximo, las SPI soportan hasta 10 mhz.
La igualdad en ambas es que tardan unos 5ms para grabar un byte. Pero si grabas o lees por página la cosa mejora.
Mi jefe mirando el prototipo que estoy creando: "Y eso va a funcionar?"

Desconectado jmcs87

  • PIC10
  • *
  • Mensajes: 44
Re: Ejemplo utilización SPI master del 877 con una 25LC256
« Respuesta #9 en: 08 de Enero de 2009, 20:09:05 »

gracias por la respuesta .... y yo pensaba que para grabar un byte era mas rapido que el 24lc256 pero segun tu respuesta veo que no lastima porque eso es lo que nesecito que para grabar sea mas rapido  pero bueno .......dejo una duda como es que el winpic800 cuando grabo  el 24lc256 lo hace en menos de un minuto y graba toda la eeprom y cuando lo hago por medio de un pic me demoro mucho  ..supuestamente se debe dejar 5ms entre byte y byte o me equivoco .... tambien e leeido que se puede grabar en bloques de 64 bytes pero tambien se debe dejar 5ms entre cada una?

Desconectado pibe

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 635
Re: Ejemplo utilización SPI master del 877 con una 25LC256
« Respuesta #10 en: 09 de Enero de 2009, 04:14:48 »
Para escribir un byte te tomaria lo que tardes en enviar el byte de comando, los dos bytes de direccion y el byte de datos , mas 5ms que tarda el chip en escribir lo que le mandaste en sus celdas.
Para escribir una página te tomaría lo que tardes en enviar el byte de comando, los dos bytes de direccion inicial y los 64 bytes de datos , mas 5ms que tarda el chip en escribir lo que le mandaste en la página.

O sea que si el chip tiene 512 páginas y tarda 5-6ms en grabar cada una:
512*6ms=3072ms (todas las memorias que he visto son de 512 páginas. Lo que cambia es la cantidad de bytes por página)
3072ms=  3segundos

(Según microchip grabar una página toma alrededor de 3ms , lo que grabar las 512 paginas nos llevaría a la mitad de tiempo : 1,5 segundos)

No está mal, no?

Mira la hoja de aplicaciones AN1040. Está muy interesante y te da la tabla de tiempos de escritura.

Lo único que tienes que tener cuidado de saber exactamente donde comienza y termina cada página, para no sobreescribir datos de la página, ya que se autoincrementa el puntero de direcciones , pero no el de página . Si te pasas de dirección vuelve a escribir desde el inicio de la página.
Yo no he encontrado un mapa de memoria y lo tuve que hacer a mano, a ver si tu puedes encontrar algo.

Una cosita más: he visto que en las hojas de aplicaciones le ponen un resistencia de pullup de 10k al CS.
« Última modificación: 09 de Enero de 2009, 04:43:03 por pibe »
Mi jefe mirando el prototipo que estoy creando: "Y eso va a funcionar?"

Desconectado jmcs87

  • PIC10
  • *
  • Mensajes: 44
Re: Ejemplo utilización SPI master del 877 con una 25LC256
« Respuesta #11 en: 10 de Enero de 2009, 03:25:29 »
disculpa todos esos datos son para el 24lc256 o para 25lc256

Desconectado pibe

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 635
Re: Ejemplo utilización SPI master del 877 con una 25LC256
« Respuesta #12 en: 10 de Enero de 2009, 05:34:45 »
Pero...has al menos mirado la AN1040 ?  :mrgreen:
Mi jefe mirando el prototipo que estoy creando: "Y eso va a funcionar?"

Desconectado jmcs87

  • PIC10
  • *
  • Mensajes: 44
Re: Ejemplo utilización SPI master del 877 con una 25LC256
« Respuesta #13 en: 10 de Enero de 2009, 21:16:02 »

si si lo chequee  y es solo para 25lc256  el ejemplo que pusiste que debe votar por el puerto D  toy intentando simularlo y nada .......si fueras tan amable de comentar mejor el codigo del programa haci me doy cuenta mejor gracias  :-) :-) :-)

Desconectado jmcs87

  • PIC10
  • *
  • Mensajes: 44
Re: Ejemplo utilización SPI master del 877 con una 25LC256
« Respuesta #14 en: 11 de Enero de 2009, 01:43:01 »
 :-/ :-/ :-/Pibe e solucionado el problema que te comente que era que la eprom demoraba mucho en grabarse toda .......demoraba tanto por que yo daba 5ms por cada byte de dato  que enviaba y eso taba mal ....... con solo mandar los 64bytes de datos y recien al final mandar los 5ms se soluciono todo .....gracias a tu post aclare mis dudas y espero como ya te dije una mejor explicacion del codigo de arriba ya que me interesa mucho trabajar con esa eprom que tengo entendido es mas moderna que la 24LC256 y tambien entender el SPI  :-) :-) :-) :-)