# Guardar datos no volatiles en PIC16F877A



## Mol (Mar 25, 2007)

Hola.
Estoy usando un PIC16F877A en un proyecto de una báscula industrial. Tengo que guardar datos de los pesajes, la compañia y el producto pesado. Necesito guardar el máximo número de datos posibles, pero la memoria EEPROM es bastante escasa en este modelo 256 bytes. Por otro lado tengo 8K de flash, pero es memoria de programa. ¿Se puede usar la memoria de programa para gaurdar datos, escribir y modificarlos?¿Si se puede como lo hago?


----------



## Jairo (Mar 25, 2007)

Hola que tal

Claro que puiedes utilizar esa memoria para mayor información revisa el datasheet del pic, en la parte de la memoria flash, ahi te dice la subrutina para escribir y leer de esa parte de la memoria, ademas en la pagina www.microchip.com puedes encontrar información acerca de la programacion para grabar en la flash

Saludos

jairo


----------



## tiopepe123 (Mar 25, 2007)

No te recomiendo utilizar la memoria de programa por dos razones.
Por la salud del programa o sofware del pic, un error y ya te puedes imaginar
Por que tiene un endurance o limite de veces que se puede escrivir de 1000 veces

Te recomiendo utilizar una eeprom externa tipo 24C02,24c08...24c128. o la serie 93c56..

tambien mira en microchip.

Tienes dos ventajas, primero si se estropea se puede cambiar facilmente.
Tiene una endurance mucho mayor.
Si por lo que sea tienes que leerla la puedes sacar del zocalo y leerla facilmente con cualquier programador o circuito tipo ICPROG, con un tE20 o un pipo o cualquier programador de tarjetas pirada de satelite.

Para que veas la importancia del tema, ultimamente me llegan TV que no arrancan, todo va bien, la fuente, la circuiteria, tensiones, el micro pero no funciona.

Resulta que tienen arzaimer, si ellas tambien tienen , les cambias la eeprom y listo , como una seda.

Si es interna debes cambiar el micro, bueno hay un modelo que se logra resucitarlo tostandolo un poquito.

Finalmente tambien se puede utilizar un tarjeta de cámara de fotos tipo SD/MMC y un zocalo de disquetes como enchufe.

Espero que te sirva la sugerencia


----------



## dragonspirit (Abr 17, 2007)

Hola a todos

Estoy interesado en el tema. Estoy haciendo un circuito parecido al que comento el compañero Mol. Yo había pensado utlizar una memoria externa (EEPROM o una tarjeta SD), pero me han comentado que la comunicación con la SD da bastantes quebraderos de cabeza. Me dispongo a utilizar un EEPROM, pero no he utilizado nunca ninguna memoria externa, y no tengo ni idea de como hacerlo.

¿Qué memoria me recomendais? 
¿Teneis algún ejemplo de como grabar y leer datos en una memoria EEPROM desde el PIC?



Muchas gracias

Un saludo


----------



## maunix (Abr 18, 2007)

Mol dijo:
			
		

> ¿Se puede usar la memoria de programa para gaurdar datos, escribir y modificarlos?


Sí, se puede.



			
				Mol dijo:
			
		

> ¿Si se puede como lo hago?



Está en la sección Flash Memory del datasheet.  Este micro graba 4 words por vez.

Si guardarás muy seguido los datos te sugiero hagas el uso de lo que te han sugerido de usar una memoria externa, si los datos se grabarán esporádicamente no veo inconveniente para usar la flash interna de hecho para datos no volátiles y que se modifiquen rara vez, suele ser hasta mejor opción usar la flash que la eeprom.  Eso si, verifica luego de grabar.

Saludos


----------



## maunix (Abr 18, 2007)

dragonspirit dijo:
			
		

> Hola a todos
> 
> Estoy interesado en el tema. Estoy haciendo un circuito parecido al que comento el compañero Mol. Yo había pensado utlizar una memoria externa (EEPROM o una tarjeta SD), pero me han comentado que la comunicación con la SD da bastantes quebraderos de cabeza. Me dispongo a utilizar un EEPROM, pero no he utilizado nunca ninguna memoria externa, y no tengo ni idea de como hacerlo.
> 
> ...



¿Qué capacidad necesitas?

¿Por SPI o I2C?

Microchip tiene notas de aplicacion de grabación de memorias i2c y spi.


----------



## dragonspirit (Abr 23, 2007)

Hola a todos,

Gracias por tu contestacion Maunix. Estoy pensando utilizar una memoria 25LC1024 que pedí de muestra hace tiempo, y no he utilizado nunca. La comunicacion con ésta es por SPI (supongo que la conoceras), nunca he utilizado SPI, pero estoy leyendo el datasheet y las notes de aplicacion y no parece muy complicado. Necesito una capacidad de una 400K, ya que necesito guardar muchos datos (adquiero muestras cada X segundos) y cada dato me ocupa unos 4 bytes. Pedía un ejemplo para hacerme una idea del funcionamiento de este tipo de comunicaciones, ya que lo que he trabajado con PIC, nunca me he dedicado yo al tema de la comunicacion, y me he centrado más en el tratamiento de muestras adquiridas con sensores y cosas asi.

