Ir ao conteúdo

Programação pic com botão liga/desliga


Ir à solução Resolvido por nil.34,

Posts recomendados

Postado

Aguem sabe uma rotina para ler um unico botão, de maneira que com um toque ele execute uma função, outro toque ela deixa de executar a mesma funcão.

Postado
Fiz uma breve programação para isto, a jogada é quando você utiliza a função " while(input(pin_a0)==1); " que aguarda você soltar o botão para sair da condição "if".

Utilizei o pic 16f877a com clock de 4MHz, se for outro só substituir o "include" e o "use delay".

(Não consegui testar pois estou sem o picc no meu pc, perdoe qualquer esquecimento.)

 

Espero ter ajudado.

 

 

// Diretivas do compilador 

 

#include<16f877a.h>                            // Anexa ao programa o arquivo 16F877A.h 

#use delay(clock=4000000)                 // Utiliza um clock de 4MHz para o para o microcontrolador 

#fuses NOPROTECT                           // Dispositivo sem proteção para leitura da eeprom 

#fuses NOWDT                                   // Watch dog desabilitado 

#fuses NOLVP                                    // gravação em alta tensão desligada 

#fuses HS                                           // Opera com cristal acima de 4MHz 

#fuses NOBROWNOUT                     // Não resseta o chip se a tensão cair abaixo de 4V

 

// O programa 

 

unsigned int conta=0;                        // declara uma variável conta de 16bits 

 

main() 


 while (true) 

 { 

 

   if(input(pin_a0)==1 & conta==0) 

   { 

     conta++; 

     //Aqui você coloca a função que deseja acionar, por exemplo vou botar para ligar o pino b0

     output_high(pin_b0);

     delay_ms(1); 

     while(input(pin_a0)==1);                 // Aguarda você soltar o pin_a0

   } 


   if(input(pin_a0)==1 & conta==1) 

   { 

     conta++; 

     //Aqui você coloca a função que deseja desligar, por exemplo vou botar para desligar o pino b0

     output_low(pin_b0);

     delay_ms(1); 

     while(input(pin_a0)==1);                 // Aguarda você soltar o pin_a0

     conta=0;

   } 


 }


  • Membro VIP
Postado


static bit b=0;

void main(void)

{

for(;;)

{

while(RA0);//espera "um toque..."

while(!RA0);//tire o dedinho do botão por favor

b^=1;

if (B) funcao(); //"...ele execute uma função"

//else deixa_de_executar();//..."outro toque ela deixa de executar a mesma funcão."

}

}

Postado

Obrigado.

DMHIGOR

 

Conforme você sugeriu, fiz algumas adaptações no programa que estou testando e funcionou, conforme estava esperando...

 

A intenção é acionar e desacionar um motor cc com pwm (através mosfet) através de um unico botão, e variar a velocidade mesmo através de um botão incrementa e outro decrementa.

 

Esta funcionando, o que estou agora tentando resolver, é que as vezes o botão que lig/ desl o pwm falha como se fosse problema de ruido.Mas não testei na pratica, apenas simulei no proteus, não sei se pode ser problema de simulação,Mas o acionamento esta falhando.

 

Segue abaixo  o programa


/*******************************************************************************
                         Acionamento motor com PWM
                                PIC 16f877A
                                Compilador CCS
*******************************************************************************/                                
#FUSES NOWDT    //No Watch Dog Timer
#FUSES HS      //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT  //No Power Up Timer
#FUSES NOPROTECT  //Code not protected from reading
#FUSES NODEBUG   //No Debug mode for ICD
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD   //No EE protection
#FUSES NOWRT   //Program memory not write protected
#FUSES RESERVED  //Used to set the reserved FUSE bits

#use delay(clock=4000000)

#use fast_io(a)// define as utilizações das portas a como entrada e saida
#use fast_io(b)// define as utilizações das portas b como entrada e saida
#use fast_io(d)//                 --

