Siguenos en ...

Google+facebooktwitter

youtubepinterest RSS aquihayapuntes

Últimos Tutoriales


Licencia

Creative Commons

 

Todo el contenido de este sitio está bajo una licencia de Creative Commons

 

Recursos del PIC. Uso de la memoria EEPROM interna

CCS implementa muchas funciones para trabajar con las memorias EEPROM,  algunas de ellas son:

  • value = read_eeprom (address): función básica para leer el valor de la EEPROM interna del PIC.  Devuelve un valor entero (int8) de un byte. "address" puede ser un entero de 8 ó 16 bit.  Dependiendo del PIC que utilicemos dispondremos de mas ó menos memoria EEPROM, por ejemplo el PIC 16f84A  dispone de 64 bytes y los pic16F87X tienen 256 bytes que se direccionan del 0 a 255.
  • write_eeprom (address, value): esta función escribe un dato (entero de 8 bit) en la dirección especificada en address en la memoria interna del PIC. Al igual que read_eeprom address puede ser un entero de 8 ó 16 bit.

 

Algunos dispositivos permiten  leer y escribir datos en la memoria de programa en tiempo de ejecución, para los dispositivos que soportan esta funcionalidad CCS, nos proporciona las siguientes funciones:

 

  • value = read_program_eeprom (address): esta función lee un dato de la memoria de programa del PIC  y devuelve el valor leído como un entero de 16 bits. Adrress es un entero de 16 ó 32 bits  que depende del dispositivo empleado.
  • write_program_eeprom (address, data): función homologa a la anterior pero que nos permite  escribir datos en la memoria de programa. data tiene que ser un entero de 16 bits.


CCS también incorpora funciones para leer y escribir en memorias EEPROM externas:

read_external_memory(address, dataptr, count )
write_program_memory( address, dataptr, count)


Como veis CCS nos aporta una serie de funciones para trabajar fácilmente con este tipo de memorias,

estas que he puesto aquí son algunas de ellas, pero todavía hay más. Mejor ir viéndolas poco a poco con ejemplos.

Algunas consideraciones a tener en cuenta sobre las memorias EEPROM es que son rápidas en el proceso de lectura, pero pueden tardar varios ms en realizar un proceso de escritura. Otro factor a tener en cuenta es que se pueden hacer operaciones de lectura sobre el valor de sus registros el numero de veces que se quiera, pero soportan un número limitado de ciclos de escritura / borrado. Ese número según Microchip es de aproximadamente un millón,  el que quiera que lo compruebe.  

La memoria EEPROM de datos no está mapeada en la zona de la memoria de datos donde se ubican los registros SFR y GPR, si programáramos en Ensamblador deberíamos realizar una serie de pasos para su lectura y escritura que aunque no difíciles resultan al menos laboriosos, CCS nos permite abstraernos por completo del proceso de lectura y escritura,  lo único que tenemos que saber es las funciones que tenemos que aplicar y los parámetros y  valores que devuelven dichas funciones.

Como 1º ejemplo del uso de este tipo de memorias vamos a utilizar las funciones básicas para leer y escribir datos en la memoria interna del PIC: read_eeprom (address) y write_eeprom (address, value).  

El ejemplo es un contador del tipo "su turno" que solemos encontrar en algunos  establecimientos como carnicerías y pescaderías. Como funcionalidades mínimas he puesto que sea capaz de contar del 0 al 99.
Y por supuesto que si se va la corriente guarde en memoria el último valor.

El esquema del circuito será el siguiente:

 

Circuito contador ascendente 0 a 99

 

Cuando queremos utilizar mas de un display y minimizar el número de patillas en el PIC para su control hay varias formas de hacerlo, una de ellas (la que he utilizado en este ejemplo) es utilizar un decodificador BCD a 7 segmentos como el 7447, el datasseht lo tenéis aquí. Donde se puede ver el diagrama lógico y su tabla de verdad.

Otra forma es multiplexar las líneas de datos, es decir en cada instante solo habrá un display activo pero el cambio de uno a otro será tan rápido que para el ojo humano parecerá que los dos están activos a la vez, este sistema es bueno porque nos ahorramos los decodificadores, pero si utilizamos mas de cuatro display, notaremos un parpadeo molesto.  

El código del programa será el siguiente:

 
 /*-----------------------------------------------------------*\  
|  Uso de la memoria EEPROM del PIC                          |  
|  autor: biblioman                                          |  
|  www.aquihayapuntes.com                                    |  
\*-----------------------------------------------------------*/  
 
