Problema con un código para 16F84A

Este código lo compilo y sin ningún problema pero a la hora de simularlo en proteus sólo funciona un botón y los demás no hacen nada, no sé que falla.
Aquí les dejo el código a ver si pueden ayudarme
Código:
#use standard_io(b)

void main()
{

   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_CLOCK_DIV_2);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);

   // TODO: USER CODE!!
 int i;
set_tris_a(011111111);
   while(true)

   if(input(pin_a1)==1){
   for(i=0;i<10;i++)
   {
output_high(pin_b0);
delay_ms(100);
output_high(pin_b1);
delay_ms(100);
output_high(pin_b2);
delay_ms(100);
output_high(pin_b3);
delay_ms(100);
output_low(pin_b3);
delay_ms(100);
output_low(pin_b2);
delay_ms(100);
output_low(pin_b1);
delay_ms(100);
output_low(pin_b0);
delay_ms(100);
output_high(pin_b0);
delay_ms(100);
output_high(pin_b1);
delay_ms(100);
output_high(pin_b2);
delay_ms(100);
output_low(pin_b2);
delay_ms(100);
output_low(pin_b1);
delay_ms(100);
output_low(pin_b0);
delay_ms(100);
output_high(pin_b0);
delay_ms(100);
output_low(pin_b0);
delay_ms(100);
output_high(pin_b0);
delay_ms(100);
output_high(pin_b1);
delay_ms(100);
output_high(pin_b2);
delay_ms(100);
output_high(pin_b3);
delay_ms(100);
output_low(pin_b3);
delay_ms(100);
output_low(pin_b2);
delay_ms(100);
output_low(pin_b1);
delay_ms(100);
output_low(pin_b0);
delay_ms(100);
   }
   }
   if(input(pin_a2)==0){
output_low(pin_b4);
}
if(input(pin_a2)==1){
output_high(pin_b4);
}
if(input(pin_a3)==0){
output_low(pin_b5);
}
if(input(pin_a3)==1){
output_high(pin_b5);
}
if((input(pin_a1)==1)&&(input(pin_a2)==1)){
   output_high(pin_b0);
   output_high(pin_b4);
   delay_ms(15000);
   if((input(pin_a1)==0)&&(input(pin_a2)==0)){
   output_low(pin_b0);
   output_low(pin_b1);
   delay_ms(500);
   }
   }
   if((input(pin_a3)==1)&&(input(pin_a4)==1)){
   output_high(pin_b0);
   output_high(pin_b1);
   output_high(pin_b5);
   delay_ms(20000);
   if((input(pin_a3)==0)&&(input(pin_a4)==0)){
   output_low(pin_b0);
   output_low(pin_b1);
   output_low(pin_b5);
   }
   }
   if((input(pin_a2)==1)&&(input(pin_a4)==1)){
   output_high(pin_b4);
   delay_ms(5000);
   output_low(pin_b4);
   delay_ms(3000);
   output_high(pin_b5);
   delay_ms(4000);
   if((input(pin_a3)==0)&&(input(pin_a4)==0)){
   output_low(pin_b4);
   output_low(pin_b5);
   }
   }
}
 
Última edición por un moderador:
El problema está en la línea

set_tris_a(011111111);

Tal como tienes escrito el argumento, es un número en base octal (empieza por '0').

Ese número, en binario sería así (sólo el byte bajo):

01001001

Y por eso solo activas un par de botones (el A0, el A3 y el A6), de lo que sólo tienes en cuenta el A3 en tu programa (el único que te funcionaba).

La solución es escribir correctamente el número en notación binaria:

set_tris_a(0b11111111);

Veo, además, que le faltan llaves al while()...

El programa quedaría así:
PHP:
#use standard_io(b)