#byte porta = 0x05 // padrão endereços das portas
#byte portb = 0x06 // padrão endereços das portas
#byte portc = 0x07 //             --
#byte portd = 0x08 //             --

#bit botao_desce = porta.0 // define porta A0 como botão decrementa PWM
#bit botao_sobe = porta.1  // define porta A1 como botão incrementa PWM
#bit botao_start = porta.2 // define porta A2 como botão liga /desliga PWM

unsigned int a=10,x=0;
/***************************************************************************
                           Função liga / desliga - motor
****************************************************************************/                           

void motor_para(){ //rotina deliga motor
 
                     x++;
                     if(x>=1)
                     set_pwm1_duty(0);// desliga pwm
                     delay_ms(1);
                     while(input(botao_start)==1);//aguarda soltar botão
                     x=0;
                 }
                     
void motor_gira(){ //rotina liga motor
                     x++;
                     if(x>=1)
                     set_pwm1_duty(a);
                     delay_ms(1);
                     while(input(botao_start)==1);//aguarda soltar botão  
                 }

/*****************************************************************************
                           Função Principal
******************************************************************************/

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_DIV_BY_4,249,1);// frequência 1KZ
   setup_ccp1(CCP_PWM);
   set_pwm1_duty(10);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);

set_tris_a (0b00000111); // define port a0 e port a1 e a2 como entrada


set_pwm1_duty(30);// ***********************************************************
delay_ms(600); //     Estas funçoes acionam um pulso no motor sempre lig progr.
set_pwm1_duty(0);//*************************************************************

 while(true){
 
if (botao_start==1 && x>=1){ // se o botao start acionado,motor estiver lig
     delay_ms(5);
     motor_para();//rotina - motor desliga
                           }
if (botao_start==1 && x>=0){ //se o botao start acionado,motor estiver deslig
     delay_ms(5);
     motor_gira(); // rotina - motor liga
                           }
 
if (botao_sobe==1){ // botão incrementa pwm
 
                     if (a<245){ // incrementa até 245
                     a=a+1;
                     delay_ms(100);
                     if(x>=1){ // mesmo soltando botão pwm continua ligado
                     set_pwm1_duty(a);// pwm assume valor variavel a
                              }
                               }
                   }
 if (botao_desce==1){// botão decrementa pwm
                     if (a>0){
                     a=a-1;
                     delay_ms(100);
                     if(x>=1){
                     set_pwm1_duty(a);
                             }
                              }
                    }
            }

}

  • 3 semanas depois...
  • Solução
Postado

Consegui resolver problema, não era ruido, e sim erro no programa, que no CCS ficou assim:

