Autor Tema: comportamiento extraño usando eeprom  (Leído 1283 veces)

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

Desconectado martin12as

  • PIC10
  • *
  • Mensajes: 36
comportamiento extraño usando eeprom
« en: 08 de Noviembre de 2014, 01:43:07 »
buenas noches, tengo un comportamiento super extraño según los datos que escribo en una dirección de la eeprom el programa hace ciertas cosas.

lo que estoy haciendo es un reloj de ajedrez, utilizo 4 direcciones en la eeprom para guardar los tiempos que se configuran para cada jugador

Código: [Seleccionar]
  minutos_a=read_eeprom(0);
   segundos_a=read_eeprom(1);
   minutos_b=read_eeprom(2);
   segundos_b=read_eeprom(3);

para mostrar los tiempos estoy usando 8 display de 7 segmentos multiplexeados, uso 7 pines del pic para manejar cada segmento, y utilizo 8 pines para manejar 8 transistores en el común de cada display, la forma clásica de multiplexear, los 8 pines de los transistores ocupan todo el puerto A, y el problema que tengo es con la dirección de la eeprom 3, que corresponde a los segundos del jugador b, el comportamiento es bastante extraño, pero al menos sigue una lógica.

el problema con la dirección 3 es que cada bit que se pone en 1 me apaga un display, si esta en 00 funcionan todos los display, si esta en ff se apagan todos, si por ejemplo esta en 01010101, se prenden intercalados, si esta 0F, se prenden los 4 últimos, y así sucesivamente con las 255 posibilidades que hay, cada bit que se pone en 1 hace que deje de funcionar un display, la verdad no entiendo que es lo que esta pasando.

recién probé cambiando la dirección 3 por la 4, y pasa lo mismo. no entiendo porque el puerto a, o los display, o no se que cosa, depende de lo que se escriba en la variable  "segundos_b"

dejo el código completo por las dudas, es bastante largo.

Código: [Seleccionar]
#include <16f886.h> // Selecciona el PIC

#fuses intrc_io //oscilador interno
#fuses NOWDT    //no wath dog timer
#fuses MCLR   //master clear reset
#fuses NOLVP    //no low voltage programing
#fuses NOPROTECT //no protect

#use delay(clock=8000000) // Velocidad del Cristal : 8 Mhz

#use fast_io (a)
#use fast_io (b)
#use fast_io (c)

char const RTCCxS=31; // Número de RTCC's para 1 segundo con 8 Mhz / 1:256.

// VARIABLES GLOBALES

   int8 men=0;                //variable para contar las veces que se entra al menu   
   int8 jugador=2;            //0=A, 1=B, 2=juego en pausa
   int1 cambio=1;             //bandera de cambio de segundos
   int8 nRTCC=0x00;           // Contador de interrupciones RTCC completas

   int8 minutos_a=0;          //variables con los tiempos
   int8 segundos_a=0;
   int8 minutos_b=0;
   int8 segundos_b=0;

   int8 minuto_ax10=0;        //variables con los numeros que se muestran en cada display
   int8 minuto_bx10=0;
   int8 minuto_a=0;
   int8 minuto_b=0;
   int8 segundo_ax10=0;
   int8 segundo_bx10=0;
   int8 segundo_a=0;
   int8 segundo_b=0;
   
   void fin(int1);            //funcion cuando alguien pierde
   void numeros(void);        //funcion que cambia los numeros en cada segundo
   void menu(void);           //funcion del menu para cambiar tiempos
   void mostrar(void);        //funcion que muestra el display todo el tiempo
   int8 convertir(int8);      //funcion que convierte las variables del tiempo en numeros para mostrar en los display
   
#int_EXT
void EXT_isr() //hay 4 pulsadores conectados a al pin rb0, con cualquier pulsador salta la int y luego hace alguna funcion
{
   if(!input(pin_c2)) //este pulsador empieza a descontar el tiempo a un jugador
   {
      jugador=0;           //variable que indica el que esta jugando
      output_high(pin_c0); //se prende 1 led y apaga otro para saber cual esta jugando
      output_low(pin_c1);
      nRTCC=0;             //reinicio el acumulador del segundo cada vez que cambia de jugador
   }
   if(!input(pin_c3)) //este pulsador empieza a descontar el tiempo al otro jugador
   {
      jugador=1;           //variable que indica el que esta jugando
      output_high(pin_c1); //se prende 1 led y apaga otro para saber cual esta jugando
      output_low(pin_c0);
      nRTCC=0;             //reinicio el acumulador del segundo cada vez que cambia de jugador
   }
   if(!input(pin_c4)) //este pulsador abre el menu para ajustar tiempos
      menu();         //menu para ajustar tiempos
   if(!input(pin_c5)) //este pulsador pone el juego en pausa
   {
      jugador=2; //variable que indica que el juego esta en pausa
      output_high(pin_c0); //prenden los 2 led
      output_high(pin_c1);
      nRTCC=0;    ////reinicio el acumulador del segundo
   }
   
}