void main() {
    setup_adc_ports(NO_ANALOGS);
    setup_adc(ADC_CLOCK_DIV_2);
    setup_psp(PSP_DISABLED);
    setup_spi(SPI_SS_DISABLED);
    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
    setup_timer_1(T1_DISABLED);
    setup_timer_2(T2_DISABLED,0,1);
    setup_comparator(NC_NC_NC_NC);
    setup_vref(FALSE);

    int i;
    set_tris_a(0b11111111);

    while(true) {
        if(input(pin_a1) == 1) {                        # A1    1
            for(i = 0; i < 10; i++) {
                output_high(pin_b0);
                delay_ms(100);
                output_high(pin_b1);
                delay_ms(100);
                output_high(pin_b2);
                delay_ms(100);
                output_high(pin_b3);
                delay_ms(100);
                output_low(pin_b3);
                delay_ms(100);
                output_low(pin_b2);
                delay_ms(100);
                output_low(pin_b1);
                delay_ms(100);
                output_low(pin_b0);
                delay_ms(100);

                output_high(pin_b0);
                delay_ms(100);
                output_high(pin_b1);
                delay_ms(100);
                output_high(pin_b2);
                delay_ms(100);
                output_low(pin_b2);
                delay_ms(100);
                output_low(pin_b1);
                delay_ms(100);
                output_low(pin_b0);
                delay_ms(100);

                output_high(pin_b0);
                delay_ms(100);
                output_low(pin_b0);
                delay_ms(100);

                output_high(pin_b0);
                delay_ms(100);
                output_high(pin_b1);
                delay_ms(100);
                output_high(pin_b2);
                delay_ms(100);
                output_high(pin_b3);
                delay_ms(100);
                output_low(pin_b3);
                delay_ms(100);
                output_low(pin_b2);
                delay_ms(100);
                output_low(pin_b1);
                delay_ms(100);
                output_low(pin_b0);
                delay_ms(100);
            }
        }

        if(input(pin_a2) == 0) {                        # A2    0
            output_low(pin_b4);
        }
        if(input(pin_a2) == 1) {                        # A2    1
            output_high(pin_b4);
        }
        if(input(pin_a3) == 0) {                        # A3    0
            output_low(pin_b5);
        }
        if(input(pin_a3) == 1) {                        # A3    1
            output_high(pin_b5);
        }

        if((input(pin_a1)==1) && (input(pin_a2)==1)) {          # A1 y A2       1
            output_high(pin_b0);
            output_high(pin_b4);
            delay_ms(15000);

            if((input(pin_a1)==0) && (input(pin_a2)==0)) {      # A1 y A2       0
                output_low(pin_b0);
                output_low(pin_b1);
                delay_ms(500);
            }
        }

        if((input(pin_a3)==1) && (input(pin_a4)==1)) {          # A3 y A4       1
            output_high(pin_b0);
            output_high(pin_b1);
            output_high(pin_b5);
            delay_ms(20000);

            if((input(pin_a3)==0) && (input(pin_a4)==0)) {      # A3 y A4       0
                output_low(pin_b0);
                output_low(pin_b1);
                output_low(pin_b5);
            }
        }

        if((input(pin_a2)==1) && (input(pin_a4)==1)) {          # A2 y A4       1
            output_high(pin_b4);
            delay_ms(5000);
            output_low(pin_b4);
            delay_ms(3000);
            output_high(pin_b5);
            delay_ms(4000);

            if((input(pin_a3)==0) && (input(pin_a4)==0)) {      # A3 y A4       0
                output_low(pin_b4);
                output_low(pin_b5);
            }
        }
    }
}
 
Última edición por un moderador:
tanto if y tanto delay es una atrocidad!!!

lo que debes hacer es hacer un SWITCH, leer el puerto A y con switch y case leer los botones
bueno eso podria ser

funciona bien el IF pero en un pic tan obsoleto y de baja memoria pues es mas eficiente el Switch

delay pues 1 desperdicias memoria y trabas el micro

sugiero que cambies los if por switch y otra cosa para que no te confundas poniendo:

output_low(pin_b0);
output_high(pin_b1);

puedes poner

output_b(0b00001010);

donde cero B indica que es binario


ejemplo:

decimal 45 a binario

0b00101101
 
Una vez compilado el código, tanto si se usa if() como switch(), el resultado es el mismo (depende del compilador, pero en la mayor parte de los casos es así, ya que switch/case no es más que un if() en cascada, con el añadido de que se puede desviar el control a sentencias posteriores a la que inició la condición cierta).

