Ir ao conteúdo

PIC filtro anti-debounce na linguagem C


Ir à solução Resolvido por Maria Cristina Oliveira,

Posts recomendados

Postado

Oi:

Esse filtro é perfeito em assembly, mas não estou conseguindo passar esse

trecho do programa para a linguagem C.😪

Gostaria de aprender a fazer sem  usar #asm e #endasm.

Se alguém souber, eu ficaria muito agradecida!

 

main:
      btfsc    bot0                                   ; testa botão 0
      goto     bot0lib                               ; se liberado, vai para bot0lib
      decfsz antdeb,f                             ; se pressionado, decrementa filtro
      goto     main                                   ; volta para main
      decfsz antdeb2,f                           ; se acabou filtro 1, inicia filtro 2
      goto     main                                   ; volta para main
      goto     bot0pres                            ; vai para bot0pres
bot0lib:
      goto main
bot0pres:
          ...
          ...

 

Quanto às intruções:

 

(BTFSC f,b) - Testa o bit b, do registrador f, pula se for 0
(goto  k) - desvia o programa para k
(DECFSZ f,d) - Decrementa f, resultado no d, pula se for 0

antdeb e antdeb2 são registradores de propósito geral de 8 bits
 

 

Postado
1 hora atrás, Maria Cristina Oliveira disse:

Oi:

Esse filtro é perfeito em assembly, mas não estou conseguindo passar esse

trecho do programa para a linguagem C.😪

Gostaria de aprender a fazer sem  usar #asm e #endasm.

Se alguém souber, eu ficaria muito agradecida!

 

main:
      btfsc    bot0                                   ; testa botão 0
      goto     bot0lib                               ; se liberado, vai para bot0lib
      decfsz antdeb,f                             ; se pressionado, decrementa filtro
      goto     main                                   ; volta para main
      decfsz antdeb2,f                           ; se acabou filtro 1, inicia filtro 2
      goto     main                                   ; volta para main
      goto     bot0pres                            ; vai para bot0pres
bot0lib:
      goto main
bot0pres:
          ...
          ...

 

Quanto às intruções:

 

(BTFSC f,b) - Testa o bit b, do registrador f, pula se for 0
(goto  k) - desvia o programa para k
(DECFSZ f,d) - Decrementa f, resultado no d, pula se for 0

antdeb e antdeb2 são registradores de propósito geral de 8 bits
 

 

 

Se fosse outro Assembly eu poderia tentar .....

 

Eu fiz vários tipos de debounce, e hoje uso um bem simples :

 

1 - Verifica se o botão foi apertado ( NORMALMENTE DEVE IR PARA NÍVEL 0 ).

2 - Espera 40 mseg ( algum tipo de delay )

3 - Verifique novamente o botão. Se estiver em nível 1, já acabou o bounce e pode ir fazer o que deve quando botão foi apertado.

     Se estiver em 0, fica verificando até ele estar em nivel 1, aí faça o que escreví em cima.

 

Ficou bem simples e funcional  ....

 

Paulo

  • Curtir 1
Postado
16 horas atrás, aphawk disse:

 

Se fosse outro Assembly eu poderia tentar .....

 

Eu fiz vários tipos de debounce, e hoje uso um bem simples :

 

1 - Verifica se o botão foi apertado ( NORMALMENTE DEVE IR PARA NÍVEL 0 ).

2 - Espera 40 mseg ( algum tipo de delay )

3 - Verifique novamente o botão. Se estiver em nível 1, já acabou o bounce e pode ir fazer o que deve quando botão foi apertado.

     Se estiver em 0, fica verificando até ele estar em nivel 1, aí faça o que escreví em cima.

 

Ficou bem simples e funcional  ....

 

Paulo

Eu uso exatamente dessa maneira !!

  • Curtir 1
  • Solução
Postado
Em 06/04/2021 às 14:12, Maria Cristina Oliveira disse:

main:
      btfsc    bot0                                   ; testa botão 0
      goto     bot0lib                               ; se liberado, vai para bot0lib
      decfsz antdeb,f                             ; se pressionado, decrementa filtro
      goto     main                                   ; volta para main
      decfsz antdeb2,f                           ; se acabou filtro 1, inicia filtro 2
      goto     main                                   ; volta para main
      goto     bot0pres                            ; vai para bot0pres
bot0lib:
      goto main
bot0pres:

 

Ufa! 

Queimei meus neurônios (não sou loira), mas acho que consegui!!!!! :jump:

main:
   if(!bot0) antdeb –-;
   else {goto bot0lib};
   if(!antdeb)antdeb2--;
   else {goto main};
   if(!antdeb2) goto bot0pres;
   else {goto main};

bot0lib:
   ...
bot0pres:
   ...

 

Muito simples, fiz agora, às pressas. Deve funcionar, se eu consegui escrever

tudo corretamente! :thumbsup:

 

OBS:antdeb e antdeb2 são registradores de propósito geral de 8 bits


 

 

 

Postado
1 minuto atrás, aphawk disse:

