Página 1 de 1

Como implementar uma rotina

MensagemEnviado: 17 Dez 2007 18:51
por Canabrava
Pessoal!
Boa noite

Estou muito tempo sem postar, mas estou sempre dando uma lida nos tópicos.

Estou com dificuldade em implementar uma rotina, para uma aplicação muito usada.

1)-Tenho 02 botões, sendo um para "INCREMENTAR" outro para "DECREMENTAR”.

2)-Quando pressiono um dos botões, um valor de 0 a 65535 (16bits) é "Incrementado" ou "Decrementado" e é mostrado em um LCD 16x2.

3)- Uso um delay alto, na casa de 200mS para evitar o efeito "debounce"
e o ato de pressionar e soltar uma das teclas ocasiona apenas um "incremento" ou "Decremento".

4)- Eu queria implementar esta rotina para que se eu pressionasse por exemplo a tecla "Incremento" e a mantivesse pressionada, o contador seria incrementado continuamente , inicialmente no delay inicial que é de 200mS, depois este delay iria diminuindo gradativamente , tal que a velocidade de incremento iria aumentando de tal forma a atingir a casa das "Dezenas de Milhar" rapidamente. Soltando a tecla e voltando a pressioná-la novamente recomeça o processo, inicialmente lento e depois rápido.

Alguém já implementou uma rotina deste tipo antes e pode me dar uma "luz" de como fazer isso?

Conheço quase nada de "C" , mas uma dica em qualquer linguagem é bem vinda.

Obrigado!

MensagemEnviado: 17 Dez 2007 23:01
por Iran
Olha aí um exemplo em Assembly.

No caso é um contador Up Down de 0 a 99 com uma tecla para incrementar e outra pra decrementar. Qdo a tecla é mantida pressionada a contagem Incrementa /Decrementa automaticamente só que com velocidade constante.

;**********************************************************************************
; Este programa inplemeta um contador de 0 a 99. Na porta P2 estão ligados dois *
; displays de 7 seg. anodo comum, multiplexados através dos pinos P0.6 e P0.7. *
; ativos em nível baixo. Na porta P3.2 e P3.3 dois push buttons que cada vez *
; que pessionado faz a contagem no display ser decrementada. Um buzzer na *
; porta P1.0 soa cada vez que o push button é pessionado. Quando o botão é *
; mantido pressionado a contagem é incrementada automaticamente. *
; *
; Frequencia de clock = 19.5Mhz *
; *
; *
; *
;******************************************************************************

.titl 'Contador Up/Down de 0 a 99'

.include '89s8252.inc'


pontu .define 002h ; Ponteiro para a unidade na tabela de códigos
pontd .define 003h ; Ponteiro para a dezena na tabela de códigos
cont1 .define 030h ; Contador 1 para a função delay
cont2 .define 031h ; Contador 2 para a função delay
cont3 .define 032h ; Contador 2 para a função delay
unid .define 034h ; Variavel codigo das unidades
deze .define 033h ; Variavel codigo das dezenas

display .equ P2 ; saida para o display
dispu .equ P0.6 ;
dispd .equ P0.7 ;
beep .equ P1.0 ; Saida para o buzzer
menos .equ P3.2 ; Tecla menos
mais .equ P3.3 ; Tecla mais

zero .equ 021h ;
nove .equ 003h ;


;------------------------------------------------------------------------------
; Seguimento de Jumps
;------------------------------------------------------------------------------


.aseg jump_seg,code ;

.org 0000h ;

ajmp inicio ; jump para o início do programa

.org 0003h ;

ajmp decre ; jump para rotina de tratamento de interrupção externa 1

.org 0013h ;

ajmp incre ; jump para rotina de tratamento de interrupção externa 1


;------------------------------------------------------------------------------
; Programa principal
;------------------------------------------------------------------------------

.rseg programa,code

inicio: mov .byte pontu,#000h ; iniciliza o ponteiro de unidades
mov .byte pontd,#000h ;
mov .byte unid,#zero ;
mov .byte deze,#zero ;
mov dptr,#itab ; inicializa ponteiro da tabela
setb it0 ; define interrupção 0 na borda
setb it1 ; define interrupção 1 na borda
mov ie,#005h ; habilita interrupção global e externa 0 e 1
espera: acall mux ; chama sub-rotina
setb ea
sjmp espera


;------------------------------------------------------------------------------
; Função de multiplexação dos displays
;------------------------------------------------------------------------------

mux: clr ea ; desabilita interrupçãoe
setb .bit dispu ; habilita display de unidades
mov display,.byte unid ; excita display de unidades
acall delay ; chama atraso
clr .bit dispu ; desabilita display de unidades
setb .bit dispd ; habilita display de dezenas
mov display,.byte deze ; excita display de dezenas
acall delay ; chama atraso
clr dispd ; desabilita display de dezenas
ret ; retorna da sub-rotina


