TODOPIC
Microcontroladores PIC => Almacén del Assembler => Mensaje iniciado por: pibe 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
-
Código muy interesante. :-/
-
¿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?.
-
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
-
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.
-
Es que la 24LC/AA es I2c.
La 25LC/AA es SPI. :)
-
Es que la 24LC/AA es I2c.
La 25LC/AA es SPI. :)
!AAAAAAAAAHHHHHHHHHH¡
-
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 :-) :-) :-)
-
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.
-
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?
-
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.
-
disculpa todos esos datos son para el 24lc256 o para 25lc256
-
Pero...has al menos mirado la AN1040 ? :mrgreen:
-
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 :-) :-) :-)
-
:-/ :-/ :-/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 :-) :-) :-) :-)
-
No entiendo que necesitas que explique...
Que lo traduzca?
O que haga comentarios para que sirve cada rutina? (aunque ya lo explica en inglés)
EDITADO: Ya he hecho comentarios en las rutinas. Espero que te aclare mejor como funciona el programa.
Presta atención que este programa solo escribe UN BYTE y luego lo lee, no hace escritura ni lectura de página.
Sería cuestión de seguir los pasos que te dije en un reply anterior.
-
Lo que pasa es que no el logrado Simularlo todavia........... :cry: :cry:
-
Toma. Acá te dejo el programa en assembler y el circuito en Proteus.
spiok.DSN (http://www.4shared.com/file/80203120/ee969f90/spiok.html) Circuito
http://www.4shared.com/file/80203090/ca02c6c/spiOK.html Programa
-
mucha gracias Pibe ya veo como anda esto solo espero poder simularlo en la realidad y no tener ningun problema............
ya lo has simulado en la realidad o todavia?..........esto de la eeprom se me hacen muy necesarias es por eso el interes que le pongo .....muchas gracias.. :) :) :) :) :mrgreen:
-
No, aún no lo he puesto en marcha, quisas la semana próxima. Te pongo al tanto cuando lo haga.