Lectura y escritura de las memorias EEPROM y FLASH

Một phần của tài liệu Microcontroladores PIC diseno practico de aplicaciones segunda parte PIC16F87X PIC18FXXX 2 ed jose angulo (Trang 77 - 96)

Capítulo 3. PRINCIPALES REGISTROS DE CONTROL Y MANEJO DE LAS ME-

3.5. Lectura y escritura de las memorias EEPROM y FLASH

En el PIC16F84 se podía leer y escribir la memoria de datos EEPROM. En los PIC16F87x también se pue- de leer y escribir la memoria de código FLASH. Esto significa que un programa dinámicamente puede ge- nerar información que se puede grabar en la FLASH directamente, sin necesidad del grabador externo.

La propia aplicación se puede reprogramar según las condiciones externas. Es posible ampliar el área de la memoria de datos no volátil EEPROM con posiciones libres de la memoria de código FLASH.

PSPIE Permiso de interrupción para la puerta paralela esclava al realizar una operación de lectura/

escritura. En modelos de 40 patitas.

ADIE Permiso de interrupción para el conversor A/D al finalizar la conversión.

RCIE Permiso de interrupción para el receptor del USART cuando el buffer se llena.

TXIE Permiso de interrupción para el transmisor del USART cuando el buffer se vacía.

SSPIE Permiso de interrupción para la puerta serie síncrona.

CCP1IE Permiso de interrupción para el módulo CCP1 cuando se produce una captura o comparación.

TMR2IE Permiso de interrupción para el TMR2 con su desbordamiento.

TMR1IE Permiso de interrupción para el TMR1 con su desbordamiento.

REGISTRO PIE1

PSPIE ADIE RCIE TXIE SSPIE CCP1IE TMR2IE TMR1IE

7 0

Figura 3.4. Designación y funciones de permiso y prohibición de los bits del registro PIE1.

La memoria EEPROM de los PIC16F87x tiene una capacidad de 128 o 256 bytes, con un rango de direcciones de 00h a 7Fh o 00h a FFh, respectivamente.

En los PIC16F87x se puede leer y escribir la memoria FLASH y ộsta puede alcanzar un tamaủo de 8 K palabras de 14 bits cada una. No es suficiente con un solo registro para especificar la direc- ción, que alcanza los 13 bits, y lo mismo sucede para el contenido, que tiene una longitud de 14 bits.

Para cubrir esta necesidad, el registro EEADR se concatena con el EEADRH, que contiene los 5 bits de más peso de la dirección. Por otra parte, el registro EEDATAH se concatena con el EEDATA y contiene los 6 bits de más peso de la palabra leída o a escribir en la FLASH. Estos dos nuevos re- gistros no se usan en las operaciones que afectan a la EEPROM. (Figura 3.7.)

Para controlar la operación de lectura/escritura de las memorias EEPROM y FLASH hay dos re- gistros denominados EECON1 y EECON2. El EECON1 (Figura 3.8) ocupa la dirección 18Ch, mientras que el EECON2, como sucedía con el PIC16F84, no está implementado físicamente y só- lo se utiliza como registro de seguridad en la delicada operación de escritura, que tiene la elevada duración de 2 milisegundos, aproximadamente. Antes de iniciar la escritura de una palabra se es- cribe en EECON2 primero el dato 55h y luego el AAh.

CMIE Permiso de interrupción para el comparador.

EEIE Permiso de interrupción por fin de escritura en la EEPROM de datos.

BCLIE Permiso de interrupción por colisión de bus en el SSP cuando dos o más maestros tratan de transferir al mismo tiempo.

CCP2IE Permiso de interrupción en el módulo CCP2.

REGISTRO PIE2

7 0

Figura 3.5. Designación y funciones de los bits del registro PIE2.

REGISTRO PIR1

PSPIF ADIF RCIF TXIF SSPIF CCP1IF TMR2IF TMR1IF

7 0

REGISTRO PIR2

— CMIF — EEIF BCLIF — — CCP2IF

7 0