while(true){

 

 if(botao_start==0 && x==1){ // se o botao start acionado,motor estiver lig

     delay_ms(5);

                     x++;

                     set_pwm1_duty(0);// desliga motor

                     led_start=0; //apaga led start

                     led_stop=1;// acende led stop

                     delay_ms(1);

                     while(botao_start==0);//aguarda soltar botão

                     x=0;   

                             }

if(botao_start==0 && x==0){ //se o botao start acionado,motor estiver deslig

     delay_ms(5);

                     x++;

                     set_pwm1_duty(a); // atribui pwm ao valor ajustado em a

                     led_start=1;// acende led start

                     led_stop=0; // apaga led stop

                     delay_ms(1);

                     while(botao_start==0);//aguarda soltar botão

                            }

 

 

 

tópico resolvido.

  • 6 anos depois...
  • Membro VIP
Postado

Não vi o seu problema mas acho que é porquê não vi seu programa. Tenta publicá-lo bem como o esquema. Dica publique diretamente na caixa de texto 'code' clicando no botão '< >' acima.

E espero que não tenha queimado a importantíssima etapa do pisca led.

 

edit ... não responda aqui. Use seu outro tópico ok?

🙃

Postado

@.if   Honrado por responder.

             O programa a baixo funciona perfeitamente, ou seja, quado pressiono t2, aciona duas saidas no portb e junto o pwm e tenho controle do mesmo, digo o duty.

            Construi três cases nesse programa, quando aperto rb1, ele vai incrementando e passando pelas saídas no portb. Cade led desse terá uma tarefa a executar, porém, a primeira( led 1) eu aciono o motor e ele fica direto, mesmo soltando o botão. Quando pressiono novamente, ele desliga o pwm.

           O problema é que já fiz varios procedimentos, mas quando consigo ligar e ao pressionar novamente, ele liga( pwm), mas eu não tenho controle, ou seja, quando vario o potenciômetro ele não aumenta o duty. Queria ter uma ajuda, sou medíocre ainda.

 

#define t2 portb.rb0      // mapea t2, rb0

#define t1 portb.rb2      // mapea t1, rb2

#define l4 portb.rb4      // mapea L4, rb4

#define l5 portb.rb5      // mapea l5, rb5

 

 

 

#define b1 portb.rb1    // mapea b1 como entrada digital

#define l1 portc.rc4    // mapea L1 como  saida

#define l2 portc.rc5    // mapea L2 como  saida

#define l3 portc.rc6    // mapea L3 como  saida

 

         //             variaveis globais

 

      int pwm2 = 0;

      int pwm1 = 0;               // variavel para o pwm

      unsigned int motor_speed;   // varial controle de velocidade

      char x1=0,x2=0,controle=0;  //variaveis aux botao

      int cont=0;                 // varial aux botao

      char x3 = 0;                // varial aux botao

      char x4 = 0;

      char x5 = 1;

      char x6 = 0;

       //             funcão principal

 

      void main()

   {

 

   //OPTION_REG = 0x80;

   //GIE_bit = 0x01;      //Habilita a interrupção global

   //PEIE_bit = 0x00;     //Desabilita a interrupção por periféricos

   // INTE_bit = 0x01;     //Habilita a interrupção externa

   //INTEDG_bit = 0x00;   //Configura a interrupção por borda de descida

 

 

  trisa0_bit =1;        // define ra0 como entrada

  trisb1_bit = 1;       // define rb1 como entrada

  trisb2_bit = 1;       // define rb2 como entrada

  trisc4_bit = 0;       // define rc4 como saida

  trisb4_bit = 0;       // define rb4 como saida

  trisb5_bit = 0;       // define rb5 como saida

  trisc5_bit = 0;        // define rc5 como saida

  trisc6_bit = 0;       // define rc6 como saida

  trisc3_bit = 0;       // define rc3 como saida

  rc3_bit = 1;          // incia-se rc3 em nivel alto

  rb4_bit = 0;           // incia-se rb4.rb5, em nivel baixo

  rb5_bit = 0;

  rb1_bit = 1;           // incia-se rb1 em nivel alto

  rb2_bit = 1;           // incia-se rb2 em nivel alto

  rc7_bit= 0;

  trisc7_bit= 0;

  trisb6_bit = 0;

  rb6_bit = 0;

 

            //   configuração adc, pwm, e entrada analogica ra0

 

 

   ADCON0 = 1;       // habilita o conversor

   ADCON1 = 0;       // declara ra0 como entrada analocica

   ADC_Init();

 

 

         // incia-se

 

   PWM2_Init(1000);  // pwm em 1kh

   PWM2_Start();     // starta o pwm

   ULPWUIE_bit = 0x00;

   ANSEL =  1;       // registrador entradas analogicas

   ANSELH = 0X00;    // coloca como entrada e saidas p portb

 

   C1ON_bit = 0;      // desabilita os comparadores

   C2ON_bit = 0;

 

 

 

              // loop infinito

 

  while(1)

  {

    cont++;delay_ms(1);  // incremento

    if((b1==0)&&(x1==0)){controle++;x1=1;x4;cont=0;}

    if((b1==1)&&(x1==1)&&(cont>100))x1=0;

 

    if(controle==0)

    {l1=0;l2=0;l3=0;}

 

    if(controle==1) {

 

       l1=1;

 

 

       }

       if((t1==0))       // botao rb2  pressionado? execute:

 

       {

 

 

             x4 = 1;       // varial aux do botao rb0

             rc7_bit =1 ;

             l1 = 1;

             delay_ms(100);

             l1 = 0;

             delay_ms(100);

            }

 

            if(( t2==0)&&( x4==1))

           

            {

           

             // eu queria colocar o controle do motor( quatro tempo) aqui.

             // ao entrar no case 1,  eu seleciono com o botão t1( tecla confirma)

             // e após isso, eu  pressiono t2 e meu motor fica direto até ter

             // um novo toque no mesmo.

           

           

           

           

            }

 

              // botao rb0 pressionar? execute:

                // loop

 

          }

 

 

       if(controle==2){l1=0;l2=1;l3=0;}

       if(controle==3){l1=0;l2=0;l3=1;}

       if(controle==4)controle=0;

      

      

      

      

      

 

 

        //    Aqui esta o controle do motor: ao  pressionar o motor, ele liga

        //    e ao solta-lo, ele desliga e tenho o controle do duty.

       

       

       

       

     if((t2==0)&&(x2==0))

       {

         l4=1;l5=1; x2=1; x3 = 1;

 

         }

 

      if((t2==1)&&(x2==1))

 

        {

           l4=0;l5=0;x2=0; x3 = 0;

 

        }

 

        if((pwm2 ==0)&&(x3==1))

        {

 

         motor_speed = ADC_Read(0);

        PWM2_Set_Duty(motor_speed >> 2);

 

          delay_ms(50) ;

 

 

        }

 

        if((pwm2 ==0)&&(x3==0))

         {

 

             motor_speed = 0x00;

             PWM2_Set_Duty(motor_speed = 0);

 

 

 

        }

 

 

 

 

}

}