Muchas gracias otra vez

Un saludo


----------



## maunix (Abr 23, 2007)

Fíjate, que en otro hilo te respondí sobre el uso y capacidad de estas memorias!

Tal vez no sea lo que necesites.


----------



## dragonspirit (Abr 23, 2007)

Perdona Maunix, ha sido una equivocacion, no recordaba que ya habia planteado esta duda en otro tema.

Muchas gracias y perdon por mi error


----------



## maunix (Abr 23, 2007)

dragonspirit dijo:
			
		

> Perdona Maunix, ha sido una equivocacion, no recordaba que ya habia planteado esta duda en otro tema.
> 
> Muchas gracias y perdon por mi error



Ey, no hay problema.  Solamente te comentaba que ya se habló del tema en otro hilo


----------



## COARITES (Feb 23, 2010)

Alguien me podria pasar un ejemplo de como grabar y hacer lectura de una memoria EEPROM externa con el pic 16f877A


----------



## vertigo2040 (Oct 7, 2010)

el codigo es con pic simulator ide para el 16F877a y una memoria 24c256 que cuesta 2 dolares americanos


Define CONF_WORD = 0x3f72
Define CLOCK_FREQUENCY = 12
AllDigital

Define LCD_BITS = 8
Define LCD_DREG = PORTD
Define LCD_DBIT = 0
Define LCD_RSREG = PORTE
Define LCD_RSBIT = 0
Define LCD_RWREG = PORTE
Define LCD_RWBIT = 1
Define LCD_EREG = PORTE
Define LCD_EBIT = 2
Define LCD_READ_BUSY_FLAG = 1
Lcdinit

Symbol scl = PORTC.3
Symbol sda = PORTC.4

Dim addr As Word
Dim data As Byte

For addr = 0 To 31
	Lcdcmdout LcdClear
	data = 255 - addr
	I2CWrite sda, scl, 0xa0, addr, data
	Lcdout "Write To EEPROM"
	Lcdcmdout LcdLine2Home
	Lcdout "(", #addr, ") = ", #data
	WaitMs 500
Next addr

For addr = 0 To 31
	Lcdcmdout LcdClear
	I2CRead sda, scl, 0xa0, addr, data
	Lcdout "Read From EEPROM"
	Lcdcmdout LcdLine2Home
	Lcdout "(", #addr, ") = ", #data
	WaitMs 500
Next addr


----------



## mcpiebot (Oct 7, 2010)

En la nota de aplicación AN976 de microchip se explica el uso de las memorias externas, se explica también el protocolo I2C y se da un código de ejemplo.

Saludos!


----------



## BeToR (Oct 18, 2011)

Buenas tardes.

Tengo una duda, si se usara unicamente la EEPROM interna del PIC, para guardar una variable que llega a un valor de mas de 256 como se le haria en la programacion?

Yo estoy usando programacion en C, uso el programa MikroC y si logro guardar en la memoria EEPROM interna del PIC16f877A, pero solo guarda hasta el numero 255 del conteo de mi variable y empieza nuevamente en 0.

Si quiero que guarde numeros mayores como 300, 1000, como puedo unir dos direcciones de la eeprom para que cuente mas? o como se solucionaria este problema?

Gracias.


----------



## gardab (Dic 1, 2013)

Hola, comunidad.
Estoy haciendo una báscula digital utilizando un pic 16f877a y haciendo el programa en C++.
Ya tengo lo que es el convertidor AD y la salida al LCD, pero además de la conversión le quiero poner una función de puesta a cero, en la que se pueda poner un recipiente en la plataforma y despreciar su peso para medir solo lo que sería el peso de la comida.
Estaba pensando en guardar el dato del peso del recipiente y luego medir el recipiente con el alimento para restar ambos datos, pero no sé como guardar el dato de la salida del ADC y después utilizar el posterior para hacer la resta, me gustaría que me pudieran ayudar con esto o si hay una forma más fácil de realizar la función.
Gracias de antemano.


----------



## ByAxel (Dic 1, 2013)

Hola.
Para guardar datos se usan variables (es básico si ya sabes realizar operaciones) y que sean del mismo tipo (byte con byte, int con int, etc). Si el detalle es que se apaga el aparato, entonces se puede usar la memoria EEPROM para mantener el valor ahunque el PIC se apague...

PD: Dudo que sea C++, los PICs de gama media soportan hasta ANSI C, no más.
Saludos.


----------



## gardab (Dic 1, 2013)

Sí, perdón, en C.
Y bueno, de las variables sí sé, solo que no sé cómo hacer esto.
Mi idea era la siguiente:
Poner el recipiente (un vaso, un plato, etc.) en la plataforma y tomar un valor del ADC
Guardar este valor.
Poner el ingrediente en el recipiente y el valor del ADC que me sale aquí, restarle el que ya había guardado.

