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
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.
#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);
}