Ir ao conteúdo

PIC- Um botão com 3 Funções


Robson Lopes

Posts recomendados

Postado

Ola pessoal

 

Tudo bem?

 

Sou iniciante na programação, mas estou fazendo um cronometro e ja fiz tudo bem dizer, porém travei nas lógicas do botão, eu quero fazer um botão com 3 a função (star / stop / configuração) .... ou seja .... se eu apenas apertar o botão (como click) ele ira fazer as funções start e stop apenas, porém se eu segurar por 3 segundos, ele vai para a tela de configuração...

 

E outra coisa amigos, poderiam por favor  me explicar técnicamente se eu posso colocar ações na interrupção (vetor de interrupção org 0x04) tipo se eu posso colocar a função varredura de um display, atualização de ports, verificação de flgs dentro da interrupção por que eu quero aprender a program,ar certinho ....

 

eu programo em MIKROC e conheço o CCS e gosto muito tambem....

 

Obrigado pesssoal

Postado

Olá,

Vou tentar te ajudar, qualquer coisa é só questionar.

Dentro de interrupções não é bom colocar chamadas para outras funções não heim, No CCS acusa erro de reentrância (se não me engano);

Sobre os botões, eu particularmente prefiro usar interrupções para varrer botões, no seu caso como só tem um botão eu faria a lógica da seguinte forma:

Esse bloco fica dentro da sua interrupção, é bom que fique em um local que seja executado várias vezes por segundo (Eu usaria esse bloco dentro de um local com dez execuções por segundo.).