No sé si se pueda así y sin memoria EEPROM (no cuento con una en este momento)
Agradecería su ayuda.


----------



## ByAxel (Dic 1, 2013)

Supongo que las dos acciones (poner un baso y poner ingrediente) son acciones por separado y accionados manualmente para que sepa el PIC. Si es el caso entonces se puede:
- Acción A = poner un vaso, valor del ADC = varA.
- Acción B = poner ingrediente, valor ADC = varB.
- Entonces ya puedes restar.

No es el caso, entonces se puede intentar:
- El ADC en cero y cuando se detecte un cambio muy grande en el valor ADC se suponer que es la acción A, cuando se estabilice y pasado un tiempo (milisegundos) vuelve a haber otro cambio cualquiera y mayor se puede decir que es la acción B.
Es una idea, pero almenos el PIC necesita saber cuando son esos cambios de lo contrario se pone algo complicado...

PD: El PIC incluye memoria EEPROM interna...
Saludos


----------



## Gino98Electronica (Jul 18, 2019)

Buenas tardes, estoy trabajando con RFID y tengo que guardar los TAGS en la memoria para luego compararlos y mostrar en pantalla si es bienvenido o no. Mi problema es que recibo los tags y los guardo en la eeprom, pero cuendo voy a comprar solo me toma como valido el ultimo TAGS guardado. a los tags los guardo en:

```
int dir=0;
char UID[8]; // VARIABLE DONDE GUARDO EL TAG

WRITE_EEPROM(DIR,UID); //con este escribo la memoria
DIR++
read_eeprom(UID); CON ESTE LA LEO
```


----------



## DJ T3 (Jul 18, 2019)

Pon el codigo completo.
"*dir*" no es lo mismo que "*DIR*".
La longitud del "tag" es exactamente 8 caracteres, osea no es superior?


----------



## Gino98Electronica (Jul 18, 2019)

```
int x=0, dir=0;
char UID[8], UID1[8], j[8];

while(input(b1)==1) //CON ESTO GUARDO EL TAG
      { 
         delay_ms(20);
         LCD_PUTC("\f");
         LCD_GOTOXY(1,1);
         printf (LCD_PUTC, ":colocar TAG:");
         if (MFRC522_isCard (&TagType))                                           
         {                   
            DELAY_MS(20);
            if (MFRC522_ReadCardSerial (&UID1))             
            {
               for (i=0 ;i<=8; i++)
               {
                  LCD_GOTOXY(i+21,2);
                  printf (LCD_PUTC, "%x",UID1[i]);
               }
               dir++;
               WRITE_EEPROM(dir,UID1);
            }
            
if (MFRC522_isCard (&TagType)) //CON ESTE COMPARO       
      {
         LCD_PUTC("\f");
         LCD_GOTOXY(1,2);
         //printf (LCD_PUTC, "Ttp:%d",TagType);      //%x   
         //Read ID
         if (MFRC522_ReadCardSerial (&UID))             
         {
            if(dir!=0)
            {
               for(y=0;y<=dir;y++)     //Compara el TAG con las guardadas en la memoria
               {
                  strcpy(j,READ_EEPROM(y));
                  
                  if(strcmp(UID,j)==0)
                  {
                     //levanta servo
                     LCD_PUTC("\f");
                     lcd_gotoxy(5,2);
                     printf(lcd_putc, "Bienvenido");
                     delay_ms(2000);
                     LCD_PUTC("\f");
                     break;
                  }
               }
            }
```

@DJ T3  No pongo todo el código porque es extenso y no esta terminado, al tag lo corto yo para que sea de 8 bits por eso los meto en vectores de 8, porque después del bit 5 se repiten todos los números. El tema es porque solamente me toma el ultimo tag que guardo y los otros que guarde no


----------



## Dr. Zoidberg (Jul 18, 2019)

Por que será que no usan la potencia expresiva del lenguaje C cuando escriben esa chorrera de código??


----------



## Gino98Electronica (Jul 18, 2019)

Dr. Zoidberg dijo:


> Por que será que no usan la potencia expresiva del lenguaje C cuando escriben esa chorrera de código??


Podrías ayudarme? ya que no se mucho


----------



## Dr. Zoidberg (Jul 18, 2019)

Dificilmente pueda ayudarte leyendo un fragmento de código completamente desarmado, sin comentarios y que opera sobre un sistema que desconozco completamente lo que hace.

Lo correcto es que te sientes, estudies mucho, aprendas a programar y modelar el software y recien entonces intentes resolver un problema.


----------



## DJ T3 (Jul 18, 2019)

Ademas de lo que dice el Dr , esta el problema que tampoco sabemos con qué librerias estás usando, ya que ésta puede tener algun "bug", asi como el resto del codigo.


----------