#int_RTCC                 // Interrupción por desbordamiento del TIMER0 RTC
void RTCC_isr()           // esto es para contar cada segundo
{             
   if(++nRTCC==RTCCxS)
   {
      nRTCC=0;
      set_timer0(4);
      cambio=1;         //cada 1 segundo cambio esta bandera
   }
}

void main(void)
{
   setup_counters(RTCC_INTERNAL,RTCC_DIV_256); // TIMER0: Clock Interno y Preescaler
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   
   minutos_a=read_eeprom(0);   //lee los valores iniciales de cada variable en la eeprom
   segundos_a=read_eeprom(1);
   minutos_b=read_eeprom(2);
   segundos_b=read_eeprom(3);
   
   set_tris_a(0b00000000);
   set_tris_b(0b00000001); //entrada el pin b0 para la int_ext
   set_tris_c(0b00111100); //entradas los 4 pines de los pulsadores
   
   output_a(0);
   output_b(0);
   output_c(0);
   
   ext_int_edge(H_TO_L);
   
   enable_interrupts(INT_EXT);
   enable_interrupts(INT_RTCC);// Habilito Interrupción RTCC
   enable_interrupts(global);  // Habilito Interrupciones
   
  do{ // Bucle infinito

    if(cambio){    // si cambia el segundo actualizo las
      numeros();   // variables con lo que hay que mostrar
      cambio=0;
    }
    mostrar();          // Muestra constantemente

  }While(TRUE);

}

void numeros(void) //esta funcion va midiendo el tiempo de cada uno
{
   if(jugador==1)  //si esta jugando el jugador 1
   {
      output_toggle(pin_c0); //led segundero del jugador 1
      segundos_a--;
      if(segundos_a==0) //cuando llegan los segundos a 0 resta un minuto y pasa a 59 segundos
      {
         segundos_a=59;
         minutos_a--;
         if(minutos_a==-1) //cuando los minutos y segundos llegan a 0, pierde
            fin(1);
      }
   }
   if(jugador==0) //si esta jugando el jugador 2
   {
      output_toggle(pin_c1); //led segundero del jugador 2
      segundos_b--;
      if(segundos_b==0) //cuando llegan los segundos a 0 resta un minuto y pasa a 59 segundos
      {
         segundos_b=59;
         minutos_b--;
         if(minutos_b==-1) //cuando los minutos y segundos llegan a 0, pierde
            fin(0);
      }
   }
   if(jugador==2)   //si esta en pausa no descuenta ningun tiempo a nadie
   {
      output_toggle(pin_c0); //se prenden los led segunderos de los 2 jugadores
      output_toggle(pin_c1);
   }
                                                                //convierte las variables del tiempo en numeros para mostrar en los display
   minuto_ax10=convertir((minutos_a-minutos_a%10)/10);          // display 1
   minuto_bx10=convertir((minutos_b-minutos_b%10)/10);          // display 5
   minuto_a=convertir(minutos_a%10);                            // display 2
   minuto_b=convertir(minutos_b%10);                            // display 6
   segundo_ax10=convertir((segundos_a-segundos_a%10)/10);       // display 3
   segundo_bx10=convertir((segundos_b-segundos_b%10)/10);       // display 7
   segundo_a=convertir(segundos_a%10);                          // display 4
   segundo_b=convertir(segundos_b%10);                          // display 8

}



void fin(int1 a)//por ahora no hace nada
{
}