¿En qué se desperdicia memoria con un delay? ¿Trabar el micro? Lo que tiene que hacer el micro en ese momento es... nada.

Sería interesante ver este mismo ejemplo, pero escrito con switch/case y con otra alternativa a los delay. Lo que veo es un ejercicio de juegos de luces, según los pulsadores activos.
 
bueno yo lo digo pues hace tiempo estaba diseñando una maquina bueno un TAXIMETRO
no procedio pues los tramites son largos y hay que aflojar billete para que sea aprobado y sobretodo los pulsos no son los mismpos en diferentes modelos de coche ;) por si alguien quiere diseñar uno

me di cuenta por ing reversa de varios modelos de taximetros usaban el pic16f886 y el pic16f883
pics muy economicos y de memoria limitada

los hacke y despues empese a diseñar uno propio

me di cuenta que los IF deberian llevar su else o su ifelse por que despues de varios if havia un problema con los punteros de la memoria

ejemplo

unsigned char secuencia[10]={12...etc};
funcionaba

pero!

unsigned char *secuencia;

dejaba de funcionar

eso es en caso de trabajar con la eeprom

y ocupaba un 3% mas de codigo los if que el switch sobre todo que en momoento de usar los botones como que tardaba mas en pensar que si lo hacia con switch.

ahora el delay

el delay ¿que es lo que hace?

digamos tenemos 3 tareas

tareas:
1.- leer pulsos
2.- leer en cualquier momento un boton
3.- escribir en un display multiplexado la palabra hola

con un delay en la instruccion de leer un boton el de digamos 1 segundo para evitar un rebote
deja de leer pulsos y el display se ve notoriamente apagado cuando el delay termina todo vuelve a la normalidad

¿que hace el delay?
trabar la maquina en un numero de ciclos

ejemplo

bla
bla
bla...

goto delay

delay:
mov bla bla bla
call etc.
etc.
etc.
"pregunta si ya acabo las repeticiones"
"si no brinca a la etiqueta delay otra vez"
goto delay:


"si ya acabo continua con lo demas"

bla bla push
mov etc.



bueno yo decia es bueno atacar primero los problemas antes de que se hagan malos habitos
 
Hola isair, bienvenido al foro. A primera vista da la impresión de que quieres grabar un código escrito para el compilador CCS C, y que fue escrito para un micro diferente al PIC16F84A. Lo mejor, en cuanto al uso de instrucciones se trata, es consultar siempre el manual del compilador. Por poner algún ejemplo, la instrucción:
Código:
#use standard_io(b)
que por cierto está activa por defecto en CCS, deja sin sentido el uso de la instrucción
Código:
set_tris_a(011111111);

Después aparece al inicio del main():

Código:
    setup_adc_ports(NO_ANALOGS);
    setup_adc(ADC_CLOCK_DIV_2);
    setup_psp(PSP_DISABLED);
    setup_spi(SPI_SS_DISABLED);
    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
    setup_timer_1(T1_DISABLED);
    setup_timer_2(T2_DISABLED,0,1);
    setup_comparator(NC_NC_NC_NC);
    setup_vref(FALSE);

Si te fijas en la hoja de datos, te darás cuenta que este micro no tiene ni Timer1 ni Timer2, ni módulo convertidor de A/D, ni puerto paralelo, etc.

Lo del uso de los delays, si puede presentar algún problema, sobretodo cuando son muy extensos como por ejemplo
Código:
delay_ms(20000);
Cuando TRILO-BYTE dice que traba el micro, creo que se refiere a que si por ejemplo está el micro en un momento dado ejecutando un delay de 20 segundos como el del ejemplo, y en el momento en que han transcurrido digamos solo 3 segundos, presionas un pulsador para ejecutar otra orden, el micro no va a responder a esa pulsación hasta que no se termine el tiempo del delay.

Para tiempos tan extensos, es mejor usar la interrupción de un temporizador para manejar los tiempos de espera y no bloquear el micro.

Finalmente, debes poner atención a lo que te han mencionado del uso correcto de llaves con las instrucciones. Sería bueno también ver el encabezado del programa donde están los bits de configuración (fuses).

Saludos!
 
Atrás
Arriba