1 minuto atrás, Afonso tales disse:

@.if   Honrado por responder.

             O programa a baixo funciona perfeitamente, ou seja, quado pressiono t2, aciona duas saidas no portb e junto o pwm e tenho controle do mesmo, digo o duty.

            Construi três cases nesse programa, quando aperto rb1, ele vai incrementando e passando pelas saídas no portb. Cade led desse terá uma tarefa a executar, porém, a primeira( led 1) eu aciono o motor e ele fica direto, mesmo soltando o botão. Quando pressiono novamente, ele desliga o pwm.

           O problema é que já fiz varios procedimentos, mas quando consigo ligar e ao pressionar novamente, ele liga( pwm), mas eu não tenho controle, ou seja, quando vario o potenciômetro ele não aumenta o duty. Queria ter uma ajuda, sou medíocre ainda.

 

#define t2 portb.rb0      // mapea t2, rb0

#define t1 portb.rb2      // mapea t1, rb2

#define l4 portb.rb4      // mapea L4, rb4

#define l5 portb.rb5      // mapea l5, rb5

 

 

 

#define b1 portb.rb1    // mapea b1 como entrada digital

#define l1 portc.rc4    // mapea L1 como  saida

#define l2 portc.rc5    // mapea L2 como  saida

#define l3 portc.rc6    // mapea L3 como  saida

 

         //             variaveis globais

 

      int pwm2 = 0;

      int pwm1 = 0;               // variavel para o pwm

      unsigned int motor_speed;   // varial controle de velocidade

      char x1=0,x2=0,controle=0;  //variaveis aux botao

      int cont=0;                 // varial aux botao

      char x3 = 0;                // varial aux botao

      char x4 = 0;

      char x5 = 1;

      char x6 = 0;

       //             funcão principal

 

      void main()

   {

 

   //OPTION_REG = 0x80;

   //GIE_bit = 0x01;      //Habilita a interrupção global

   //PEIE_bit = 0x00;     //Desabilita a interrupção por periféricos

   // INTE_bit = 0x01;     //Habilita a interrupção externa

   //INTEDG_bit = 0x00;   //Configura a interrupção por borda de descida

 

 

  trisa0_bit =1;        // define ra0 como entrada

  trisb1_bit = 1;       // define rb1 como entrada

  trisb2_bit = 1;       // define rb2 como entrada

  trisc4_bit = 0;       // define rc4 como saida

  trisb4_bit = 0;       // define rb4 como saida

  trisb5_bit = 0;       // define rb5 como saida

  trisc5_bit = 0;        // define rc5 como saida

  trisc6_bit = 0;       // define rc6 como saida

  trisc3_bit = 0;       // define rc3 como saida

  rc3_bit = 1;          // incia-se rc3 em nivel alto

  rb4_bit = 0;           // incia-se rb4.rb5, em nivel baixo

  rb5_bit = 0;

  rb1_bit = 1;           // incia-se rb1 em nivel alto

  rb2_bit = 1;           // incia-se rb2 em nivel alto

  rc7_bit= 0;

  trisc7_bit= 0;

  trisb6_bit = 0;

  rb6_bit = 0;

 

            //   configuração adc, pwm, e entrada analogica ra0

 

 

   ADCON0 = 1;       // habilita o conversor

   ADCON1 = 0;       // declara ra0 como entrada analocica

   ADC_Init();

 

 

         // incia-se

 

   PWM2_Init(1000);  // pwm em 1kh

   PWM2_Start();     // starta o pwm

   ULPWUIE_bit = 0x00;

   ANSEL =  1;       // registrador entradas analogicas

   ANSELH = 0X00;    // coloca como entrada e saidas p portb

 

   C1ON_bit = 0;      // desabilita os comparadores

   C2ON_bit = 0;

 

 

 

              // loop infinito

 

  while(1)

  {

    cont++;delay_ms(1);  // incremento

    if((b1==0)&&(x1==0)){controle++;x1=1;x4;cont=0;}

    if((b1==1)&&(x1==1)&&(cont>100))x1=0;

 

    if(controle==0)

    {l1=0;l2=0;l3=0;}

 

    if(controle==1) {

 

       l1=1;

 

 

       }

       if((t1==0))       // botao rb2  pressionado? execute:

 

       {

 

 

             x4 = 1;       // varial aux do botao rb0

             rc7_bit =1 ;

             l1 = 1;

             delay_ms(100);

             l1 = 0;

             delay_ms(100);

            }

 

            if(( t2==0)&&( x4==1))

           

            {

           

             // eu queria colocar o controle do motor( quatro tempo) aqui.

             // ao entrar no case 1,  eu seleciono com o botão t1( tecla confirma)

             // e após isso, eu  pressiono t2 e meu motor fica direto até ter

             // um novo toque no mesmo.

           

           

           

           

            }

 

              // botao rb0 pressionar? execute:

                // loop

 

          }

 

 

       if(controle==2){l1=0;l2=1;l3=0;}

       if(controle==3){l1=0;l2=0;l3=1;}

       if(controle==4)controle=0;

      

      

      

      

      

 

 

        //    Aqui esta o controle do motor: ao  pressionar o motor, ele liga

        //    e ao solta-lo, ele desliga e tenho o controle do duty.

       

       

       

       

     if((t2==0)&&(x2==0))

       {

         l4=1;l5=1; x2=1; x3 = 1;

 

         }

 

      if((t2==1)&&(x2==1))

 

        {

           l4=0;l5=0;x2=0; x3 = 0;

 

        }

 

        if((pwm2 ==0)&&(x3==1))

        {

 

         motor_speed = ADC_Read(0);

        PWM2_Set_Duty(motor_speed >> 2);

 

          delay_ms(50) ;

 

 

        }

 

        if((pwm2 ==0)&&(x3==0))

         {

 

             motor_speed = 0x00;

             PWM2_Set_Duty(motor_speed = 0);

 

 

 

        }

 

 

 

 

}

}

 

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...