int8 convertir(int8 numero) //recibe un int y lo convierte en los bits de los segmentos
{                           //para poner en el puerto b
   int8 resultado;
   
   switch(numero)
   {
      case 0: resultado=0b01111110;
      break;
      case 1: resultado=0b00001100;
      break;
      case 2: resultado=0b10110110;
      break;
      case 3: resultado=0b10011110;
      break;
      case 4: resultado=0b11001100;
      break;
      case 5: resultado=0b11011010;
      break;
      case 6: resultado=0b11111010;
      break;
      case 7: resultado=0b00001110;
      break;
      case 8: resultado=0b11111110;
      break;
      case 9: resultado=0b11001110;
      break;
   }   
   return resultado;
}

void menu(void)
{
   disable_interrupts(GLOBAL);
   
   output_a(0);
   output_b(0);
   output_c(0);    //se ponen todos en 0 para apagar los display
   
   minuto_ax10=0;  //se ponen en 0 todos los numeros que se muestran en los display para que se apaguen
   minuto_bx10=0;
   minuto_a=0;
   minuto_b=0;
   segundo_ax10=0;
   segundo_bx10=0;
   segundo_a=0;
   segundo_b=0;
   
   delay_ms(500); //delay para soltar el boton menu y no pasar de largo los while
   
   switch(men)    //segun la cantidad de veces que se apreto la tecla menu hace distintas cosas
   {
   case 0: output_high(PIN_a3);                    //se prende el display 4 y se configuran los segundos del jugador a
           segundo_a=convertir(segundos_a%10);     //se convierte el numero para mostrar en el display
           output_b(segundo_a);                    //se muestra el numero acutal de los segundos
           while(input(pin_c4))                    //se pueden ajustar los segundos hasta que se vuelve a tocar la tecla menu
           {   
               if(!input(pin_c2))                  //si aprieto esta tecla, aumenta los segundos
               {
                  if(segundos_a%10==9)             //si llega a 9, se vuelve a 0
                     segundos_a=segundos_a-9;
                  else                             //sino se aumenta de 1 en 1
                     segundos_a=segundos_a+1;
                     
                  write_eeprom(1,segundos_a);      //escribe en la eeprom el valor nuevo ¿se puede hacer fuera del while?
                  segundo_a=convertir(segundos_a%10);//se cambia el numero del display
                  output_b(segundo_a);                //se muestra el numero en el display
                  delay_ms(200);                   //delay para auemntar los segundos
               }
               if(!input(pin_c3))                  //si aprieto esta tecla, disminuye los segundos
               {
                  if(segundos_a%10==0)             //si llega a 9 se vuelve a 0
                     segundos_a=segundos_a+9;
                  else
                     segundos_a=segundos_a-1;      //sino disminuye de 1 en 1
                     
                  write_eeprom(1,segundos_a);
                  segundo_a=convertir(segundos_a%10);
                  output_b(segundo_a);
                  delay_ms(200);
               }         
           }
           output_low(PIN_a3); //apaga el display y pasa al que sigue
   break;
   
   case 1: output_high(PIN_a2); //prende el display 3
           segundo_ax10=convertir((segundos_a-segundos_a%10)/10);
           output_b(segundo_ax10);
           while(input(pin_c4))
           {               
               if(!input(pin_c2))  //aumenta segundos
               {
                  if(segundos_a>=50)   //si llega a 5x, se vuelve a 0x
                     segundos_a=segundos_a-50;
                  else               
                     segundos_a=segundos_a+10; //sino aumenta de 10 en 10
                  write_eeprom(1,segundos_a);
                  segundo_ax10=convertir((segundos_a-segundos_a%10)/10);
                  output_b(segundo_ax10);
                  delay_ms(200);
               }
               if(!input(pin_c3)) //disminuye segundos
               {
                  if(segundos_a<10)
                     segundos_a=segundos_a+50;
                  else
                     segundos_a=segundos_a-10;
                  write_eeprom(1,segundos_a);
                  segundo_ax10=convertir((segundos_a-segundos_a%10)/10);
                  output_b(segundo_ax10);
                  delay_ms(200);
               }               
           }
           output_low(PIN_a2);
   break;
   case 2: output_high(PIN_a1);
           minuto_a=convertir(minutos_a%10);
           output_b(minuto_a);
           while(input(pin_c4))
           {   
               if(!input(pin_c2))
               {
                  if(minutos_a%10==9)
                     minutos_a=minutos_a-9;
                  else
                     minutos_a=minutos_a+1;
                  write_eeprom(0,minutos_a);
                  minuto_a=convertir(minutos_a%10);
                  output_b(minuto_a);
                  delay_ms(200);
               }
               if(!input(pin_c3))
               {
                  if(minutos_a%10==0)
                     minutos_a=minutos_a+9;
                  else
                     minutos_a=minutos_a-1;
                  write_eeprom(0,minutos_a);
                  minuto_a=convertir(minutos_a%10);
                  output_b(minuto_a);
                  delay_ms(200);
               }         
           }
           output_low(PIN_a1);
   break;
   case 3: output_high(PIN_a0);
           minuto_ax10=convertir((minutos_a-minutos_a%10)/10);
           output_b(minuto_ax10);
           while(input(pin_c4))
           {   
               if(!input(pin_c2))
               {
                  if(minutos_a>=50)
                     minutos_a=minutos_a-50;
                  else
                     minutos_a=minutos_a+10;
                  write_eeprom(0,minutos_a);
                  minuto_ax10=convertir((minutos_a-minutos_a%10)/10);
                  output_b(minuto_ax10);
                  delay_ms(200);
               }
               if(!input(pin_c3))
               {
                  if(minutos_a<10)
                     minutos_a=minutos_a+50;
                  else
                     minutos_a=minutos_a-10;
                  write_eeprom(0,minutos_a);
                  minuto_ax10=convertir((minutos_a-minutos_a%10)/10);
                  output_b(minuto_ax10);
                  delay_ms(200);
               }         
           }
           output_low(PIN_a0);
   break;
   
   
   ////////////////lado B/////////////////////
   
   
   case 4: output_high(PIN_a7);
           segundo_b=convertir(segundos_b%10);
           output_b(segundo_b);
           while(input(pin_c4))
           {   
               if(!input(pin_c2))
               {
                  if(segundos_b%10==9)
                     segundos_b=segundos_b-9;
                  else
                     segundos_b=segundos_b+1;
                     
                  write_eeprom(3,segundos_b);
                  segundo_b=convertir(segundos_b%10);
                  output_b(segundo_b);
                  delay_ms(200);
               }
               if(!input(pin_c3))
               {
                  if(segundos_b%10==0)
                     segundos_b=segundos_b+9;
                  else
                     segundos_b=segundos_b-1;
                     
                  write_eeprom(3,segundos_b);
                  segundo_b=convertir(segundos_b%10);
                  output_b(segundo_b);
                  delay_ms(200);
               }         
           }
           output_low(PIN_a7);
   break;
   
   case 5: output_high(PIN_a6);
           segundo_bx10=convertir((segundos_b-segundos_b%10)/10);
           output_b(segundo_bx10);
           while(input(pin_c4))
           {               
               if(!input(pin_c2))
               {
                  if(segundos_b>=50)
                     segundos_b=segundos_b-50;
                  else               
                     segundos_b=segundos_b+10;
                  write_eeprom(3,segundos_b);
                  segundo_bx10=convertir((segundos_b-segundos_b%10)/10);
                  output_b(segundo_bx10);
                  delay_ms(200);
               }
               if(!input(pin_c3))
               {
                  if(segundos_b<10)
                     segundos_b=segundos_b+50;
                  else
                     segundos_b=segundos_b-10;
                  write_eeprom(3,segundos_b);
                  segundo_bx10=convertir((segundos_b-segundos_b%10)/10);
                  output_b(segundo_bx10);
                  delay_ms(200);
               }               
           }
           output_low(PIN_a6);
   break;
   case 6: output_high(PIN_a5);
           minuto_b=convertir(minutos_b%10);
           output_b(minuto_b);
           while(input(pin_c4))
           {   
               if(!input(pin_c2))
               {
                  if(minutos_b%10==9)
                     minutos_b=minutos_b-9;
                  else
                     minutos_b=minutos_b+1;
                  write_eeprom(2,minutos_b);
                  minuto_b=convertir(minutos_b%10);
                  output_b(minuto_b);
                  delay_ms(200);
               }
               if(!input(pin_c3))
               {
                  if(minutos_b%10==0)
                     minutos_b=minutos_b+9;
                  else
                     minutos_b=minutos_b-1;
                  write_eeprom(2,minutos_b);
                  minuto_b=convertir(minutos_b%10);
                  output_b(minuto_b);
                  delay_ms(200);
               }         
           }
           output_low(PIN_a5);
   break;
   case 7: output_high(PIN_a4);
           minuto_bx10=convertir((minutos_b-minutos_b%10)/10);
           output_b(minuto_bx10);
           while(input(pin_c4))
           {   
               if(!input(pin_c2))
               {
                  if(minutos_b>=50)
                     minutos_b=minutos_b-50;
                  else
                     minutos_b=minutos_b+10;
                  write_eeprom(2,minutos_b);
                  minuto_bx10=convertir((minutos_b-minutos_b%10)/10);
                  output_b(minuto_bx10);
                  delay_ms(200);
               }
               if(!input(pin_c3))
               {
                  if(minutos_b<10)
                     minutos_b=minutos_b+50;
                  else
                     minutos_b=minutos_b-10;
                  write_eeprom(2,minutos_b);
                  minuto_bx10=convertir((minutos_b-minutos_b%10)/10);
                  output_b(minuto_bx10);
                  delay_ms(200);
               }         
           }
           output_low(PIN_a4);
   break;
   case 8: //nada por ahora
   break;
   }
   
   men++; //cuenta las veces que se entra al menu
   enable_interrupts(GLOBAL);
   
}

