Autor Tema: Aprendiendo de errores CCS & Pic  (Leído 2274 veces)

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

Desconectado estalli2

  • PIC10
  • *
  • Mensajes: 12
Aprendiendo de errores CCS & Pic
« en: 09 de Agosto de 2010, 22:33:06 »
Queridos colegas, aca vengo con otra duda que tengo con la programacion en c para pic.
Estoy armando un aparato que simplemente es un contador regresivo de 60 segundos el cual debe funcionar asi:
1 solo boton que al presionarlo cuente a partir de 60 hacia 00, una vez contando si presiono el mismo boton tiene que detener la cuenta y si lo vuelvo a presionar vuelve a contar desde 60 hacia 00.
Por ahora solo vengo con lo mas simple(creo) que es la parte del contador, del cual pongo el codigo:


Código: [Seleccionar]
#include <16F628.h>
#USE DELAY( CLOCK=4000000)
#FUSES XT,NOWDT,NOPROTECT,NOPUT
#USE fast_IO (B)
#USE fast_IO (A)

byte CONST DISPLAY[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //codigo para bcd
signed char ud=0,dec=6;
char flag=0;
short soni=1;
short bott=0;
short ini=0;
void disp(void); //saca a display
void alarm(void); //alarma por puerto A3 por 5 segundos
void cuenta_reg(void); //programa de cuenta



///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////programa principal


void main(void){

set_tris_b(0x00);
set_tris_a(0x10);
disable_interrupts(GLOBAL);   //todas las interrupciones desactivadas
ud=read_eeprom(0);  //lee los valores de ultima cuenta
dec=read_eeprom(1);
disp();

WHILE(1){
if (input(pin_A4)==1){cuenta_reg();
}

}

}










///////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////rutina de salida al display/////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
void disp(void){

OUTPUT_A(0x02);           //con 0 encendido en este caso unidades
OUTPUT_B(DISPLAY[ud]);   //Digito unidades
delay_ms(100);
OUTPUT_A(0x01); //decenas
OUTPUT_B(DISPLAY[dec]);
delay_ms(100);

}


///////////////////////////////////////////////////////////////////////////////////////////////////
//////////rutina de la alarma cuando sale pone el flag en cero
///////////////////////////////////////////////////////////////////////////////////////////////////
void alarm(void){

if (soni=1){
OUTPUT_A(0x04);
delay_ms(1000);
}
soni=0;
}


  
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////rutina cuenta regresiva de 60 a 00//////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////

void cuenta_reg(void)

{
signed char unidad,decenas;

      for (decenas=5;decenas>-1;decenas--){       //Cuenta digito decenas
      for (unidad=9;unidad>-1;unidad--){
         OUTPUT_A(0x02);           //cat_D=apagado,cat_U=encendido
         OUTPUT_B(DISPLAY[unidad]);   //Digito unidades
         delay_ms(50);            //Para evitar parpadeos
         output_a(0x01);           //Si decenas>0, cat_D=encendido
         OUTPUT_B(DISPLAY[decenas]);      //Digito decenas
         delay_ms(50);               //Para evitar parpadeos

}
}
    }


bueno, el contador funciona ahora no tengo idea como seguir con lo demas ya que todavia no estoy muy familiarizado con los bucles for, while, if, etc.
me confundo un poco con las posibilidades de llamar subrutinas y diagramar las funciones que tendria que secuenciar el programa... :shock:
por otro lado no pense todavia como implementar las cuentas del tmr0 para manejar todo el sistema cuando lo tenga funcionando...
agradecere todo consejo-critica-etc etc...la idea es aprender de mis propios errores..
MIL GRACIAS POR ADELANTADO!!!
« Última modificación: 09 de Agosto de 2010, 22:41:50 por un Moderador »

Desconectado MarkKnopfler81

  • PIC12
  • **
  • Mensajes: 64
    • PICs, Electrónica y Robótica
Re: Aprendiendo de errores CCS & Pic
« Respuesta #1 en: 11 de Agosto de 2010, 14:18:33 »
Hola estalli2

Te cuento, el código que pusiste tiene algunos errores como por ejemplo que al hacer la cuenta en un bucle, no hace otra cosa que contar y mostrar los displays, lo que estas haciendo es: decrementas la unidad en 1 y muestras los displays, decrementas otra vez y vuelves a mostrar los displays. Esto hace que la cuenta sea muy rápida.

Para contar segundos lo que tienes que hacer es precisamente eso, decrementar cada segundo y entre cuenta y cuenta, mostrar muchas veces los displays sino no verias nada, te dejo el codigo que hice, cuenta aproximadamente cada 1 segundo por medio del timer0.

Código: [Seleccionar]
#include <16F628.h>
#USE DELAY( CLOCK=4000000)
#FUSES XT,NOWDT,NOPROTECT,NOPUT
#USE fast_IO (B)
#USE fast_IO (A)

byte CONST DISPLAY[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //codigo para bcd

int   Numero[2]; 
int   Cifra;
int1  Pulso;
int1  anPulso;
int1  Flag;
int   Tiempo;

#define Cat_U  PIN_A0
#define Cat_D  PIN_A1
#define Tecla  PIN_A4



#int_rtcc
void isr(){   // cada 1024 ciclos salta esta interrupcion
   if(--Tiempo>200){       // Decrementa Tiempo y se pasa de 0
      Tiempo=60;            // Pone Tiempo a 60
      Disable_interrupts(int_rtcc); // y detiene la cuenta
      Flag=False;          // desactiva el flag
   }
}



void main(void){
   int tmp;
   set_tris_b(0x00);
   set_tris_a(0x10);
   setup_timer_0(rtcc_internal|rtcc_div_4);
   disable_interrupts(int_rtcc);
   enable_interrupts(GLOBAL);   
   Flag=false;
   
   WHILE(true){
      tmp=tiempo/10;
      Numero[1]=tmp;
      Numero[0]=Tiempo-(tmp*10);
     
      if (++Cifra>1)Cifra=0; //En cada iteracion muestra la decena o la unidad
      output_high(Cat_U);
      output_high(Cat_D);
      OUTPUT_B(DISPLAY[Numero[Cifra]]);   
     
      if (Cifra==1)output_low(Cat_D); else output_low(Cat_U);  // Activando los respectivos
                                                               // cátodos
     
      if (Input(Tecla)) Pulso=true; else Pulso=false; // Si se pulso B4 carga pulso con true
                                                      // sino con false
     
      if (Pulso&&!anPulso){               // Si Pulso es true y anPulso es false
                                          // (La primera vez que detecta la pulsacion)
         if (Flag){                       // Si el Flag está activado
            Disable_interrupts(int_rtcc); //  detiene la cuenta
         }else{                           // Si el flag no está activado
            Tiempo=60;                    // Pone el tiempo a 60
            Enable_interrupts(int_rtcc);  // y activa la cuenta
         }
         Flag=!Flag;                      // invierte el estado del flag
      }
      AnPulso=Pulso;                      // Para que detecte la pulsacion 1 sola vez.
       
      delay_ms(10);                       // pausa entre iteracion e iteracion
   }
   
}

Si hay algo que no se entienda me lo dices.

saludos.
« Última modificación: 13 de Agosto de 2010, 07:50:28 por MarkKnopfler81 »

Desconectado estalli2

  • PIC10
  • *
  • Mensajes: 12
Re: Aprendiendo de errores CCS & Pic
« Respuesta #2 en: 27 de Octubre de 2010, 09:20:27 »
Hola estalli2

Te cuento, el código que pusiste tiene algunos errores como por ejemplo que al hacer la cuenta en un bucle, no hace otra cosa que contar y mostrar los displays, lo que estas haciendo es: decrementas la unidad en 1 y muestras los displays, decrementas otra vez y vuelves a mostrar los displays. Esto hace que la cuenta sea muy rápida.

Para contar segundos lo que tienes que hacer es precisamente eso, decrementar cada segundo y entre cuenta y cuenta, mostrar muchas veces los displays sino no verias nada, te dejo el codigo que hice, cuenta aproximadamente cada 1 segundo por medio del timer0.

Código: [Seleccionar]
#include <16F628.h>
#USE DELAY( CLOCK=4000000)
#FUSES XT,NOWDT,NOPROTECT,NOPUT
#USE fast_IO (B)
#USE fast_IO (A)

byte CONST DISPLAY[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //codigo para bcd

int   Numero[2]; 
int   Cifra;
int1  Pulso;
int1  anPulso;
int1  Flag;
int   Tiempo;

#define Cat_U  PIN_A0
#define Cat_D  PIN_A1
#define Tecla  PIN_A4



#int_rtcc
void isr(){   // cada 1024 ciclos salta esta interrupcion
   if(--Tiempo>200){       // Decrementa Tiempo y se pasa de 0
      Tiempo=60;            // Pone Tiempo a 60
      Disable_interrupts(int_rtcc); // y detiene la cuenta
      Flag=False;          // desactiva el flag
   }
}



void main(void){
   int tmp;
   set_tris_b(0x00);
   set_tris_a(0x10);
   setup_timer_0(rtcc_internal|rtcc_div_4);
   disable_interrupts(int_rtcc);
   enable_interrupts(GLOBAL);   
   Flag=false;
   
   WHILE(true){
      tmp=tiempo/10;
      Numero[1]=tmp;
      Numero[0]=Tiempo-(tmp*10);
     
      if (++Cifra>1)Cifra=0; //En cada iteracion muestra la decena o la unidad
      output_high(Cat_U);
      output_high(Cat_D);
      OUTPUT_B(DISPLAY[Numero[Cifra]]);   
     
      if (Cifra==1)output_low(Cat_D); else output_low(Cat_U);  // Activando los respectivos
                                                               // cátodos
     
      if (Input(Tecla)) Pulso=true; else Pulso=false; // Si se pulso B4 carga pulso con true
                                                      // sino con false
     
      if (Pulso&&!anPulso){               // Si Pulso es true y anPulso es false
                                          // (La primera vez que detecta la pulsacion)
         if (Flag){                       // Si el Flag está activado
            Disable_interrupts(int_rtcc); //  detiene la cuenta
         }else{                           // Si el flag no está activado
            Tiempo=60;                    // Pone el tiempo a 60
            Enable_interrupts(int_rtcc);  // y activa la cuenta
         }
         Flag=!Flag;                      // invierte el estado del flag
      }
      AnPulso=Pulso;                      // Para que detecte la pulsacion 1 sola vez.
       
      delay_ms(10);                       // pausa entre iteracion e iteracion
   }
   
}

Si hay algo que no se entienda me lo dices.

saludos.



Ok! Muchas gracias! esta excelente y los comentarios me ayudaron muchisimo.
 :-/ gracias de verdad!


 

anything