Não entendo nada de C... mas por mais que tente intuitivamente entender, não vejo nenhum delay... e sem delay o Bounce pode causar vários erros .... tem delay nesse código ?

 

 

O delay acontece com o decremento dos registradores antdeb  e antdeb2.

Postado

Não ira funcionar como esperado.

antdeb deve ser um registro de 8 bits,ele só é zerado quando passa de 255(decfsz antdeb,f (decrementa o registro,pule se zero  )

 

 if(!bot0){while(antdeb--);} //se botão pressionado,aguarde contagem de 0 255

 

Postado
38 minutos atrás, Maria Cristina Oliveira disse:

 

O delay acontece com o decremento dos registradores antdeb  e antdeb2.

 

Isso deve ser muito rápido... como você controla para que o atraso total seja algo entre 30 e 50 milissegundos, independente do clock de seu microprocessador ?

 

Paulo

Postado
12 minutos atrás, aphawk disse:

Isso deve ser muito rápido... como você controla para que o atraso total seja algo entre 30 e 50 milissegundos, independente do clock de seu microprocessador ?

 

Sempre uso o clock de 4Mhz e o decremento vai somando o tempo de cada instrução. 

Postado

Tem algo estranho no seu ASM,o que esta postado faz assim;



main:
      btfsc    bot0                                   ; testa botão se zero
      goto     bot0lib                               ; se não for zero va para bot0lib?
      decfsz antdeb,f                             ; se pressionado, decrementa filtro (de zero a 255)
      goto     main                                   ;antdeb não é zero, volta para main
      decfsz antdeb2,f                           ; se acabou filtro 1, inicia filtro 2
      goto     main                                   ; volta para main
      goto     bot0pres                            ; vai para bot0pres
bot0lib:
      goto main
bot0pres:

-----------

 

Postado
20 minutos atrás, vtrx disse:

Não ira funcionar como esperado.

antdeb deve ser um registro de 8 bits,ele só é zerado quando passa de 255(decfsz antdeb,f (decrementa o registro,pule se zero  )

 

Oi:

Acompanhe a execução do programa passo a passo ( "gotos") e vai somando o tempo de cada instrução que fica mais fácil de entender. Não testei ainda mas acho que vai funcionar corretamente porque faz exatamente o que o outro código faz em ASM. 

Postado

A menos que esteja dentro de um loop,"if(!bot0) antdeb –-;" antdeb só é decrementado uma vez aqui,ja no ASM ele é decrementado até zerar.

Se voce esta usando CCS,é só olhar o ASM que este código em C gerou e comparar.

Qual o comportamento que deseja quando aperta o botão e quando libera?

Postado
11 minutos atrás, vtrx disse:

A menos que esteja dentro de um loop,"if(!bot0) antdeb –-;" antdeb só é decrementado uma vez aqui,ja no ASM ele é decrementado até zerar.

 

Espera aí.... Deixe eu pensar um pouco...

 

enquanto o antdeb não é zero, tem o loop do else {goto main}

 

Está tentando me confundir??????????????????(_( 

 

Brincadeira...👍

Postado

Tenta aí e poste o resultado.

Aí está uma ideia que é fácill em ASM mas 'complicado' em C.

Isso aqui não resolveria?

while(!bot0);		//enquanto botão não é pressionado(=0)fica aqui
while(!antdeb--);       //foi pressionado fica aqui diminuindo de 1 antdeb até ser = 0
...

 

Postado
23 minutos atrás, vtrx disse:

Tenta aí e poste o resultado.

Aí está uma ideia que é fácill em ASM mas 'complicado' em C.

Isso aqui não resolveria?



while(!bot0);		//enquanto botão não é pressionado(=0)fica aqui
while(!antdeb--);       //foi pressionado fica aqui diminuindo de 1 antdeb até ser = 0
...

 

 

Nunca vi um código anti-debounce assim. Se resolver seria muito bom. Mas acho que não funciona...🙄

 

42 minutos atrás, vtrx disse:

Qual o comportamento que deseja quando aperta o botão e quando libera?

image.png.59410cacfbe8c838f0db73fdeff3caea.png

 

 

 

23 minutos atrás, vtrx disse:

Tenta aí e poste o resultado.

Aí está uma ideia que é fácill em ASM mas 'complicado' em C.

Isso aqui não resolveria?



while(!bot0);		//enquanto botão não é pressionado(=0)fica aqui
while(!antdeb--);       //foi pressionado fica aqui diminuindo de 1 antdeb até ser = 0
...

 

Esse é um trabalho para o nosso amigo sumido @.if resolver...  😁

Postado

@Maria Cristina Oliveira ,

 

Eu escrevi código de debouce para Z80, 6502 e AVR, todos sempre em.Assembly ( ultimamente em Basic kkk ) desde 1984 .... e sempre usei uma função de delay dela que era independente do clock do processador, bastava informar ao assembler qual era o clock usado em Mhz e meu código fazia a aproximação melhor. Eu também sempre facilitava o trabalho ao padronizar no máximo 3 frequências diferentes de clock para os projetos.

 

Profissionalmente não dá para deixar isso ao ponto de depois de escrever querer fazer contas com incrementos e decrementos e mudando a quantidade deles para obter um tempo adequado.

 

Por exemplo esse código original que rodava bem no PIC, normalmente o clock é de 4 Mhz,  e como os Pics antigos são relativamente lentos, talvez esse delay chegasse a uns 20 mseg, o que serve quando o botão é novo... mas quando o botão fica mais usado e antigo, o desgaste e oxidação fazem ocorrer Bounces maiores, e eu sempre usei um mínimo de 40 mseg para garantir.

 

Hoje nem perco tempo, faço como escreví logo no começo do tópico, espero um tempo fixo e leio de novo o botão.

 

Mas acho que deveria pensar no seu caso em uma rotina de delay de tempo fixo, para garantir o resultado.

 

Faz um bom tempo, creio que uns 10 anos, fizemos um tópico explicando sobre o DEBOUNCE e expusemos várias técnicas de eliminar, algumas de hardware e algumas de software, pois alguns adoram usar interrupções  para tratar isso, umas causadas pelo botão mesmo, e outras usando um Timer que analisa o estado de todos os botões. 

Pode fazer uma pesquisa no Fórum, ok ?

 

Paulo

  • Curtir 1
  • Membro VIP
Postado

Uma técnica frankstein filha da do Paulão com o amigo @vtrx sujeita à melhorias mas tem algo pra dar certo é algo como:

unsigned int tempo=0;
while(!bot && (tempo<10000)	//ajuste pra sua realidade	
	{
	tempo++; //tempo time out
	if (bot) tempo=0; //se tiver repique recomeça
//	while (!bot); //tire o dedo do botão
	}

Carece de teste prático, personalizações, aprimoramentos e tal

  • Curtir 1
  • Amei 1
  • Haha 1
  • Membro VIP
Postado

A ideia foi esta mesma. Lembrando que está comentado portanto sujeito a melhorias, ajustes, atualizações e tal

Se quiser testar ..."descomente" kk

  • Amei 1
Postado

 

4 horas atrás, .if disse:

unsigned int tempo=0; while(!bot && (tempo<10000) //ajuste pra sua realidade { tempo++; //tempo time out if (bot) tempo=0; //se tiver repique recomeça // while (!bot); //tire o dedo do botão }

 

unsigned int tempo=0;

while(!bot && (tempo<10000))    //ajuste pra sua realidade    
    {
    tempo++;                 //tempo time out
    if (bot) tempo=0;        //se tiver repique recomeça     
          }
while (!bot);            //tire o dedo do botão
 

 

 

 

 

 

Excelente filtro anti-debounce, amigo!:thumbsup:

Vou testar, mas sei que vai funcionar!

Meus filtros são em  ASM, mas eu estava precisando de um bom filtro na linguagem C. 😪

 

 

 

Postado

@.if ,

 

Só para lembrar que creio que fomos eu, você e o @vtrx  que comentamos mais sobre os Debounce já naqueles idos de 2010. Ah, e o saudoso Soschip  também  ( era esse o nick ??? ) .

 

Estamos ficando idosos aqui no CDH ....

 

Paulo

Postado
3 horas atrás, aphawk disse:

@.if ,

 

Só para lembrar que creio que fomos eu, você e o @vtrx  que comentamos mais sobre os Debounce já naqueles idos de 2010. Ah, e o saudoso Soschip  também  ( era esse o nick ??? ) .

 

Estamos ficando idosos aqui no CDH ....

 

Paulo

Posta o link para eu lembrar quando era feliz...

  • Haha 1
Postado
13 horas atrás, Maria Cristina Oliveira disse:

Excelente filtro anti-debounce

 

Epa! Só mais uma coisinha...

Eu estava falando errado o tempo todo.:oops:

 

"Todas as chaves mecânicas possuem um comportamento indesejável chamado “bouncing“, mas existem várias formas de “debounce” para resolver esse problema."

 

Ou seja, anti-debounce  não existe (anti-bouncing = debounce).

Desculpem nossa falha... 😪

 

(Droga! O título do post vai ficar errado pra sempre! Não dá para mudar...:wacko: 

Agora vou ter que inventar um filtro anti-debounce para justificar o título...)

 

Postado
2 horas atrás, Maria Cristina Oliveira disse:

Agora vou ter que inventar um filtro anti-debounce para justificar o título...

 

Bem...

 

Como eu não costumo "dar essas mancadas" (filtro anti-debounce), em minha defesa citarei a fonte:

 

Livro:  Microcontroladores PIC - Teoria e Montagens Práticas
           Prof. Eng. Geraldo Carvalho
           Editora Eltec

Página 66, tópico : 4.8 - Filtros Anti De-bounce

 

(Não vou assumir sozinha...😁   )

 

OBS: Fora isso, o livro é muito bom! Aprendi muita coisa com ele (comprei na Santa Efigênia).

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

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!