Autor Tema: Problema con programita en CCS  (Leído 9272 veces)

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

Desconectado soymoe

  • PIC18
  • ****
  • Mensajes: 456
    • El blog de Moe
Problema con programita en CCS
« en: 15 de Octubre de 2010, 16:56:13 »
Estoy haciendo mis primeras armas en CCS y estoy  tratando de prender y apagar un led conectado a RB0 al pulsar una tecla conectada a RA0, pero solo funciona la primera vez, se apaga pero no vuelve a encender. Este es el codigo.
Código: [Seleccionar]
#include <16F628A.h>
#use standard_io(b) 
#fuses NOWDT,INTRC,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
#use delay(clock=4000000)
#byte PORTA=0x05
void main()
{  set_tris_a(0xFF);
   set_tris_b(0xF0);
   output_bit(PIN_B0,0x01);
   while(true)
{  if(!bit_test(PORTA,0))
{  delay_ms(100);//ESPERO SUELTA
   if(bit_test(PORTA,0))
   output_bit(PIN_B0,!PIN_B0);}}
   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);
   }
Espero me puedan decir porque.

Desconectado bigluis

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 511
    • Tutoriales de Qt C++
Re: Problema con programita en CCS
« Respuesta #1 en: 15 de Octubre de 2010, 17:48:33 »
Tu problema radica en el algoritmo, ya que preguntabas si RA0 es igual a cero y luego preguntas si es igual a 1, es decir el segundo if estaba adentro del primero por lo cual se debia cumplir que ambas condiciones ocurrieran, por eso solo lo hacia la primera vez.

prueba con esto

Código: [Seleccionar]
#include <16F628A.h>
#use standard_io(b) 
#fuses NOWDT,INTRC,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
#use delay(clock=4000000)
#byte PORTA=0x05
void main(){ 
    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);
    set_tris_a(0xFF);
    set_tris_b(0xF0);
    output_bit(PIN_B0,0x01);
    while(true){
        if(bit_test(PORTA,0)){        //Si presionas el boton conectado a RA0
            delay_ms(10);            //ESPERO SUELTA
            output_bit(PIN_B0,1);    //RB0 sera igual a 1
        }
        else{                        //De lo contrario
            delay_ms(10);            //ESPERO SUELTA
            output_bit(PIN_B0,0);    //RB0 sera igual a 0
        }
    }
}

Por aqui podras encontrar una libraria para utilizar los puertos de otra forma en CCS.
Tutoriales de Qt C++

No es necesario que hagamos Grandes cosas, sino que lo que hagamos sea importante.

SI la NECESIDAD es la MADRE del CONOCIMIENTO, SEGURAMENTE la PEREZA su TÍA.

Cuando el ARTE requiere de PRECISION le llamamos CIENCIA

Desconectado soymoe

  • PIC18
  • ****
  • Mensajes: 456
    • El blog de Moe
Re: Problema con programita en CCS
« Respuesta #2 en: 16 de Octubre de 2010, 12:11:29 »
La idea es que al apretar el pulsador conectado a RA0 ,el led conectado a RB0 se apague si esta encendido o se encienda si esta apagado. osea cambie de estado y permanezca asi hasta que se vuelva a pulsar la tecla de RA0

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Problema con programita en CCS
« Respuesta #3 en: 16 de Octubre de 2010, 12:20:22 »
Hola Moe.   :)

Más allá de lo que necesites, fijate como te ordenó el programa BigLuis.
Por defecto los pines A0, A1, A2 y A3 corresponden a entradas analógicas.

En tu programa las configuras como digitales constantemente y dentro del "IF" pero hay que hacerlo como te mostró BigLuis. Primero configuras los periféricos (en tu caso los comparadores tenés que deshabilitarlos para poder usar las entradas digitales) y luego hacer las cosas que necesite tu programa.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado bmb

  • PIC18
  • ****
  • Mensajes: 423
Re: Problema con programita en CCS
« Respuesta #4 en: 16 de Octubre de 2010, 13:35:19 »
Hola soymoe, si entendí bien que lo que quieres es que si el LED está encendido se apague y si está apagado se encienda, entonces puedes intentar algo asi:
Código: [Seleccionar]
#include <16F628A.h>

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC                    //Internal RC Osc
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection

#use delay(clock=4000000)

#byte PORTB=0x06