Figura 3.6. Los bits de los registros PIR1 y PIR2 contienen los seủalizadores de las causas que producen las interrupciones, en correspondencia con los registros PIE1 y PIE2.

— CMIE — EEIE BCLIE — — CCP2IE

Se proponen algunos programas fundamentales para manejar las operaciones de lectura y escri- tura en las memorias EEPROM y FLASH. En la parte dedicada a programación se incluye un ejer- cicio completo sobre este tema. Un resumen de la operación de escritura de una posición de la EE- PROM consta de los siguientes pasos:

Figura 3.7. Para contener la dirección y el dato de la memoria FLASH se necesitan dos registros para cada valor.

EADRH (10Fh) EEADR (10Dh)

0 0 0 x x x x x x x x x x x x x

DIRECCIÓN DE 13 BITS (8 K) EEDATAH (10Eh) EEDATA (10Ch)

0 0 x x x x x x x x x x x x x x

DATO DE 14 BITS (FLASH)

PROGRAMA DE ESCRITURA DE LA MEMORIA EEPROM DE DATOS bsf STATUS,RP1 ; Con estas dos instrucciones se

bcf STATUS,RP0 ; selecciona el banco 2

movf ADDR_L,W ; Se mete en EEADR la dirección a la

movwf EEADR ; que se va a acceder

movf DATA_L,W ; Se mete en EEDATA el dato a escribir

movwf EEDATA

bsf STATUS,RP0 ; Se pasa al banco 3

bcf EECON1,EEPGD ; Se selecciona el acceso a la EEPROM bsf EECON1,WREN ; Se habilita la escritura en la EEPROM bcf INTCON,GIE ; Se prohiben las interrupciones

movlw 55h ; Se mete el valor 55h y el AAh en el

movwf EECON2 ; registro de seguridad EECON2 tal y

movlw AAh ; como recomienda el fabricante

movwf EECON2

bsf EECON1,WR ; Se da la orden de escritura bsf INTCON,GIE ; Se habilitan las interrupciones

sleep ; Se espera a que se produzca interrupción

; por fin de escritura

bcf EECON1,WREN ; Se prohibe la escritura de nuevos datos

bcf STATUS,RP1 ; Se pasa al banco 0

bcf STATUS,RP0 ;

bcf PIR2,EEIF ; Se borra el flag de fin de escritura 1.aSe introduce el dato a escribir en EEDATA y la dirección en EEADR.

2.a Se pone WREN=1 en EECON1. Permiso de escritura.

3.a Se escribe la secuencia de seguridad que carga el registro EECON2 con el dato 55h y luego con AAh.

4.a Para iniciar la escritura se pone WR=1 en EECON1.

5.a Al finalizar la escritura se activa el seủalizador EEIF de forma automỏtica.

6.a Se debe borrar el seủalizador EEIF y prohibir la escritura (WREN=0).

EEPGD Selecciona el acceso a la FLASH (1) o a la EEPROM (0).

WRERR Seủalizador de error en escritura.

WREN Permiso de escritura.

WR Hay que ponerlo a 1 para iniciar la escritura y pasa a 0 automáticamente cuando finaliza.

RD Hay que ponerlo a 1 para iniciar la lectura.

REGISTRO EECON1

EEPGD — — — WRERR WREN WR RD

7 0

Figura 3.8. Denominación y misión de los bits del registro EECON1.

PROGRAMA DE LECTURA DE LA MEMORIA FLASH DE CÓDIGO

bsf STATUS,RP1 ; Con estas dos instrucciones se

bcf STATUS,RP0 ; selecciona el banco 2

movf ADDR_H,W ; Se mete en EEADRH la parte alta de la

movwf EEADRH ; dirección a leer

movf ADDR_L,W ; Se mete en EEADR la parte baja de la

movwf EEADR ; dirección a leer

bsf STATUS,RP0 ; Se pasa al banco 3

bsf EECON1,EEPGD ; Se selecciona el acceso a la FLASH bsf EECON1,RD ; Se da la orden de lectura de la FLASH