#include <16F877.h>  
//Configuración de los fusibles.  
#FUSES NOWDT, XT, NOPUT, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG  
#use delay(clock=4000000) //Frecuencia de reloj 4MHz  
#byte  puerto_D = 0x08    // Identificador para el puerto C.  
 
 #int_EXT 
 
 void EXT_isr( void ) 
 { 
 
 if ((read_eeprom(0)==0x99)||(read_eeprom(0)==0xFF)) 
 { 
 write_eeprom(0,0); 
 puerto_D=read_eeprom(0); 
 } 
 else if ((read_eeprom(0) & 0x0F)<0x09) 
 {     
 write_eeprom(0,(read_eeprom(0))+1); 
 puerto_D=read_eeprom(0); 
 }       
 else if ((read_eeprom(0) & 0x0F)>=0x09) 
 {        
 write_eeprom(0,(read_eeprom(0))+7); 
 puerto_D=read_eeprom(0); 
 }    
 
 } 
 
 void main() 
 { 
 set_tris_b(0xFF); //Puerto B como entrada  
 set_tris_d(0x00);//Puerto D como salida 
 enable_interrupts(GLOBAL);  // Se habilita la interrupción global 
 enable_interrupts(INT_EXT); // Se habilita la  interrupción externa 
 puerto_D =0xFF; //inicializo puerto D 
 //write_eeprom(0,0xFF);Resetear EEPROM 
 while(true) 
 { 
 //Resto del programa   
 
 } 
 } 
 
 

Comentario del programa:

El ejemplo básicamente es un contador ascendente de 0 a 99 que incrementa su valor cada vez que pulsamos el pulsador "su turno" para evitar que el contador se reinicie y empiece a contar desde cero cada vez que se vaya la corriente, el valor actual del contador se almacenará en la memoria EEPROM del PIC en vez de en  la memoria RAM. Como solo queremos guardar un valor que estará comprendido entre 0 y 99, solo utilizaremos el primer byte de la memoria EEPROM. Para detectar cuando se pulsa el pulsador, se utiliza la interrupción externa en la patilla RB0/INT.

Dentro de la función de interrupción nos encontramos con tres sentencias condicionales:

if ((read_eeprom(0)==0x99)||(read_eeprom(0)==0xFF))
{
write_eeprom(0,0);//escribo el valor 0 en la dirección 0 de la memoria EEPROM
puerto_D=read_eeprom(0);//asigno al puerto D el valor devuelto por la función de lectura de la EEPROM
}

La primera vez que se ejecute el programa el valor de la EEPROM es 0xFF (viene así de fabrica) por lo que tendremos que sobreescribir su valor a 0 para iniciar el contaje, después de esto esta condición solo se cumplirá cuando el contador llegue a 99.  

else if ((read_eeprom(0) & 0x0F)<0x09)
{     
write_eeprom(0,(read_eeprom(0))+1);
puerto_D=read_eeprom(0);
}


Cada "nibble" del puerto D está conectado a un decodificador por lo que tenemos RD0-RD3 al decodificador U2 y su salida conectado al display de las unidades a través del bus de datos (hay que hacer un zoom sobre el esquema en Proteus para ver las conexiones) y RD4-RD7 al decodificador U3, que está conectado al display de las decenas.


Pues bien, si tenemos 4 bits por "nibble" tendremos 16 combinaciones posibles, incrementamos con 1 el valor de la EEPROM  mientras el valor del "nibble" de menor peso sea < 9. Fijaros como la función de escritura en la EEPROM nos permite poner como parámetro la función de lectura por lo que no es necesario declarar una variable local para hacer de intercambio.


Una vez incrementado el valor de la EEPROM, hacemos una nueva lectura y asignamos su valor al puerto D.

else if ((read_eeprom(0) & 0x0F)>=0x09)
{        
write_eeprom(0,(read_eeprom(0))+7);
puerto_D=read_eeprom(0);
}


Los valores del "nibble" de menor peso correspondientes al rango 10-15 los saltamos sumando 7 en vez de uno. El nibble de mas peso de la lectura de la EEPROM no me interesa ya que el primer if ya se encarga de ponerlo a cero cuando el valor llegue a 0x99. Para discriminar el "nibble" de mas peso de la EEPROM lo enmascaramos antes de hacer la comparación

Podemos ver los registros de la EEPROM interna del PIC, si en Proteus seleccionamos Debug-->PIC CPU EPROM Memory.

 

Registros EEPROM interna PIC 16f877

 

Proteus simula bastante bien el uso de la memoria EEPROM del PIC, si paramos la simulación y volvemos a iniciarla vemos como los valores de la EEPROM se mantienen.

El DNS del circuito lo tenéis aquí

Para cualquier duda, sugerencia ó mejora como siempre la podéis hacer en el foro.


Mejor tutorial de la semana en abcdatos
Un saludo y hasta pronto

© 2007-2017 AquiHayapuntes.com