void main()
{
   int1 anterior =true;
  
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_ccp1(CCP_OFF);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);

   set_tris_b(0xF0);

   // Asumiendo que el cátodo esté conectado al negativo y el ánodo al
   // pin B0 a través de una resistencia...
  
   output_low(PIN_B0); // LED apagado

   while(true)
   {
      // Asumiendo que la tecla en RA0 tiene una resistencia pullup....
      if( !input(PIN_A0))
      {
         if(anterior)
         {
            if (!bit_test(PORTB,0))    // Si el LED está apagado
               output_high(PIN_B0);    // Enciende el LED
            else
               output_low(PIN_B0);     // Si no, lo apaga
          
            anterior = false;
         }
      }
      else
         anterior = true;
   }
}

Son muy importantes las anotaciones sobre el orden en los programas que te hacen los colegas.  Asi tienes menos posibilidades de error.

Saludos!

Edito: olvidaba el set_tris del puerto b.
« Última modificación: 16 de Octubre de 2010, 14:31:12 por bmb »

Desconectado bigluis

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 511
    • Tutoriales de Qt C++
Re: Problema con programita en CCS
« Respuesta #5 en: 16 de Octubre de 2010, 14:44:26 »
Otra forma de resolver ese problema es esperando hasta que la tecla sea presionada, para ello lo puedes hacer de dos formas, mediante una tecnia a la que llamamos polling, o mediante interrupciones.

La tecnica polling es similar a la que muestra bmb y sería de la siguiente manera.
Código: [Seleccionar]
void main()
{
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_ccp1(CCP_OFF);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);

   set_tris_b(0xF0);

   // Asumiendo que el cátodo esté conectado al negativo y el ánodo al
   // pin B0 a través de una resistencia...
   
   output_low(PIN_B0); // LED apagado

   while(true)
   {
      // Asumiendo que la tecla en RA0 tiene una resistencia pullup....

      while( !input(PIN_A0));    //Esperar hasta que se presione RA0.

      if (!bit_test(PORTB,0))    // Si el LED está apagado
         output_high(PIN_B0);    // Enciende el LED
      else
         output_low(PIN_B0);     // Si no, lo apaga
   }
}
Tutoriales de Qt C++

No es necesario que hagamos Grandes cosas, sino que lo que hagamos sea importante.

SI la NECESIDAD es la MADRE del CONOCIMIENTO, SEGURAMENTE la PEREZA su TÍA.

Cuando el ARTE requiere de PRECISION le llamamos CIENCIA

Desconectado bmb

  • PIC18
  • ****
  • Mensajes: 423
Re: Problema con programita en CCS
« Respuesta #6 en: 16 de Octubre de 2010, 15:22:53 »
Otra forma de resolver ese problema es esperando hasta que la tecla sea presionada, para ello lo puedes hacer de dos formas, mediante una tecnia a la que llamamos polling, o mediante interrupciones.

La tecnica polling es similar a la que muestra bmb y sería de la siguiente manera.
Código: [Seleccionar]
void main()
{
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_ccp1(CCP_OFF);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);

   set_tris_b(0xF0);

   // Asumiendo que el cátodo esté conectado al negativo y el ánodo al
   // pin B0 a través de una resistencia...
   
   output_low(PIN_B0); // LED apagado

   while(true)
   {
      // Asumiendo que la tecla en RA0 tiene una resistencia pullup....

      while( !input(PIN_A0));    //Esperar hasta que se presione RA0.

      if (!bit_test(PORTB,0))    // Si el LED está apagado
         output_high(PIN_B0);    // Enciende el LED
      else
         output_low(PIN_B0);     // Si no, lo apaga
   }
}

Hola bigluis. Asi como dices, el LED va a estar encendiendo y apagando constantemente.  Aunque (me imagino que por olvido) no le pusiste los corchetes {} al segundo while y si cambiaras la instrucción while( !input(PIN_A0)); por while( input(PIN_A0));, de todos modos mientras el pulsador esté presionado va a cambiar constantemente el estado del LED.  De ahí que se use una bandera para evitar esto.

Saludos!

Desconectado soymoe

  • PIC18
  • ****
  • Mensajes: 456
    • El blog de Moe
Re: Problema con programita en CCS
« Respuesta #7 en: 16 de Octubre de 2010, 17:58:29 »
Otra forma de resolver ese problema es esperando hasta que la tecla sea presionada, para ello lo puedes hacer de dos formas, mediante una tecnia a la que llamamos polling, o mediante interrupciones.