nop ; Tarda 3 ciclos en tener el dato, por lo que

nop ; cualquier instrucción es ignorada

bcf STATUS,RP0 ; Se pasa al banco 2

movf EEDATA,W ; Se coge la parte baja del dato leído

movwf DATA_L

movf EEDATAH,W ; Se coge la parte alta del dato leído

movwf DATA_H

PROGRAMA DE ESCRITURA EN LA MEMORIA FLASH DE CÓDIGO bsf STATUS,RP1 ; Con estas dos instrucciones se

bcf STATUS,RP0 ; selecciona el banco 2

movf ADDR_H,W ; Se mete en EEADRH la parte alta de la

movwf EEADRH ; dirección a escribir

movf ADDR_L,W ; Se mete en EEADR la parte baja de la

movwf EEADR ; dirección a escribir

movf DATA_H,W ; Se mete en EEDATH la parte alta

movwf EEDATH ; del dato a escribir

movf DATA_L,W ; Se mete en EEDATA la parte baja

CONFIGURACIÓN DE BITS POSICIONES LECTURA ESCRITURA LECTURA ESCRITURA

CP1 CP0 WRT DE FLASH INTERNA INTERNA ICSP ICSP

0 0 x Toda la memoria de programa Sí No No No

0 1 0 Áreas no protegidas Sí No Sí No

0 1 0 Áreas protegidas Sí No No No

0 1 1 Áreas no protegidas Sí Sí Sí No

0 1 1 Áreas protegidas Sí No No No

1 0 0 Áreas no protegidas Sí No Sí No

1 0 0 Áreas protegidas Sí No No No

1 0 1 Áreas no protegidas Sí Sí Sí No

1 0 1 Áreas protegidas Sí No No No

1 1 0 Toda la memoria de programa Sí No Sí Sí

1 1 1 Toda la memoria de programa Sí Sí Sí Sí

Figura 3.9. Diversas posibilidades de protección de la memoria FLASH ante operaciones de lectura y es- critura, de acuerdo con los valores de los bits WRT, CP1 y CP0 de la Palabra de Configuración.

PROGRAMA DE ESCRITURA EN LA MEMORIA FLASH DE CÓDIGO (continuación)

movwf EEDATA ; del dato a escribir

bsf STATUS,RP0 ; Se pasa al banco 3

bsf EECON1,EEPGD ; Se selecciona el acceso a la FLASH bsf EECON1,WREN ; Se habilita la escritura en la FLASH bcf INTCON,GIE ; Se prohiben las interrupciones

movlw 55h ; Se mete el valor 55h y el AAh en el

movwf EECON2 ; registro de seguridad EECON2 tal y

movlw AAh ; como recomienda el fabricante

movwf EECON2

bsf EECON1,WR ; Se da la orden de escritura

nop ; El microcontrolador ignora estas dos

nop ; instrucciones y no sigue con la siguiente

; hasta que no termine la escritura bsf INTCON,GIE ; Se habilitan las interrupciones bcf EECON1,WREN ; Se prohibe la escritura de nuevos datos

Es una buena práctica de programación verificar que todos los valores escritos en las memorias EEPROM y FLASH son correctos. Para evitar escrituras indeseadas en la EEPROM motivadas por espúreos en la inicialización del microcontrolador, se controla el bit WREN, prohibiendo cualquier operación de escritura mientras duran los 72 milisegundos que temporiza el Timer de Power-up. Pa- ra realizar la misma protección en la memoria FLASH se debe poner a 0 el bit WRT de la Palabra de Configuración, que sólo puede escribirse desde un grabador externo.

Dependiendo del valor del bit WRT y de los bits de Protección de Código CP1 y CP0, ubicados en la Palabra de Configuración, se consiguen diversas alternativas de protección contra lectura y es- critura de la FLASH. (Figura 3.9.)

UN PROGRAMA QUE MANEJA LAS MEMORIAS FLASH DE CÓDIGO Y EEPROM DE DATOS