;------------------------------------------------------------------------------
; Função de incremento da contagem
;------------------------------------------------------------------------------

.func incre

clr beep ; aciona o beep
inc .byte pontu ; ponteiro aponta pro póximo codigo na tabela
mov a,.byte pontu ;
clr c ;
subb a,#00ah ; testa se chegou no fin da tabela
jz segue1 ; se sim, reinicializa o contador
mov a,.byte pontu ;
movc a,@a+dptr ; busca novo código
mov .byte unid,a ; aciona display
sjmp sai1 ;
segue1: mov .byte pontu,#000h ; reinicialia ponteiro
mov .byte unid,#zero ; mostra 0 no display
inc .byte pontd ;
mov a,.byte pontd ;
clr c ;
subb a,#00ah ;
jz segue2 ;
mov a,.byte pontd ;
movc a,@a+dptr ; busca novo código
mov .byte deze,a ; aciona display
sjmp sai1 ;
segue2: mov .byte pontd,#000h ; reinicialia ponteiro
mov .byte deze,#zero ; mostra 0 no display
sai1: mov .byte cont3,#10
repete0: acall mux
djnz .byte cont3,repete0
setb beep ; para o beep
mov .byte cont3,#40 ;
repete1: acall mux
djnz .byte cont3,repete1
jnb mais,incre ; testa se tecla ainda está pessionada
clr ie1
reti ; sai da interrupção
.endf


;------------------------------------------------------------------------------
; Função de decremento da contagem
;------------------------------------------------------------------------------

.func decre

clr beep ; aciona o beep
dec .byte pontu ;
mov a,.byte pontu ;
cjne a,#0ffh,segue3 ;
sjmp segue4 ;
segue3: mov a,.byte pontu ;
movc a,@a+dptr ; busca novo código
mov .byte unid,a ; aciona display
sjmp sai2 ;
segue4: mov .byte pontu,#(ftab-itab) ; reinicialia ponteiro
mov .byte unid,#nove ; mostra 0 no display
dec .byte pontd ;
mov a,.byte pontd ;
cjne a,#0ffh,segue5 ;
sjmp segue6 ;
segue5: mov a,.byte pontd ;
movc a,@a+dptr ; busca novo código
mov .byte deze,a ; aciona display
sjmp sai2 ;
segue6: mov .byte pontd,#(ftab-itab) ; reinicialia ponteiro
mov .byte deze,#nove ; mostra 0 no display
sai2: mov .byte cont3,#10
repete2: acall mux
djnz .byte cont3,repete2
setb beep ; para o beep
mov .byte cont3,#40 ;
repete3: acall mux
djnz .byte cont3,repete3
jnb menos,decre ; testa se tecla ainda está pessionada
clr ie0
reti ; sai da interrupção

.endf

;------------------------------------------------------------------------------
; Função de atraso de tempo
;------------------------------------------------------------------------------

.func delay

mov .byte cont1,#010h ; inicializa variável
volta: mov .byte cont2,#0fch ; inicializa variável
loop: djnz .byte cont2,loop ; decrementa até chegar a zero
djnz .byte cont1,volta ; decrementa até cont 1 e 2 chegarem a zero
ret ; retorna da sub rotina
.endf

;------------------------------------------------------------------------------
; Tabela de códigos para o display
;------------------------------------------------------------------------------

itab: .dcb 021h ; Codigo para o 0
.dcb 077h ; Codigo para o 1
.dcb 019h ; Codigo para o 2
.dcb 013h ; Codigo para o 3
.dcb 047h ; Codigo para o 4
.dcb 083h ; Codigo para o 5
.dcb 081h ; Codigo para o 6
.dcb 027h ; Codigo para o 7
.dcb 001h ; Codigo para o 8
ftab: .dcb 003h ; Codigo para o 9 ; Codigo para o 9

.end

MensagemEnviado: 18 Dez 2007 06:32
por Canabrava
Obrigado Iran!

Com velocidade constante eu já consegui fazer usando aquele delay de 200mS que eu mencionei. O meu desafio é ir diminuindo este delay gradativamente.

MensagemEnviado: 18 Dez 2007 06:44
por ze
Pode ser que funcione, (ou não)
Código: Selecionar todos
void inc_dec(void)
{
char ttp;//tempo de tecla pressionada
if ((tecla==incrementa) || (tecla==decrementa))
   {
   if (ttp++>5) {delay(50);ttp=6;} //se manter pressionado por + de 1Seg, delay=50mS
   }
else    {
   ttp=0; delay(200); //durante o primeiro segundo, delay=200mS
   }

.... //incementa ou

.... //decrementa o que quiser


}   


colocando switch/case em ttp pode decrementar delay.
Se tiver erros/[dúvidas] e quiser postar, fique a vontade.

Feliz Natal!