void mostrar(void)
{
   int delay=30;
   output_b(minuto_ax10);           // Muestro display 1
   output_high(PIN_a0);
   delay_us(delay);
   output_low(pin_a0);

   output_b(minuto_a);           // Muestro display 2
   output_high(PIN_a1);
   delay_us(delay);
   output_low(pin_a1);

   output_b(segundo_ax10);           // Muestro display 3
   output_high(PIN_a2);
   delay_us(delay);
   output_low(pin_a2);

   output_b(segundo_a);           // Muestro display 4
   output_high(PIN_a3);
   delay_us(delay);
   output_low(pin_a3);

   output_b(minuto_bx10);           // Muestro display 5
   output_high(PIN_a4);
   delay_us(delay);
   output_low(pin_a4);

   output_b(minuto_b);           // Mue5stro display 6
   output_high(PIN_a5);
   delay_us(delay);
   output_low(pin_a5);

   output_b(segundo_bx10);           // Muestro display 7
   output_high(PIN_a6);
   delay_us(delay);
   output_low(pin_a6);

   output_b(segundo_b);           // Muestro display 8
   output_high(PIN_a7);
   delay_us(delay);
   output_low(pin_a7);
}
« Última modificación: 08 de Noviembre de 2014, 02:27:09 por martin12as »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: comportamiento extraño usando eeprom
« Respuesta #1 en: 08 de Noviembre de 2014, 06:54:42 »
Que version de CSS usas...

