Autor Tema: PROBLEMA CON EEPROM DEL PIC 16F876  (Leído 2710 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado pipipi

  • PIC12
  • **
  • Mensajes: 91
PROBLEMA CON EEPROM DEL PIC 16F876
« en: 03 de Octubre de 2010, 12:06:52 »
HOLA amigos del foro:

Me encuentro trabajando en un proyecto en el cual necesito su ayuda, el proyecto consiste en tomar una lectura del adc del pic convertirla a temperatura y visualizarla en 4 display´s de 7 segmentos. Se tiene un teclado el cual consta de tres botones con uno de ellos accedemos a un especie de menu en el cual se puede modificar una variable con dos botones mas, uno de incremento y otro de decremento, esta variable es sumada o restada a la temperatura segun sea el caso. Hasta este punto no tengo ningun problema y todo marcha a la perfeccion pero ahora necesito almacenar la variable de suma o resta en la EEPROM del micro para asegurar que si por algun motivo se desconecta la alimentacion del pic esta variable se respete y no se pierda la programacion es la siguiente:


#include <16f876.h> //pic a utilizar
#FUSES XT,NOWDT,NOPROTECT,NOPUT//Mandos para el programador
#device adc=10//configuramos adc a 10 bits
#use delay (clock=4000000) //Fosc=4Mhz
#define A1      PIN_A1
#define A4      PIN_C7
#define A5      PIN_A5

float32 adc,dato[10];//lectura adc,s1; letras a mandar
int tab7seg[10]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xe7};//tabla para datos de display
int uni;//variable para guardar unidades
int dec;//variable para guardar decenas
int dp;//variable para guardar unidades despues del punto
int num=0; //variable para almacenar dato antes de descomponer
int t;//variable para dato[?]
int a;//variable para ciclos pequeños
int16 b;//variable para 1 ciclo grande
int n;//variable para muestras s1
int x=0;//mute


void determinar_dato(void);


void main (void)
{

/////////////////////////////////////CONFIGURACION///////////////////////////////

   set_tris_b (0x00);//configuramos puerto b como salida
   set_tris_c (0xf0);//configuramos puerto c como salida
     
   setup_adc(ADC_CLOCK_INTERNAL );//oscilador interno para el ADC
   (setup_adc_ports(AN0_VREF_VREF ));//configuramos adc y voltajes de referencia
   set_adc_channel( 0 );//seleccionamos adc1 para el sensor1
   delay_us(20);
   
   output_b (0x00);//ponemos en cero el puerto b
   output_c (0x00);//ponemos en cero el puerto b
   
   dato[1]=-15;//alarma alta
   dato[2]=-25;//alarma baja
   dato[3]=0;//of_set
   
   dato[4]=0;//menor
   dato[5]=0;//mayor
   
///////////////////////////////FIN DE CONFIGURACION///////////////////////////////

while(true)
{


///////////////////////////LECTURA DE SENSOR DE GABINETE/////////////////////////

 for(n=0;n<50;n++)//ciclo
   {
   
      adc = adc+read_adc();//leemos lo que hay en adc y lo guardamos en adc
   
   }
   
      adc=adc/50;
   
   
 
   
   
   if(adc<512)//0/-35°C
   {
     
      adc=adc/14.62857143;
      dato[0]=35-adc;
      dato[0]=(dato[0]*(-1));
      dato[0]=dato[0]+(dato[3]);
     
   }
   
   else//0/35°C
   {
      adc=adc/14.61428571;
      dato[0]=adc-35;
      dato[0]=dato[0]+(dato[3]);
   
   }



///////////////////////FIN DE LECTURA DE SENSOR//////////////////////////////////


 
 t=0;
 determinar_dato();

 


////////////////////////////////TECLADO/////////////////////////////////////////////////

if(input (PIN_C5))//
{

   salir:

   //****************mandamos os*******************

   for(a=0;a<=150;a++)//ciclo para visualizar os
   {
   
   
   
      output_b (0xbf);//mandamos O
      output_high(pin_C1);//prendemos display 2
      delay_ms(3);//esperamos 3ms
     
      output_low(pin_C1);//apagamos display 2
      output_b (0x6d);//mandamos S
      output_high(pin_C2);//prendemos display 3
      delay_ms(3);//esperamos 3ms
     
      output_low(pin_C2);//apagamos display 2
         
   }
   
    //*****************fin de os*********************

    //***************ciclo para of-set**************

    for(b=0;b<=600;b++)//ciclo para modificar datos del menu
    {
   
    t=3;
    determinar_dato();
     
      if(input (PIN_C4) && dato[t]>-6)//si se oprime decrementar
      {
         dato[3]=dato[3]-0.1;
         delay_ms(200);
         b=0;//ponemos a cero y
                   
     
      }

      if(input (PIN_C6) && dato[t]<6)//si se oprime incrementar
      {
     
         dato[3]=dato[3]+0.1;
         delay_ms(200);
         b=0;
               
     
      }



    //*********************fin de ciclo de os (principal)********************

}

/////////////////////////////FIN DE TECLADO//////////////////////////////////////////////
   
}


}

}







/////////////////////////////////////DETERMINAR Y MANDAR DATO////////////////////////////