En este mismo capítulo se han visto trozos de código para leer y escribir la memoria FLASH de ins- trucciones y para escribir la memoria EEPROM de datos. Vamos a realizar ahora un ejercicio que reúna la utilización de estas dos memorias. Para ello, consideraremos que los códigos ya vistos, con una pequeủa modificaciún, son subrutinas a las cuales se llamarỏ para realizar procesos de lectu- ra/escritura sobre las citadas memorias. Así, tendremos las siguientes subrutinas:

Falta por realizar el código correspondiente a la lectura de la EEPROM, que una vez convertida a subrutina quedaría como sigue.

* LEER-EEPROM bsf STATUS,RP1 ; Con estas dos

; instrucciones se bcf STATUS,RP0 ; selecciona el banco 2

movf ADDR_L,W ; Se mete en EEADR

movwf EEADR ; la dirección a leer

bsf STATUS,RP0 ; Se pasa al banco 3 bcf EECON1,EEPGD ; Se selecciona el

; acceso a EEPROM bsf EECON1,RD ; Se da la orden de

; lectura

bcf STATUS,RP0 ; Se pasa al banco 2 movf EEDATA,W ; Se coge el dato leído

movwf DATA_L ; y se deja en

; DATA_L

return ; Retorno de

; subrutina LEER-FLASH

ESCRIBIR-FLASH LEER-EEPROM ESCRIBIR-EEPROM

Programar PIC es fácil

67

En las líneas que empiezan con * se pretende resaltar las modificaciones que habría que llevar a cabo en los códigos anteriores para convertirlos a subrutinas: poner como etiqueta el nombre co- rrespondiente de cada subrutina y como última instrucción la returnpara volver al programa prin- cipal.

Enunciado

La posibilidad de escribir la memoria de código mientras se está ejecutando un programa puede re- sultar interesante para ciertas aplicaciones. Imaginemos que en un programa se necesita saber si es la primera vez que se utiliza, para pedir cierta información de configuración por ejemplo, o si ya se ha utilizado más veces y dicha información ya se tiene. Hay muchos modos de hacer esto: se podría preguntar al usuario, mirar cierta variable para determinarlo y ejecutar una subrutina u otra o, como haremos aquí, modificar el programa la primera vez que se entra para en posteriores ocasiones eje- cutar un código diferente.

En nuestro programa, la primera vez que se ejecute se leerá la primera posición de la EE- PROM (aunque no es estrictamente necesario lo haremos así para probar las funciones vistas en este capítulo). Si en dicha posición se encuentra el valor 27h (que anteriormente deberemos gra- bar) significa que el programa no se ha ejecutado anteriormente, en cuyo caso se inicializarán una serie de contadores y se modificará el programa para que la próxima vez que se ejecute los con- tadores no sean inicializados. Puede parecer que sería más sencillo e igual de óptimo no modifi- car el programa, sino el valor de la EEPROM, y simplemente leer cada vez que se ejecuta el pro- grama la primera posición de ésta, de modo que se salte a un punto u otro. La ventaja de nuestro método es que, aunque un astuto usuario quisiera hacer trampa a nuestro programa variando el va- lor de la EEPROM para que creyera que era la primera vez que se entraba en él, al haberse mo- dificado el programa y, a no ser que tenga el original, le será imposible saber cuál era la secuen- cia que seguía esta primera vez. ¿Se imagina que el cuentakilómetros de los coches tuviera un método tan sofisticado?

En esta ocasión, para resolver el ejercicio sólo necesitamos como base el organigrama ya que, al no utilizar periféricos de E/S, el esquema eléctrico no aporta ningún dato significativo.

Organigrama

El organigrama de la Figura 3.10 representa el funcionamiento más completo del programa, la pri- mera vez que se ejecuta. En siguientes ocasiones, ya desde la primera instrucción se saltará a otras instrucciones.

Programa comentado