Encontre esto muy parecido a tu problema:
http://www.todopic.com.ar/foros/index.php?topic=39912.0

Probaste otro port ? al menos para sacarte la duda ?
Solamente lees al comienzo y grabas muchas veces, me imagine un "tocar y grabar en la memoria" pero veo muchos write xD aunque eso no viene al problema.

Otra de las cosas, que no se de CSS, si te configura solo el registro ANSEL, para hacerlos digitales, creo que usan setup_adc_ports(NO_ANALOG); u algo asi
« Última modificación: 08 de Noviembre de 2014, 07:07:19 por KILLERJC »

Desconectado martin12as

  • PIC10
  • *
  • Mensajes: 36
Re: comportamiento extraño usando eeprom
« Respuesta #2 en: 08 de Noviembre de 2014, 13:22:20 »
Que version de CSS usas...

Encontre esto muy parecido a tu problema:
http://www.todopic.com.ar/foros/index.php?topic=39912.0

Probaste otro port ? al menos para sacarte la duda ?
Solamente lees al comienzo y grabas muchas veces, me imagine un "tocar y grabar en la memoria" pero veo muchos write xD aunque eso no viene al problema.

Otra de las cosas, que no se de CSS, si te configura solo el registro ANSEL, para hacerlos digitales, creo que usan setup_adc_ports(NO_ANALOG); u algo asi

la versión de ccs es la 4.104, pero el problema ya lo solucione, la solución fue declar #byte TRISA = getenv ("SFR:TRISA") y luego reemplazar set_tris_a(0) por TRISA=0, aparentemente me apareció algún bug en el compilador que ponía en la función set_tris_a, el valor de la eeprom 3

lo de la eeprom capaz que la estoy escribiendo muchas veces al pedo, voy a hacer algunos cambios para que solo se escriban los valores al salir del menu, supuestamente cuando el proyecto este listo no abria porque entrar al menu a cada rato


 

anything