La tecnica polling es similar a la que muestra bmb y sería de la siguiente manera.
Código: [Seleccionar]
void main()
{
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_ccp1(CCP_OFF);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);

   set_tris_b(0xF0);

   // Asumiendo que el cátodo esté conectado al negativo y el ánodo al
   // pin B0 a través de una resistencia...
   
   output_low(PIN_B0); // LED apagado

   while(true)
   {
      // Asumiendo que la tecla en RA0 tiene una resistencia pullup....

      while( !input(PIN_A0));    //Esperar hasta que se presione RA0.

      if (!bit_test(PORTB,0))    // Si el LED está apagado
         output_high(PIN_B0);    // Enciende el LED
      else
         output_low(PIN_B0);     // Si no, lo apaga
   }
}
Este programa funciona, lo que pasa es que no elimina el rebote y a veces falla.Es por esa razon es que yo ponia un delay para eliminar el rebote.

Desconectado bmb

  • PIC18
  • ****
  • Mensajes: 423
Re: Problema con programita en CCS
« Respuesta #8 en: 16 de Octubre de 2010, 20:11:10 »
...Este programa funciona, lo que pasa es que no elimina el rebote y a veces falla.Es por esa razon es que yo ponia un delay para eliminar el rebote.

Hola soymoe. Me alcanzaste a preocupar, monté el circuito en Proteus y como había dicho en el post anterior, el LED prende y apaga constantemente.  Podrías subir tu esquemático para ver el por que a ti si te funciona?  Te adjunto una simulación en Proteus con los dos códigos fuentes y los compilados para que hagas las pruebas.

Saludos!

Desconectado bigluis

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 511
    • Tutoriales de Qt C++
Re: Problema con programita en CCS
« Respuesta #9 en: 16 de Octubre de 2010, 20:37:12 »
Este programa funciona, lo que pasa es que no elimina el rebote y a veces falla.Es por esa razon es que yo ponia un delay para eliminar el rebote.

Exactamente es necesario poner un deley luego del segundo while para eliminar rebotes.

Hola bigluis. Asi como dices, el LED va a estar encendiendo y apagando constantemente.  Aunque (me imagino que por olvido) no le pusiste los corchetes {} al segundo while y si cambiaras la instrucción while( !input(PIN_A0)); por while( input(PIN_A0));, de todos modos mientras el pulsador esté presionado va a cambiar constantemente el estado del LED.  De ahí que se use una bandera para evitar esto.

:lol: No olvide ponerle los corchetes al segund while, simplemente no los necesita ya que no tendrá ningun argumento.

Por otro lado para evitar eso de que cuando tienes presionado el boton este comienza a cambiar constantemente es necesario que pongas un while de espera para que sueltes el boton.
Código: [Seleccionar]
output_low(PIN_B0); // LED apagado

   while(true)
   {
      // Asumiendo que la tecla en RA0 tiene una resistencia pullup....

      while(input(PIN_A0));    //Esperar hasta que se presione RA0.
     
         if (!bit_test(PORTB,0))    // Si el LED está apagado
           output_high(PIN_B0);    // Enciende el LED
         else
            output_low(PIN_B0);     // Si no, lo apaga
     
      delay_ms(10); //Retardo para eliminar Rebotes.
      while(!input(PIN_A0));    //Esperar hasta que se suelte RA0.
     
   }
}
Tutoriales de Qt C++

No es necesario que hagamos Grandes cosas, sino que lo que hagamos sea importante.

SI la NECESIDAD es la MADRE del CONOCIMIENTO, SEGURAMENTE la PEREZA su TÍA.

Cuando el ARTE requiere de PRECISION le llamamos CIENCIA

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Problema con programita en CCS
« Respuesta #10 en: 16 de Octubre de 2010, 21:39:06 »
Acá dejo una versión hecha en HiTech C.
Van a notar que también hago uso de "setup_comparator" y "disable_interrupt"; pero no son funciones que tenga HiTech sino unas definiciones que hice para, en su momento, hacerme más fácil la mudanza de CCS a HiTech