Antes de realizar el programa principal se debe hacer un primer programa con el cual se escriba en la primera posición de la EEPROM (dirección 00) el valor 27. Este primer programa se gra- bará en el PIC de la forma habitual y su cuerpo consistirá en una llamada a la subrutina ESCRI- BIR-EEPROM, habiendo antes metido en el registro ADDR_L el valor 00 y en DATA_L el va- lor 27.

Antes de grabar un nuevo programa, como ya se expuso en el primer capítulo, es necesario bo- rrar el PIC, pero este borrado no afecta a la EEPROM, por lo que al grabar el programa que real- mente nos interesa el valor 27 de la primera posición permanecerá ahí.

Ahora, intente seguir el desarrollo del programa e imaginar cuál ha sido el resultado final.

Figura 3.10. Organigrama del programa en su primera ejecución.

LIST P=16F873 ; Se indica el tipo de

; procesador

RADIX HEX ; Sistema de numeración

; hexadecimal

INCLUDE ôP16F873.INCằ ; Se incluye la definiciún de

; los registros internos en

; una librería

LOCAL_VAR EQU 0x20 ; Dirección de comienzo

cblock LOCAL_VAR ; de var. locales

CONT ; Para el bucle de borrado

; de Flash

CONT1 ; Contadores a inicializar CONT2

CONT3

ADDR_H ; MSB de dirección FLASH ADDR_L ; LSB de dirección

; FLASH / EEPROM DATA_H ; MSB del dato FLASH DATA_L ; LSB del dato

; FLASH/ EEPROM DEBUG ; Registro de info.

; de debugging endc

ORG 0x00 ; Inicio en el Vector de

; Reset

goto INICIO ; Instrucción a cambiar por

; goto OTRAS

ORG 0x05 ; Salta el Vector de

; Interrupción

; Las instrucciones siguientes serán borradas tras la lectura de la EEPROM,

; realizándose la inicialización de ciertos valores si el valor leído era

; el esperado, y no haciéndola en caso contrario. En cualquiera de los dos

; casos, estas instrucciones se eliminarán.

INICIO clrf DEBUG

bsf DEBUG, 0 ; Punto de control 0

bcf STATUS, RP1 ; Selecciona banco 1

bsf STATUS, RP0

clrf TRISB ; PORTB como salida

bcf STATUS, RP0 ; Vuelta a banco 0

clrf PORTB

bsf STATUS, RP1 ; Selecciona banco 2

clrf ADDR_L ; Dirección 0 EEPROM

call LEER_EEPROM ; Deja dato leído

; en DATA_L

movlw 0x27 ; Valor para comparar

subwf DATA_L, W ; con dato leído EEPROM

btfss STATUS, Z ; ¿Son iguales?

goto NO_INIC ; No. Se indica que

; ha habido error

goto INIC ; Sí. Se realiza

; la inicialización

; Si se entra en INIC es que es la 1.avez que se ejecuta el programa y en la posición

; 00 de la EEPROM se encuentra el valor 27. Teóricamente, si no fuera así no estaría

; pasando por aquí, ya que las instrucciones no existirían.

NO_INIC bsf DEBUG, 1 ; Punto de control 1

goto MODIFICAR ; Se borra TODO el código

; de comparación e inic SIN haber realizado la INIC. Si entra por aquí algo

; va mal

INIC bsf DEBUG, 2 ; Punto de control 2

clrf CONT1 ; Se inicializan contadores

movlw 35

movwf CONT2

movlw 49

movwf CONT3

MODIFICAR bsf DEBUG, 3 ; Punto de control 3

bsf STATUS, RP1

bcf STATUS, RP0 ; Se selecciona banco 2

clrf ADDR_H ; MSB dir FLASH

clrf ADDR_L ; LSB dir FLASH

movlw b’00101000’ ; MSB instrucción goto k

movwf DATA_H

movlw OTRAS ; LSB instrucción goto k

movwf DATA_L ; →goto OTRAS

; (OTRAS ha de ser una etiqueta cuya dir en la Flash sea < = 255 )

call ESCRIBIR_FLASH

bcf STATUS, RP0 ; Banco 2