if (input(botao)){                     // Testa se o botão esta pressionado.   contador ++;                        // Incrementa um contador de tempo.}else{                                    if (contador){                      // Testa se ja houve contagem desde a ultima verificação      if (contador < tres_segundos){   // Se na ultima vez que o botão foi apertado, ficou por mais de tres segundos.         id_start_stop = 1;            // Define o indicador do botão de start como o botão apertado.         id_configuracao = 0;          // apenas por garantia, defina esse indicador como zero.      }else{         id_configuracao = 1;          // Define o indicador do botão de configuração como verdadeiro         id_start_stop = 0;            // Apenas por garantia      }      contador = 0;                    // Zera o contador para que não entre nesse bloco novamente.   }}

As variaveis id_start_stop e id_configuracao são globais do tipo short int.
A variavel contador é global é do tipo int o tamanho depende do local que tu colocar...
A tres_segundos é uma constante que depende de quantas vezes por segundo esse código vai ser executado.


Agora dentro do seu loop principal você pode testar a qualquer momento se os indicadores id_configuracao e id_start_stop estão setados.

Exemplo:

while (true){   atualiza_display();                 // Seu código para atualizar os digitos do display.   if (id_start_stop){                 // Testa se o botão foi apertado ou não      if(id_tempo_correndo){           // Se o botão foi apertado e tem contagem de tempo em andamento         pausa_contagem();             // Rotina/código que vai pausar a contagem de tempo.      }else{                                    inicia_contagem();            // Se não tiver contagem de tempo em andamento, aqui é o código/chamada para iniciar a contagem      }      id_start_stop = 0;               // Define que o botão ja foi tratado. Só entrará novamente nesse bloco se o botão voltar a ser pressionado.   }   if (id_configuracao){               // Se o botão de configuração estiver pressionado      configuracao();                  // Código ou chamada para função de configuração.   }}

Bom, não sei o seu nível de entendimento, veja se com isso consegue entender minha ideia... Se precisar de explicação é só perguntar. Esse código tem várias melhorias que podem ser feitas. Poste o código que você ja começou a fazer, fica melhor para você se eu explicar como fazer com base na sua atual lógica!!!
 

 

Esse algoritimo que uso pode não ser a melhor forma, se alguém puder melhorar essa ideia ou mostrar outra forma mais eficiente, seremos gratos!!

  • mês depois...
Postado

@williankleber
 
Ola amigo legal hein, voce é muito fera ....
 
Mano primeiramente desculpe a demora de responder, fiquei feliz por me responder obrigado mesmo....
 
 
mais primeiramente a respeito sobre chamada de funções: Amigo eu cai nesse dilema kkkkkkk por que assim estou fazendo um cronometro, e a atualização do display esta na interrupção do tmr0 calculado com 50 hz cada display, e na interrupção do tmr1 eu fiz o clock de 1 sergundo .... ai que esta o dilema, primeiramente eu utilizei o vetor de interrupção so com flags, e tratei a interrupção no bloco main, o que acontecia eu não podia colocar nenhum delay_ms(), e nenhum While() que quebrava tudo o que havia calculado, por que quando ele sai da interrupção ele volta aonde parou do bloco principal, e quando ele voltar e estiver em uma função de atraso, ele tem que esperar essa função acabar pra depois ir fazer a interrupção castela e quando acontece isso o que eu faço exemplo em baixo:
 

Interrupt (){       if (tmr0if == 1)      {         flag1 = 1;         tmr0if = 0;      }}  void main(){         if (flag1 == 1)         {           varredura_de_display();           flag1 = 0;         }           if (botão == 1)         {              Led = 1;              while (botão == 1);               }}

 
 
Então amigo sou novo na area to estudando o maximo, mais tenho muito duvida   mano
 
 
E a respeito do botão ele vai fazer um loop de start e stop ate chegar os 3 segundos pressionado que é de configuração (mais da pra usar sim :D )
 

if (input(botao)){                     // Testa se o botão esta pressionado.   contador ++;                        // Incrementa um contador de tempo.}else{                                    if (contador){                      // Testa se ja houve contagem desde a ultima verificação      if (contador < tres_segundos){   // Se na ultima vez que o botão foi apertado, ficou por mais de tres segundos.         id_start_stop = 1;            // Define o indicador do botão de start como o botão apertado.         id_configuracao = 0;          // apenas por garantia, defina esse indicador como zero.      }else{         id_configuracao = 1;          // Define o indicador do botão de configuração como verdadeiro         id_start_stop = 0;            // Apenas por garantia      }      contador = 0;                    // Zera o contador para que não entre nesse bloco novamente.   }}

 
 
@williankleber
 
desculpe esqueci de comentar, esse loop que vai ficar de start e stop quando o botão estiver pressionado para ir configuração que esta quebrando minhas pernas :D  por que quando eu pressionanar o botão o if (contador < tres_segundos) vai ser verdadeiro ate que seja igual 3 segundos e faça a função configuração ...
 
tenso, na realidade isso é mais raça do que tentar resolver o problema do cronometro, e que quero fazer 2 funções destintas com o botão, com ele pressionado e ele como click, se eu apenas fazer a parte de click não posso entrar na função da parte pressionado, e quando eu fizer da parte pressionado não posso fazer a parte click
 
please help me kkkk
 
Obrigado amigo

Postado

Olá, dessa forma independente de suas chamadas de funções os calculos e o display sempre estariam corretos.

#INT_TIMER0void  TIMER0_isr(void){                      // interrupção de 50Hz   {   ...   ...   ...    //Código de atualização do display   ...    // Atualize do display sempre com os valores das variaveis minutos e segundos   ...   }      if (++cont_timer0 == 5){                  // Esse if controla a entrada na rotina abaixo apenas a cada 100 milisegundos      cont_timer0 = 0;      if (input(botao)){                     // Testa se o botão esta pressionado.         contador ++;                        // Incrementa um contador de tempo.      }else{                                          if (contador){                      // Testa se ja houve contagem desde a ultima verificação            if (contador < tres_segundos){   // Se na ultima vez que o botão foi apertado, ficou por mais de tres segundos.               id_start_stop = 1;            // Define o indicador do botão de start como o botão apertado.               id_configuracao = 0;          // apenas por garantia, defina esse indicador como zero.            }else{                  id_configuracao = 1;          // Define o indicador do botão de configuração como verdadeiro               id_start_stop = 0;            // Apenas por garantia            }              contador = 0;                    // Zera o contador para que não entre nesse bloco novamente.         }      }   }}#INT_TIMER1void TIMER1_isr(void){                       // Essa interrupção ocorre a cada 1 segundo   if (contagem_progresso){      if (++segundos==60){         segundos = 0;         if(++minutos==99){            minutos = 1;         }      }   }}void main(){   while (true){      if (id_start_stop){                    // Testa se o botão foi apertado ou não         if(id_tempo_correndo){              // Se o botão foi apertado e tem contagem de tempo em andamento            contagem_progresso = 0;          // Rotina/código que vai pausar a contagem de tempo.         }else{                                          contagem_progresso = 1;          // Se não tiver contagem de tempo em andamento, aqui é o código/chamada para iniciar a contagem         }                                          id_start_stop = 0;                  // Define que o botão ja foi tratado. Só entrará novamente nesse bloco se o botão voltar a ser pressionado.      }                                          if (id_configuracao){                  // Se o botão de configuração estiver pressionado         configuracao();                     // Código ou chamada para função de configuração.      }   }}

O calculo dos minutos e segundos são feitos na interrupção, a atualização do display também. E a leitura e tratamento dos botões também. Independente do que ocorra, a contagem de tempo e a atualização do display ficarão corretas... aplicando essa lógica você poderá usar quantos delay for preciso para outras funções. Pois as funções críticas sempre serão executadas pelas interrupções...   Se quiser se aprofundar nisso, pesquise por RTOS...

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

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...

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!