Código: C
  1. /*
  2.   El pin RA0 lleva una resistencia de pull up y el pulsador une a GND
  3.   El led se conecta con el cátodo a GND y el ánodo por medio de una resistencia RB0
  4. */
  5.  
  6.  
  7.  
  8. #include <pic.h>
  9.  
  10. __CONFIG (MCLRDIS & LVPDIS & WDTDIS);
  11.  
  12. #include "Def16f62xa.h"
  13. #define PIC_CLK 4000000
  14. #include "delayhd.h"
  15.  
  16. void AntiRebote(void)
  17. {
  18.   unsigned char veces;
  19.  
  20.   for (veces = 40; veces > 0; veces--)
  21.     DelayUs (250);
  22.  
  23. }
  24.  
  25.  
  26. void main(void)
  27. {
  28.   setup_comparator (NC_NC_NC_NC);    // deshabilito los comparadores
  29.   disable_interrupt (GLOBAL);        // deshabilito las interrupciones
  30.   TRISA = 1;                        // A0 como entrada
  31.   TRISB = 0;                        // todo el puerto B como salida
  32.   PORTB = 0;                        // Led apagado
  33.   while (1)
  34.   {
  35.     if (RA0 == 0)                    // Switch presionado?
  36.     {
  37.       AntiRebote();                    // espera anti rebote
  38.       if (RA0 == 0)                 // si aun sigue presionado
  39.       {  
  40.         RB0 ^= 1;                    // cambio el estado de RB0
  41.         while (RA0 == 0);            // espero hasta soltar el swtich
  42.       }
  43.     }
  44.   }
  45. }
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado bmb

  • PIC18
  • ****
  • Mensajes: 423
Re: Problema con programita en CCS
« Respuesta #11 en: 16 de Octubre de 2010, 22:51:25 »
Hola bigluis, ahora con las correcciones que hiciste, el programa si funciona.  Sin embargo es bueno aclararle a soymoe, que el programa siempre se va a quedar detenido en alguno de los while alli implementados según sea accionado el pulsador en A0.  Con esto quiero decir que si el programa es solo para cambiar de estado el LED estaría muy bien, pero si se le van a adicionar otras funciones no le va a servir asi.

Saludos!

Desconectado soymoe

  • PIC18
  • ****
  • Mensajes: 456
    • El blog de Moe
Re: Problema con programita en CCS
« Respuesta #12 en: 17 de Octubre de 2010, 21:54:25 »
...Este programa funciona, lo que pasa es que no elimina el rebote y a veces falla.Es por esa razon es que yo ponia un delay para eliminar el rebote.

Hola soymoe. Me alcanzaste a preocupar, monté el circuito en Proteus y como había dicho en el post anterior, el LED prende y apaga constantemente.  Podrías subir tu esquemático para ver el por que a ti si te funciona?  Te adjunto una simulación en Proteus con los dos códigos fuentes y los compilados para que hagas las pruebas.

Saludos!
Yo no uso el proteus, lo armo en proto, este es el esquematico

Desconectado bmb

  • PIC18
  • ****
  • Mensajes: 423
Re: Problema con programita en CCS
« Respuesta #13 en: 18 de Octubre de 2010, 00:11:02 »
Hola soymoe, según se ve en tu esquemático, tienes mal conectados los pines.  Te adjunto un diagrama con las conexiones.

Saludos!

Desconectado soymoe

  • PIC18
  • ****
  • Mensajes: 456
    • El blog de Moe
Re: Problema con programita en CCS
« Respuesta #14 en: 19 de Octubre de 2010, 17:41:50 »
Hola amigos: He podido resolver el problemita de apagar y prender un led con una tecla.
Código: [Seleccionar]
#include <16F628A.h>

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC                    //Internal RC Osc
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOBROWNOUT               //No brownout reset
#FUSES MCLR                   //Master Clear pin used for I/O
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection

#use delay(clock=4000000)

#byte PORTB=0x06

void main()
{   
   int1 presiono =false;
   int1 solto =false;
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_ccp1(CCP_OFF);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   set_tris_a(0x0F);
   set_tris_b(0xF0);

   // Asumiendo que el cátodo esté conectado al negativo y el ánodo al
   // pin B0 a través de una resistencia...
   
   output_low(PIN_B0); // LED apagado
   while(true)
   {presiono =false;
    solto =false;
   while(input(PIN_A0)&(!presiono));//Esperar hasta que se presione RA0.
   {delay_ms(100);}
   presiono=true;
   while(!input(PIN_A0));//Esperar hasta que se suelte RA0.
   {delay_ms(100);}
   solto=true;
   if (!bit_test(PORTB,0)&(presiono)&(solto))    // Si el LED está apagado
           output_high(PIN_B0);    // Enciende el LED
         else
            output_low(PIN_B0);     // Si no, lo apaga
   }}
Quizas no sea lo mas elegante pero funciona. Se los dejo para lo que les interese.