; (ESCRIBIR_FLASH

; deja en el 3)

movlw d’36’ ; N.oinstrucciones a borrar

movwf CONT ; desde la dir 0x01

BORRAR incf ADDR_L, F ; Siguiente dir a borrar

clrf DATA_H ; MSB instrucción nop

clrf DATA_L ; LSB instrucción nop

call ESCRIBIR_FLASH

bcf STATUS, RP0 ; Banco 2

decfsz CONT, F ; ¿Contador a 0 ?

goto BORRAR ; No. Seguir borrando

bsf DEBUG, 4 ; Punto de control 4

goto OTRAS ; Sí. Ir a la parte que

; siempre se ejecuta

OTRAS bsf DEBUG, 5 ; Punto de control 5

bcf DEBUG,7 ; Será el único punto de

; control que se vea a partir de la 2.aejecución

bcf STATUS, RP1

bsf STATUS, RP0 ; Banco 1

clrf TRISB ; PORTB como salida. Hay

; que volverlo a configurar aquí porque sólo la primera vez se inicilizará al

; principio del programa

¿Se ha dado cuenta de nuestra pequeủa trampa? Hemos introducido puntos de control a lo largo de todo el programa poniendo a 1 los bits de un registro según se iban ejecutando partes, y mos- trando el valor total al final del programa. De esta forma, podemos comprobar de una forma rápida y fiable el cambio de nuestro código. Estos puntos de control no forman parte del programa en sí, por lo que no se muestran en el organigrama ni en el esquema eléctrico. Una vez comprobado el buen funcionamiento pueden ser eliminados.

El programa ha cambiado completamente, tal y como se muestra más abajo. Tras la primera ins- trucción, la mayoría de las instrucciones han sido cambiadas por el código de operación de la ins- trucción NOP. A partir de ese código, aun teniendo acceso a él, sería imposible conocer el progra- ma original. Este mismo método puede utilizarse para aplicaciones de aprendizaje en el campo de la Inteligencia Artificial, donde microbots controlados por microcontrolador pueden ir variando sus programas dinámicamente para adaptarse a situaciones concretas.

bcf STATUS, RP0 ; banco 0

movf DEBUG, W ; Se saca por la puerta B los

movwf PORTB ; puntos de control por los

; que ha pasado el programa

goto OTRAS

INCLUDE <eeprom.asm> ; Ficheros de escritura y INCLUDE <flash.asm> ; lectura de las memorias

END ; Fin de programa

Figura 3.11. PICME-TR mostrando el código del programa una vez modificado.

Prueba del programa

En un programa donde no hay entradas y salidas el resultado no puede comprobarse a simple vista.

Podemos introducir puntos de control, como en nuestro caso, o utilizar herramientas adecuadas pa- ra ello. Los pasos a realizar son los siguientes:

1.o Grabe en el microcontrolador el primer programa para situar en la posición 00 de la EEPROM el valor 27.

2.o Ejecútelo.

3.o Vuelva al programa de grabación PICME-TR y elija la opción Leer PIC, dentro de la ventana MO- DELO ELEGIDO,Editar Datos. La información de la ventana superior izquierda habrá variado pa- ra contener las posiciones de la EEPROM de datos. Compruebe que en la posición 00 efectiva- mente se ha grabado un 27.

4.o Grabe ahora el programa del enunciado y, antes de ejecutarlo la primera vez, elija de nuevo Leer PIC y fíjese en la ventana BUFFER DE MEMORIA DE PROGRAMA. Compruebe además que el valor de la EEPROM sigue ahí.

5.o Ejecute el nuevo programa en el PIC.

6.o Vuelva de nuevo al PICME-TR y lea el PIC para comprobar qué tiene ahora dentro. ¿Ha variado?

Một phần của tài liệu Microcontroladores PIC diseno practico de aplicaciones segunda parte PIC16F87X PIC18FXXX 2 ed jose angulo (Trang 77 - 96)

Tải bản đầy đủ (PDF)

(394 trang)