void determinar_dato(void)
{
   if(dato[t]<0)
   {
      dato[t]=(dato[t]*(-1));//temperatura positiva
      num=dato[t];//pasamos lo que hay en temp1 a num para encontrar numeros a mandar
      dec=num/10;//encontramos decimas     
      uni=dato[t]-(dec*10);//encontramos unidades
      dp=(dato[t]-num)*10;//encontramos unidades despues del punto
      dato[t]=(dato[t]*(-1));//temperatura negativa
   
      output_b (0x40);//mandamos dato -
      output_high(pin_C0);//prendemos el display 1
      delay_ms(3);//esperamos 3ms
   
   }
   
   else
   {
      num=dato[t];//pasamos lo que hay en temp1 a num para encontrar numeros a mandar
      dec=num/10;//encontramos decimas     
      uni=dato[t]-(dec*10);//encontramos unidades
      dp=(dato[t]-num)*10;//encontramos unidades despues del punto
   
   }
     
      output_low(pin_C0);//apagamos diplay 1
      output_b (tab7seg[dec]);//mandamos decima
      output_high(pin_C1);//prendemos display 2
      delay_ms(3);//esperamos 3ms
   
      output_low(pin_C1);//apagamos display 2
      output_b (tab7seg[uni]);//mandamos unidades
      output_high(pin_C2);//prendemos display 3
      delay_ms(3);//esperamos 3ms
     
      output_low(pin_C2);//apagamos display 3
      output_b (tab7seg[dp]);//mandamos decimas despues del punto
      output_high(pin_C3);//prendemos display 4
      delay_ms(3);//esperamos 3ms
      output_low(pin_C3);//apagamos display 4
     
 } 



////////////////////////////////////////FIN DE DETERMINAR Y MANDAR DATO///////////////////


Como podran observar se toma la lectura del adc del micro y se almacena en la variable dato0, despues esta variable pasa a una subrutina en la cual se determina la temperatura y se visualiza en los display´s. Como lo emcione existen 3 botones con los cuales se modifica una variable llamada dato3 esta variable es sumada o restada a la temperatura segun se requiera. Como podria guardar esta variable en la EEPROM del PIC para asegurar que se guarden los cambios aun y cuando se le quite la alimentacion al PIC?. Espero y me puedan ayudar garcias




Desconectado Diego E.

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1086
Re: PROBLEMA CON EEPROM DEL PIC 16F876
« Respuesta #1 en: 04 de Octubre de 2010, 09:29:45 »
Hola amigo, para guardar una variable en la eeprom sólo debes hacer algo como esto:

Para grabar:
write_eeprom(0, unidades);
write_eeprom(1, decenas);
write_eeprom(2, centenas);

Para leer:
unidades= read_eeprom(0);
decenas= read_eeprom(1);
centenas= read_eeprom(2);

saludos

Desconectado pipipi

  • PIC12
  • **
  • Mensajes: 91
Re: PROBLEMA CON EEPROM DEL PIC 16F876
« Respuesta #2 en: 05 de Octubre de 2010, 18:37:50 »
Hola Diego E:

Muchas gracias por tu respuesta, ok esa seria la forma de escribir y leer la eeprom, pero el problema que tengo es el siguiente: si yo guardo desde un principio un dato en la eeprom, entiendo que cada vez que desconecto la alimentacion el pic realizaria exactamente lo mismo, pero lo que yo necesito es que el dato que yo tengo almacenado en dato0 la primera vez que conecte el pic dato0=0 pero si se modifica dicho dato antes de desconectar el pic se guarde en la eeprom el nuevo, y asi cadavez que se desconecte y conecte el pic se vaya almacenando el nuevo dato si es que se oprimio alguna de las teclas para incrementar y decrementar. gracias  :-/

Desconectado Diego E.

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1086
Re: PROBLEMA CON EEPROM DEL PIC 16F876
« Respuesta #3 en: 05 de Octubre de 2010, 18:48:51 »
Si el dato se guarda cada vez que presionan una tecla podría atentar contra la vida útil de la EEPROM, son como 1 millón de grabadas, si las teclas las presionan pocas veces no hay problema es calcular más o menos cuanto duraría. Yo en algunos casos utilizo un pin para detectar cuando desconectan la energía del PIC es traer un nivel lógico antes del condensador de rizado, así cuando se va la energía hay un cero en el pin del PIC y se graba el dato antes de que el condensador de la fuente del PIC se descargue.

saludos.

Desconectado pipipi

  • PIC12
  • **
  • Mensajes: 91
Re: PROBLEMA CON EEPROM DEL PIC 16F876
« Respuesta #4 en: 05 de Octubre de 2010, 20:08:24 »
Hola Diego:

Gracias por contestar muy buena idea lo checo y te cuento como me fue va?. Gracias.

Desconectado MicroControladoresPIC

  • PIC10
  • *
  • Mensajes: 4
Re: PROBLEMA CON EEPROM DEL PIC 16F876
« Respuesta #5 en: 15 de Octubre de 2010, 22:58:30 »
No me parece mal guardar cada vez que se presione, creo que con uan cuenta rapida duraria años, y de ultima, podes guardar demas de el dato un contador, con las veces que se gaurdo un dato en la eprom, y al llegar a cierto numero de veces, empezar a grabar en otras posiciones de memoria, de la misma eprom, ya que la eeprom se va quemando de a byte.


saludos


http://microcontroladorespic.dyndns.org

Desconectado pipipi

  • PIC12
  • **
  • Mensajes: 91
Re: PROBLEMA CON EEPROM DEL PIC 16F876
« Respuesta #6 en: 21 de Octubre de 2010, 13:21:26 »
Hola amigos del foro:

He estado tratando de trabajar para resolver este problema y aun no encuentro solucion saben si hay alguna restriccion de almacenar datos flotantes en la eeprom del PIC. lo que pasa es que en mi programacion el dato que estoy almacenando es flotante y a la hora de realizar la resta me salen numeros raros por lo cual dedusco que no se pueden almacenar numeros flotantes. Si alguien me pudiera resolver esta duda y ayudarme. Gracias


 

anything