Copiador de memorias EEPROM Con PICmicro Estudio En muchos proyectos se tiene la necesidad de almacenar información de tal manera que aun cuando el equipo sea desconectado de la fuente de alimentación los datos se mantengan disponibles al reiniciar el equipo. Por ejemplo almacenar números telefónicos, claves de acceso, fechas, precios, información de instrumentos como voltaje o corriente, etc. Todos estos datos no se pueden almacenar en la memoria RAM de los PIC porque al desconectarlo de su fuente se pierden. Las memorias seriales EEPROM son una buena alternativa para este tipo de aplicaciones. Estos circuitos integrados son pequeños, de 8 pines y son especialmente útiles cuando se quiere minimizar el numero de Entradas / Salidas del PICmicro. Generalidades de las memorias seriales EEPROM Las memorias seriales EEPROM pueden ser de tres tipos atendiendo a la manera como nos comunicamos con ellas: Microwire, I2C y SPI . En este articulo estudiaremos solamente los dos primeros tipos. Estas memorias tienen normalmente 8 pines. Alimentación, tierra, uno o dos pines de datos, un pin para el reloj y algunos pines de control. El tamaño físico de la memoria no tiene nada que ver con la capacidad de la misma, que puede ir desde algunas palabras hasta varios cientos de Kilo bytes. El consumo de las memorias seriales EEPROM es mínimo debido a que están construidas con tecnología CMOS. El consumo máximo cuando la memoria esta activa es de mas o menos un miliampere pero en standby puede ser de solamente algunos microamperes. Ejemplos de memorias seriales EEPROM - Memoria Microwire 93C66 La memoria 93C66 es una de las más populares de este tipo. Su capacidad es de 4Kbits. (512 x 8 o 256 x 16 bit ) La velocidad máxima del reloj es de 2MHZ y el tiempo de escritura de 10 milisegundos. Fig. 1
Fig. 1 Los nombres de los pines son: CS CLK DI DO Vss NC Vcc
Selecci贸n del integrado (Chip Select) Reloj (Serial data Clock) Entrada serial de datos (Serial Data Input) Salida serial de datos (Serial Data Output) Tierra (Ground) Sin conexi贸n (No Connect) Alimentaci贸n (Power Suply)
Memoria I2C 24C08 La memoria 24C08 es un ejemplo de este tipo de memoria. Su capacidad es de 8Kbits. (4 X 256 X 8 ) . Velocidad m谩xima del reloj es de 100 KHZ y el ciclo de escritura es de 2 milisegundos. Fig. 2
Fig. 2
Los nombres de los pines son: Vss SDA SCL WP Vcc A0, A1, A2
Tierra (Ground) Dirección / Datos Entrada / Salida seriales(Serial Address / Data I/O) Reloj serial (Serial Clock) Protección de escritura (Write protetct input) Alimentación de +4.5V a 5.5V (Power Supply) Sin conexión (No Connect)
PICmicro Estudio cuenta con dos tarjetas que están enfocadas a la programación de memorias seriales: El modulo Clave 708 para copiar memorias 93C66 y el modulo Clave 707 para copiar memorias 24CXX (24C00 a 24C08). Veamos cada una de estas tarjetas: Copiador de memorias 93C96 (Clave 708) El funcionamiento del modulo es el siguiente: - En el zócalo Base se coloca una memoria programada que se desea copiar. - En el zócalo Clon se coloca una memoria virgen. - Al oprimir el botón el PIC copia el contenido de la memoria Base en la memoria virgen. - Los Leds OK y BAD comienzan a destellar indicando que la operación de copiado esta en curso. - Al final uno de los dos Leds se mantiene encendido: OK nos indica que el copiado se realizó con éxito y el Led BAD indica que la operación tuvo algún problema. En la Fig. 3 se ilustra el diagrama esquemático de este módulo. Aquí podemos observar que el PIC16C505 es el corazón de esta tarjeta. El pin RB0 se conecta a la terminal CS (Chip Select) de la memoria BASE y el pin RC0 se conecta a CS de la memoria CLON. Un nivel ALTO en CS selecciona el CHIP correspondiente y un nivel BAJO lo deselecciona y lo pone en modo de espera (Standby). El pin RB1 se conecta a la terminal CLK (Serial Clock) de la memoria BASE y el pin RC1 se conecta a CLK de la memoria CLON. La señal de reloj se utiliza para sincronizar la comunicación entre el PIC y las memorias. Las instrucciones, direcciones y datos se introducen a la memoria mediante la terminal DI y durante el flanco positivo del reloj. También los datos se sacan de la memoria mediante el pin DO durante el flanco positivo del reloj.
Fig. 3
Los pines de las memorias DI (Entrada serial de datos) y DO (Salida serial de datos) están unidos y conectados al PIC. Esto quiere decir que la termina RB2 se configura como salida para transmitir Instrucciones/Datos y se configura como entrada para recibir datos de la memoria BASE. De igual manera se configura el pin RC2 para atender a la memoria CLON. Son siete las instrucciones que se le pueden dar a esta memoria: Borrar/Escribir Habilitar y Deshabilitar (Erase/Write Enable/ Disable), Enable quiere decir habilitar y Disable deshabilitar, por lo tanto para entrar en los modos de Borrar/Escribir primero se debe enviar la instrucción de habilitar y para salir de los modos Borrar/Escribir se debe enviar la instrucción deshabilitar. El modo de Lectura (Read) no requiere de esta instrucción. Escribir (Write) La instrucción Escribir es seguida por los bits que se van a grabar en la memoria. Leer (Read) La instrucción Leer saca los datos de la memoria. Borrar (Erase) Esta instrucción forza a unos los bits de la dirección especificada. Borra todo (Erase All) Esta instrucción pone en uno todos los bits de la memoria Escribe todo (Write All) Llena toda la memoria con el dato especificado. Estas instrucciones se introducen a la memoria mediante un código de tres bits. Para todas las instrucciones el primer bit es un UNO que es el bit de arranque. Los otros dos bits definen la instrucción. Por ejemplo para Escribir se envía el código 1 0 1. Para escribir en la memoria la secuencia de instrucciones sería la siguiente: Todo comienza con CS y DI en CERO. Después se envía una instrucción Erase/Write Enable después la instrucción Write seguida de Erase/Write Disable y finalmente CS de nuevo a CERO. Cada instrucción tiene su formato que se puede ver en las hojas de datos correspondiente. Como ejemplo veamos el formato de la instrucción Write en la Fig. 4
Dato
Fig. 4 Código de WRITE 101
Dirección
Observe como la secuencia da comienzo cuando CS y DI están en UNO y al Flanco positivo del reloj, mientras tanto DO esta en Alta Impedancia. Después se introduce la dirección y posteriormente el Dato. Al final de este articulo se presenta el software que se acompaña con este módulo y la Fig. 5 es una fotografía del mismo.
Memoria BASE
START
Memoria CLON Fig. 5
Copiador de memorias 24CXX (Clave 709) El funcionamiento del modulo es el siguiente: - En el zócalo Base se coloca una memoria programada que se desea copiar. - En el zócalo Clon se coloca una memoria virgen. - Con el DIPSWITCH se selecciona el tipo de memoria que se desea copiar: -1 para la memoria 2400 -2 para la memoria 2401 -3 para la memoria 2402 -4 para la memoria 2404 -5 para la memoria 2408 - Al oprimir el botón el PIC copia el contenido de la memoria Base en la memoria virgen. - Los Leds OK y BAD comienzan a destellar indicando que la operación de copiado esta en curso. - Al final uno de los dos Leds se mantiene encendido: OK nos indica que el copiado se realizó con éxito y el Led BAD indica que la operación tuvo algún problema. En la Fig. 6 se ilustra el diagrama esquemático de este módulo. Aquí podemos observar que el PIC16C505 es el corazón de esta tarjeta. El pin WP (Write protetct) de la memoria BASE se conecta a POSITIVO, de esta manera no se podrá escribir en ella. Al contrario la memoria CLON tiene su pin WP conectado a TIERRA para poder escribirla. RB0 y RB1 se conectan a SDA y SCL de la memoria BASE. Asi como RC1 y RC2 se conectan a SDA y SCL de la memoria CLON. Con estas conexiones se obtiene el control de la lectura de la memoria BASE y la escritura de la memoria CLON. SDA y SCL forman un bus bidireccional, en este caso el bus esta controlado por el PIC que es llamado Maestro y la memoria es el elemento Esclavo. Cualquiera de los dos puede enviar o recibir información. Pero el PIC es el que controla el flujo de información, el reloj SCL, y las condiciones de START y STOP. Cuando el bus no esta ocupado SDA y SCL están en Alto. El PIC genera una condicion de START cuando SDA cambia de ALTO a BAJO mientras el reloj SCL esta en ALTO. Cualquier operación comienza con esta condicion. Para generar una condicion de PARO SDA debe de pasar de BAJO a ALTO mientras el reloj SCL esta en ALTO. Cualquier operación debe de terminar con esta condicion.
Fig. 6
Una secuencia de Escritura de un Byte se puede observar el la Fig. 7
SDA
Byte de Control
Dirección
Dato
Fig.7 La secuencia de Lectura se puede observar en la Fig.8
SDA
Byte de Control
Dirección
Dato
Fig. 8 Al final de este articulo se presenta el software que se acompaña con este módulo y la Fig. 9 es la fotografía del mismo.
Memoria BASE
START Memoria CLON
Selector de Tipo de memoria
Fig. 9
Para su comodidad los programas de este articulo programa los puede encontrar en: www.electronicaestudio.com/articulos bajo el nombre de grab.zip
;PROGRAMA PARA COPIAR MEMORIAS 93X66X ;PIN PORTB,3 - BOTON ;PIN PORTB.4 - LED ROJO ;PIN PORTB.5 - LED VERDE ;FUSES - INTERNAL NO CLOCK OUT ; - MASTER CLEAR INTERNAL ; - WDT NO LIST P=16C505, F=INHX8M include "P16C505.INC"
;MPLAB PIC START PLUS
addr data_rec data_H data_L data_HH data_LL data_ data_env cont0 CONT1
equ equ equ equ equ equ equ equ equ EQU
0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x10 0X11
EWEN READ WRITE
equ equ equ
152 192 160
;CONSTANTES PARA COMANDOS
cs clk din dout
equ equ equ equ
0 1 2 2
;EN PTO B - CHIP A COPIAR ;EN PTO C - CHIP COPIA
B0 B7
equ equ
0 7
;BITS 0 Y 7
MOVWF GOTO L_READ_MM bsf movlw movwf call movf movwf call MOVLW TRIS call movf movwf call movf movwf MOVLW TRIS bcf
OSCCAL INICIO portb,cs READ data_env L_envia_3 addr,w data_env L_envia_8 B'11001100' PORTB L_recibe_8 data_rec,w data_H L_recibe_8 data_rec,w data_L B'11001000' PORTB portb,cs
;CALIBRACION PARA CLOCK INTERNAL ;RUTINA DE LECTURA PARA CHIP A COPIAR ;PON ON EL BIT DE CHIP SELECT ;ENVIA 3 BITS COMANDO READ ;ENVIA 8 BITS DIRECCION DEL DATO A LEER ;CAMBIA A ENTRADA EL BIT DE DATOS ;RECIBE 1os 8 BITS DEL DATO LEIDO ;RECIBE 2os 8 BITS DEL DATO LEIDO ;CAMBIA A SALIDA EL BIT DE DATOS ;PON OFF EL CHIP SELECT
retlw L_hacia_mm L_envia_3 movlw goto L_envia_8 movlw goto L_envia_11 movlw L_envia movwf L_env_a
0 ;RUTINA PARA ENVIAR 3, 8 o 11 BITS 3 L_envia 8 L_envia 11 cont0 ;LOOP PARA ENVIAR DATOS POR EL PIN DE DATOS
bcf btfsc bsf
portb,din data_env,b7 portb,din
;CERO ;O DEPENDIENDO DEL BIT B7 ;UNO
bsf nop bcf rlf decfsz goto retlw
portb,clk
;PULSO ;DE ;CLOCK ;CORRIMIENTO DEL UN BIT A LA IZQUIERDA ;CONTROL DEL LOOP
L_desde_mm L_recibe_8 movlw movwf clrf BCF L_reci_a bsf nop bcf rlf bcf btfsc bsf bcf decfsz goto retlw
portb,clk data_env,f cont0,f L_env_a 0
;RUTINA PARA RECIBIR DATOS DEL PIN DE DATOS 8 cont0 data_rec STATUS,C portb,clk portb,clk data_rec,f data_rec,b0 portb,dout data_rec,b0 status,c cont0,f L_reci_a 0
e_EWEN_MM bsf movlw movwf call bcf retlw
portc,cs EWEN data_env e_envia_11 portc,cs 0
e_READ_MM bsf movlw
portc,cs READ
;LOOP PARA LEER EL PIN DE DATOS ;PULSO ;DE ;CLOCK ;CORRIMIENTO DE UN BIT A LA IZQUIERDA ;ESCRIBE EN UN BYTE EL BIT LEIDO
;RUTINA ENVIAR COMANDO DE PERMITIR ESCRITURA ;EN EL CHIP COPIA
;RUTINA LECTURA CHIP COPIA ;PON ON CHIP SELECT
movwf call movf movwf call MOVLW TRIS call movf movwf call movf movwf MOVLW TRIS bcf retlw e_WRITE_MM bsf movlw movwf call movf movwf call movf movwf call movf movwf call bcf movlw tris e_chec_res bcf nop bsf e_chec_r_1 bsf nop bcf btfss goto bcf movlw tris retlw e_hacia_mm e_envia_3 movlw goto e_envia_8 movlw goto
data_env e_envia_3 addr,w data_env e_envia_8 B'11001100' PORTC e_recibe_8 data_rec,w data_HH e_recibe_8 data_rec,w data_LL B'11001000' PORTC portc,cs 0 portc,cs WRITE data_env e_envia_3 addr,w data_env e_envia_8 data_H,w data_env e_envia_8 data_L,w data_env e_envia_8 portc,cs b'11001100' portc portc,cs portc,cs portc,clk portc,clk portc,dout e_chec_r_1 portc,cs b'11001000' portc 0
;ENVIA COMANDO DE READ ;ENVIA DIRECCION DE LECTURA ;HAZ ENTRADA A PIN DE DATOS
;RECIBE 1os 8 BITS DEL DATO LEIDO ;RECIBE 2os 8 BITS DEL DATO LEIDO ;HAZ SALIDA A PIN DE DATOS ;PON OFF CHIP SELECT ;RUTINA DE ESCRITURA PARA CHIP COPIA ;PON ON CHIP SELECT ;ENVIA COMANDO DE WRITE AL CHIP COPIA ;ENVIA DIRECCION DEL DATO A ESCRIBIR ;ENVIA 1os 8 BITS DEL DATO A ESCRIBIR ;ENVIA 2os 8 BITS DEL DATO A ESCRIBIR ;PON OFF CHIP SELECT ;HAZ ENTRADA PIN DE DATOS ;PON OFF CHIP SELECT ;Y ;PON ON CHIP SELECT ;PULSO ;DE ;CLOCK ;SI HAY 'UNO' ESCRITURA TERMINADA ;SI HAY 'CERO' ESCRITURA EN CURSO - REPETIR ;PON OFF CHIP SELECT ;HAZ SALIDA A PIN DE DATOS
;RUTINA P/ENVIAR 3, 8 o 11 BITS A CHIP COPIA 3 e_envia 8 e_envia
e_envia_11 movlw e_envia movwf e_env_a bcf btfsc bsf bsf nop bcf rlf decfsz goto retlw e_desde_mm e_recibe_8 movlw movwf clrf BCF e_reci_a bsf nop bcf rlf bcf btfsc bsf bcf decfsz goto retlw
11 cont0 portc,din data_env,b7 portc,din portc,clk portc,clk data_env,f cont0,f e_env_a 0 ;RUTINA PARA RECIBIR DATOS DEL CHIP COPIA 8 cont0 data_rec STATUS,C portc,clk portc,clk data_rec,f data_rec,b0 portc,dout data_rec,b0 status,c cont0,f e_reci_a 0
INICIO
;AL ENCENDER CALL CLRF CLRF
PAUSA PORTB PORTC
INICIO_0 BTFSS GOTO CLRF CLRF
PORTB,3 $-1 PORTB PORTC
;BORRA PUERTOS B Y C ;AL HACER UNA SEGUNDA COPIA ;CHECA BOTON DE INICIO ;NO ;BORRA PUERTOS B Y C
INICIO_1 CALL CALL CALL CALL CALL CALL CALL BTFSS GOTO CALL CALL CALL CALL
PAUSA PAUSA PAUSA PAUSA PAUSA PAUSA PAUSA PORTB,3 $-1 PAUSA PAUSA PAUSA PAUSA
;PAUSAS PARA EVITAR REBOTE
CALL CALL CALL CALL movlw tris movlw tris call clrf
PAUSA PAUSA PAUSA PAUSA b'11001000' portb b'11111000' portc e_EWEN_MM addr
call BCF BSF CALL call BSF BCF CALL call movf xorwf btfss goto movf xorwf btfss goto incfsz goto BSF BCF GOTO
L_READ_MM PORTB,4 PORTB,5 PAUSA e_WRITE_MM PORTB,4 PORTB,5 PAUSA e_READ_MM data_HH,w data_H,w status,z error_ data_LL,w data_L,w status,z error_ addr,f repite PORTB,5 PORTB,4 INICIO_0
;LLAMA A RUTINA DE LECTURA CHIP A COPIAR ;PRENDE Y APAGA LEDS
BSF bcf goto
PORTB,4 portb,5 INICIO_1
;SI ERROR PRENDE LED ROJO ;Y APAGA LED VERDE
;DEFINE PUERTOS
;LLAMA A RUTINA DE PERMITIR ESCRITURA ;PON DIRECCION DE DATO A LEER EN 0
repite
;HAZ PAUSA PARA QUE PARPADEEN LOS LEDS ;LLAMA A RUTINA DE ESCRITURA DE CHIP COPIA ;APAGA Y PRENDE LEDS ;PAUSA PARA QUE PARPADEEN LEDS ;LLAMA RUTINA DE LECTURA CHIP COPIA ;COMPARA ;DATOS ;A ESCRIBIR ;CONTRA DATOS ;LEIDOS EN ;CHIP COPIA ;SI CORRECTO INCREMENTA DIRECCION ;HASTA 255 ;PRENDE Y APAGA LEEDS
error_
PAUSA
;PAUSA DE 18.5 MILISEGUNDOS MOVLW MOVWF DECFSZ GOTO DECFSZ GOTO RETLW end
24 CONT1 CONT0,F $-1 CONT1,F $-3 0
;PROGRAMA PARA COPIAR MEMORIAS 24 - 00 01 02 04 Y 08 ;BO ;B1 ;B2 ;B3 ;B4 ;B5 ;C0 ;C1 ;C2 ;C3 ;C4 ;C5
-
DATA_E CLK_E LED VERDE MEM_1 MEM_0 BOTON LED ROJO DATA_S CLK_S MEM_8 MEM_4 MEM_2
list p=p16C505 #include <p16C505.inc> #define #define #DEFINE #DEFINE #DEFINE #DEFINE
DATA_E CLOK_E LED_V PTE_1 PTE_0 BOTON
0 1 2 3 4 5
;PTO_B ;PTO_B ;PTO_B ;PTO_B ;PTO_B ;PTO_B
#DEFINE #define #define #DEFINE #DEFINE #DEFINE
LED_R DATA_S CLOK_S PTE_8 PTE_4 PTE_2
0 1 2 3 4 5
;PTO_C ;PTO_C ;PTO_C ;PTO_C ;PTO_C ;PTO_C
#DEFINE #DEFINE #DEFINE #DEFINE
MASKOUT_E MASKOUT_S MASKIN_E MASKIN_S CBLOCK 0X0C CHIP_DIR LIMITE BLOQUE DIR_BYTE TXBUF RXBUF DATO_L DATO_LL COUNT DATAOUT LOOP1 LOOP2 REG0 REG1 DIR_BYTE_X NUM_BYTES ENDC
RESET_VECTOR
0XF8 0XF8 0XF9 0XFA
;B'11111000' ;B'11111000 ;B'11111001' ;B'11111010'
;DIRECCION DE BYTES ;BUFFER DE TRANSMISION ;BUFFER DE LECTURA ;CONTADOR DE BITS
MOVWF CALL GOTO
OSCCAL MS250 PROGRAMA
MS250
;CALIBRACION RELOJ INTERNO
;PAUSA 250 MILISEGUNDOS nop decfsz goto decfsz goto reTURN
REG0,f $-2 REG1,f $-4
MOVLW MOVWF movlw TRIS MOVLW TRIS movlw movwf MOVLW MOVWF retlw
0XA0 CHIP_DIR MASKOUT_E PORTB MASKOUT_S PORTC B'11111011' PORTB B'11111110' PORTC 0
macro local local btfss goto bsf goto bcf goto goto bsf goto goto bcf endm
PORT, DATO, CLOCK bitlow clkout DATAOUT,7 bitlow PORT,DATO clkout PORT,DATO clkout $+1 PORT,CLOCK $+1 $+1 PORT,CLOCK
;MACRO DE ESCRITURA DE BIT ;ETIQUETAS SOLO VALIDAS EN MACRO
macro bsf bsf btfss bcf bcf endm
PORT, DATO , CLOCK PORT,CLOCK RXBUF,0 PORT,DATO RXBUF,0 PORT,CLOCK
;MACRO DE LECTURA DE BIT ;ON CLOCK ;ASUME BIT ENTRADA = 1 ;LEE BIT DE ENTRADA ;BIT DE ENTRADA = 0 ;OFF CLOCK
OPENSW
BITOUT
;INICIALIZACION
bitlow clkout
BITIN
BSTART_E BSF BSF bcf goto goto bcf retlw
PORTB,DATA_E PORTB,CLOK_E PORTB,DATA_E $+1 $+1 PORTB,CLOK_E 0
;DIRECCION DE CHIP ;DEFINICION DE PUERTOS B Y C ;INICIALIZACION DE LEDS Y ;DE DATO Y CLOCK
;CHECA ESTADO BIT A TRANSMITIR ;CERO - VE A BITLOW ;UNO - PIN DATO = 1 ;VE A CLKOUT ;PIN DATO = 0 ;ON CLOCK ;OFF CLOCK
;GENERA BIT DE INICIO ;DATO = 1 ;CLOCK = 0 ;DATO = 0 DURANTE 5us ;OFF CLOCK
CHIP ORIG
BSTART_S BSF BSF bcf goto goto bcf retlw
PORTC,DATA_S PORTC,CLOK_S PORTC,DATA_S $+1 $+1 PORTC,CLOK_S 0
BSTOP_E
;GENERA BIT DE PARADA CHIP ORIG movlw TRIS bsf goto nop bsf retlw
MASKOUT_E PORTB PORTB,CLOK_E $+1
;PON PINES DATO/CLOCK ;ON CLOCK ;DURANTE 5us
PORTB,DATA_E
;ON PIN DATO
movlw TRIS bsf goto nop bsf retlw
MASKOUT_S PORTC PORTC,CLOK_S $+1
;GENERA BIT DE PARADA CHIP COPIA ;VER BSTOP_E
PORTC,DATA_S 0
TX_E
;TRANSMITE 8 BITS CHIP ORIG movlw movwf movlw TRIS BITOUT rlf decfsz goto movlw TRIS BITIN retlw
.8 COUNT MASKOUT_E PORTB PORTB, DATA_E, CLOK_E DATAOUT, F COUNT, F TXLP_E MASKIN_E PORTB PORTB, DATA_E, CLOK_E 0
movlw movwf movlw TRIS BITOUT rlf decfsz goto movlw TRIS BITIN retlw
.8 COUNT MASKOUT_S PORTC PORTC, DATA_S, CLOK_S DATAOUT, F COUNT, F TXLP_S MASKIN_S PORTC PORTC, DATA_S, CLOK_S 0
clrf movlw
RXBUF .8
TX_S
TXLP_S
COMO SALIDAS
0
BSTOP_S
TXLP_E
;GENERA BIT DE INICIO CHIP COPIA ;VER BSTART_E
RX_E
;NUM BITS = 8 ;PON PINES DATO/CLOCK COMO SALIDAS ;VER MACRO BITOUT ;CORRIMIENTO DE UN BIT A LA IZQ ;8 VECES? ;NO - OTRA VEZ ;HAZ PIN DATO ENTRADA ;VER MACRO BITIN ;TRANSMITE 8 BITS CHIP COPIA ;VER TX_E
;RECIBE 8 BITS CHIP ORIG ;BORRA BUFFER DE ENTRADA ;NUMERO DE BITS = 8
RXLP_E
movwf bcf movlw TRIS rlf BITIN decfsz goto bsf movlw TRIS BITOUT retlw
COUNT STATUS,C MASKIN_E PORTB RXBUF, F PORTB, DATA_E, CLOK_E COUNT, F RXLP_E DATAOUT,7 MASKOUT_E PORTB PORTB, DATA_E, CLOK_E 0
RX_S
RXLP_S
clrf movlw movwf bcf movlw TRIS rlf BITIN decfsz goto bsf movlw TRIS BITOUT retlw
RXBUF .8 COUNT STATUS,C MASKIN_S PORTC RXBUF, F PORTC, DATA_S, CLOK_S COUNT, F RXLP_S DATAOUT,7 MASKOUT_S PORTC PORTC, DATA_S, CLOK_S 0
CLRF call MOVF movwf call btfsc goto movf movwf call btfsc goto call
RXBUF BSTART_E CHIP_DIR,W DATAOUT TX_E RXBUF,0 abort_E DIR_BYTE,w DATAOUT TX_E RXBUF,0 abort_E BSTOP_E
READ_E
;CARRY BIT = 0 ;HAZ PIN DATO ENTRADA ;CORRIMIENTO DE UN BIT A LA IZQ ;LEER UN BIT - VER MACRO BITIN ;8 VECES? ;NO - OTRA VEZ ;ACK BIT = 1 ;HAZ PINES DATO/CLOCK SALIDAS ;PARA TERMINAR TRANSMISION ;LEE 8 BITS CHIP COPIA ;VER RX_E
;LECTURA DE UN BYTE CHIP ORIG ;GENERA BIT DE INICIO ;DIRECCION CHIP ;EN BUFFER DE SALIDA ;Y TRANSMITELO ;CHECA NAK ;DIRECCION BYTE ;EN BUFFER DE SALIDA ;Y TRANSMITELO
;LEER UN BYTE DEL CHIP SIG_C_E call INCF movwf call btfsc goto call MOVF MOVWF call bcf
BSTART_E CHIP_DIR,W DATAOUT TX_E RXBUF,0 abort_E RX_E RXBUF,W DATO_L BSTOP_E STATUS,C
;GENERA BIT DE INICIO ;DIRECCION DE CHIP ;EN BUFFER DE SALIDA ;Y TRANSMITELO ;CHECA NAK ;LEE UN BYTE DEL CHIP ; GENERA BIT STOP Y TERMINA TRANSMI
retlw
0
call bsf retlw
BSTOP_E STATUS,C 1
CLRF call MOVF movwf call btfsc goto movf movwf call btfsc goto call
RXBUF BSTART_S CHIP_DIR,W DATAOUT TX_S RXBUF,0 abort_S DIR_BYTE,w DATAOUT TX_S RXBUF,0 abort_S BSTOP_S
call INCF movwf call btfsc goto call MOVF MOVWF call bcf retlw
BSTART_S CHIP_DIR,W DATAOUT TX_S RXBUF,0 abort_S RX_S RXBUF,W DATO_L BSTOP_S STATUS,C 0
call bsf retlw
BSTOP_S STATUS,C 1
movwf call MOVF movwf call btfsc goto movf movwf call btfsc goto movf movwf call btfsc goto call
TXBUF BSTART_E CHIP_DIR,W DATAOUT TX_E RXBUF,0 abort_E DIR_BYTE,w DATAOUT TX_E RXBUF,0 abort_E TXBUF,w DATAOUT TX_E RXBUF,0 abort_E BSTOP_E
abort_E
READ_S
;GENERA BIT STOP Y TERMINA TRANSMI
;LECTURA DE UN BYTE DE CHIP COPIA ;VER READ_E
SIG_C_S
abort_S
WRITE_E
;ESCRIBE UN BYTE EN CHIP ORIG ;PON DATO EN W EN BUFFER DE SALIDA ;GENERA BIT DE INICIO ;MUEVE DIR DE CHIP ;EN BUFFER DE TRANSMISION ;Y TRANSMITELO ;CHECA NAK ;MUEVE DIRECCION BYTE ;EN BUFFER DE TRANSMISION ;Y TRANSMITELO ;CHECA NAK ;MUEVE DATO ;EN BUFFER DE TRANSMISION ;Y TRANSMITELO ;GENERA BIT DE PARADA
bcf retlw
STATUS,C 0
movwf call MOVF movwf call btfsc goto movf movwf call btfsc goto movf movwf call btfsc goto call bcf retlw
TXBUF BSTART_S CHIP_DIR,W DATAOUT TX_S RXBUF,0 abort_S DIR_BYTE,w DATAOUT TX_S RXBUF,0 abort_S TXBUF,w DATAOUT TX_S RXBUF,0 abort_S BSTOP_S STATUS,C 0
WRITE_S
;ESCRIBE BYTE EN CHIP COPIA ;VER WRITE_E
;PAUSA POR MILISEGUNDOS INDICADOS EN W PAUSE_MLS movwf clrf nop decfsz goto decfsz goto retlw ;
LOOP1 LOOP2 LOOP2,f $-2 LOOP1,f $-4 0
PROGRAMA CALL
OPENSW
CLRF BTFSS GOTO CALL BTFSC GOTO BTFSC GOTO BTFSC GOTO BTFSC GOTO BTFSC GOTO GOTO
BLOQUE PORTB,BOTON $-1 MS250 PORTB,PTE_0 MEM_0 PORTB,PTE_1 MEM_1 PORTC,PTE_2 MEM_2 PORTC,PTE_4 MEM_4 PORTC,PTE_8 MEM_8 INICIO
MOVLW
15
;INICIALIZACION
INICIO
MEM_0
;CHECA BOTON DE INICIO ;DETERMINA TIPO DE MEMORIA
MOVWF CLRF COMF MOVLW MOVWF CALL GOTO
NUM_BYTES DIR_BYTE_X DIR_BYTE_X,F 0XA0 LIMITE MS250 LOOP
MOVLW MOVWF CLRF COMF MOVLW MOVWF CALL GOTO
127 NUM_BYTES DIR_BYTE_X DIR_BYTE_X,F 0XA0 LIMITE MS250 LOOP
MOVLW MOVWF CLRF COMF MOVLW MOVWF CALL GOTO
255 NUM_BYTES DIR_BYTE_X DIR_BYTE_X,F 0XA0 LIMITE MS250 LOOP
MOVLW MOVWF CLRF COMF MOVLW MOVWF CALL GOTO
255 NUM_BYTES DIR_BYTE_X DIR_BYTE_X,F 0XA2 LIMITE MS250 LOOP
MOVLW MOVWF CLRF COMF MOVLW MOVWF CALL GOTO
255 NUM_BYTES DIR_BYTE_X DIR_BYTE_X,F 0XA6 LIMITE MS250 LOOP
INCF MOVF MOVWF CALL
DIR_BYTE_X,F DIR_BYTE_X,W DIR_BYTE READ_E
MOVF MOVWF MOVF MOVWF CALL
DIR_BYTE_X,W DIR_BYTE DATO_L,W DATO_LL WRITE_S
MOVLW CALL
10 PAUSE_MLS
MEM_1
MEM_2
MEM_4
MEM_8
LOOP ;INCREMENTA DIRECCION BYTE ;LEE BYTE CHIP ORIG ;MISMA DIRECCION ;ESCRIBE BYTE CHIP COPIA ;PAUSA PARA ESCRITURA BYTE
CLRF
DATO_L
MOVF MOVWF CALL
DIR_BYTE_X,W DIR_BYTE READ_S
MOVF XORWF BTFSS GOTO
DATO_L,W DATO_LL,W STATUS,Z ERROR_
;COMPARA DATO ORIGINAL ;CONTRA DATO ESCRITA
BSF BCF MOVLW CALL BCF BSF MOVLW CALL
PORTB,LED_V PORTC,LED_R 24 PAUSE_MLS PORTB,LED_V PORTC,LED_R 24 PAUSE_MLS
;HAZ PARPADEAR LEDS
MOVF XORWF BTFSS GOTO
NUM_BYTES,W DIR_BYTE_X,W STATUS,Z LOOP
;CHECA NUMERO DE BYTES
MOVF XORWF BTFSC GOTO MOVLW MOVWF INCF BCF RLF ADDWF MOVLW MOVWF GOTO
CHIP_DIR,W LIMITE,W STATUS,Z TERMINA 0XA0 CHIP_DIR BLOQUE,F STATUS,C BLOQUE,W CHIP_DIR,F 255 DIR_BYTE_X LOOP
;CHECA BLOQUES DE 256 BYTES
BSF BCF BTFSS GOTO BCF CALL GOTO
PORTB,LED_V PORTC,LED_R PORTB,BOTON $-1 PORTB,LED_V MS250 PROGRAMA
;PRENDE LED VERDE ;APAGA LED ROJO ;CHECA BOTON DE INICIO
BCF BSF BTFSS GOTO BCF CALL GOTO
PORTB,LED_V PORTC,LED_R PORTB,BOTON $-1 PORTC,LED_R MS250 PROGRAMA
;APAGA LED VERDE ;PRENDE LED ROJO ;CHECA BOTON INICIO
;LEE DATO RECIEN ESCRITO
;DIFERENCIA - ERROR
;IGUAL AL BLOQUE MAXIMO ;INCREMENTA EL NUMERO DE BLOQUE
;PROCESA UN NUEVO BLOQUE
TERMINA
;INICIA OTRA COPIA
ERROR_
END
;INICIA OTRA COPIA