Como implementar uma rotina

Software e Hardware para linha x51

Moderadores: 51, guest2003, Renie, gpenga

Como implementar uma rotina

Mensagempor Canabrava » 17 Dez 2007 18:51

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!
ABRAÇOS!
--------------------
Canabrava
Avatar do usuário
Canabrava
Bit
 
Mensagens: 14
Registrado em: 18 Nov 2006 16:50

Mensagempor Iran » 17 Dez 2007 23:01

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
Avatar do usuário
Iran
Word
 
Mensagens: 558
Registrado em: 16 Out 2006 18:10
Localização: Imperatriz - MA

Mensagempor Canabrava » 18 Dez 2007 06:32

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.
ABRAÇOS!
--------------------
Canabrava
Avatar do usuário
Canabrava
Bit
 
Mensagens: 14
Registrado em: 18 Nov 2006 16:50

Mensagempor ze » 18 Dez 2007 06:44

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!
Avatar do usuário
ze
Dword
 
Mensagens: 1655
Registrado em: 05 Jun 2007 14:32


Voltar para 8051

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

x