Ir ao conteúdo

Como contar 1s com timer1 PIC16F628?


Fervolt

Posts recomendados

Postado

Boa noite,

Já tentei bastante e já procurei no google, mas não encontrei solução para minha dúvida. Espero que aqui alguém possa me ajudar. :D

Seguinte:

Estou montando um conta-giros com PIC16F628 e 4 displays de 7 seg multiplexados.

Configurei o timer0 para captar os pulsos através do pino RA4, e esta funcionando.

Com o timer1 eu preciso contar o tempo de 1 segundo e depois ler o timer0 e multiplicar o valor por 60 e assim encontrar o RPM.

Meu problema está no timer1, não é possível contar 1s de uma só vez então estou tentando contar 2x de 500ms e é isso que não estou conseguindo. Posso fazer o que for, ele estoura com 500ms, vai para interrupção, mas não conta 1s, somente 500ms.

Alguém tem um exemplo de como poso fazer isso? Estou programando em assembly.

Se for o caso posso mandar o código, é bem extenso.

Grato

Fernando

Postado

Esse seu pulso, o tempo ON é igual o tempo OFF?

você pode usar o módulo CCP para que toda vez q o sinal ficar em ON você pode medir a duração do pulso, como o ON é igual ao OF, você soma os tempos e depois calcula a frequencia com 1/T.

Caso você realmente prefere usar o timer.. tenho um exemplo aqui. Faz exatamente o que você quer.

#include <16f876.h>
#fuses XT,NOWDT
#use delay(clock=4000000)
#use standard_io(

int1 cont=0;

#int_TIMER1 //Interrupción Timer1
void temp1s(void) //Función
{
if (cont==1) output_toggle(PIN_B1); //Cada 2 interrupciones de 0.5s
set_timer1 (3036); //recarga del TMR1
cont++;
}

main ()
{
setup_timer_1 (T1_INTERNAL | T1_DIV_BY_8);
set_timer1 (3036); //recarga del TMR1
enable_interrupts(INT_TIMER1); //habilita interrupcion timer1
enable_interrupts(global); //habilita interrupción general

while(1);
}

Falou

Postado

Se está programando em Assembly, posso ajudar.

Utilize um registrador para contar 2 interrupções do Timer 1.

Na rotina de interrupção do Timer 1, utilize a instrução DECFSZ para decrementar este registrador e testar se o resultado é 0.

Se o resultado for 0, você reinicializa o registrador com o valor 2 e faz a multiplicação por 60 para calcular o RPM.

Se o resultado não for 0, você sai da interrupção.

Postado

MatheusLPS,

Não, os tempos não são iguais, esse conta-giros será usado numa maquina de usinagem, preciso saber qual a rotação do eixo-árvore, então, vou colocar 6 imãs (neodímio ø4mm x 5mm alt.) dispostos a 60° no eixo e captar os pulsos com um sensor hall. No protótipo ja consigo contar os pulsos com o timer0, mas o período em que ele está contando os pulsos é de 500ms e preciso que seja 1s.

Abaixo coloquei parte do código, a parte da interrupção para facilitar o entendimento.


;------------------------------------------------------|
; INTERRUPÇÃO |
;------------------------------------------------------|
org 04h ; Vetor de interrupção

bank0 ; Confirma banco 0

btfss PIR1, TMR1IF ; Verifica se a interrupção foi de Timer1
retfie ; Se não foi, retorna

bcf PIR1, TMR1IF ; Limpa flag de int timer1

movwf W_TEMP ; Salva ambiente
movfw status
movwf STATUS_TEMP

decfsz aux3 ; Verifica quantas vezes o timer1 estourou
goto $+2
goto continua

bcf INTCON, GIE ; Desliga todas as interrupções
bcf T1CON, 0 ; Desliga Timer1
movlw low (.65536 - .62500) ; Valor Timer1 = 65536 - 62500 = 3036
movwf TMR1L
movlw high (.65536 - .62500)
movwf TMR1H

movf STATUS_TEMP, w ; Restaura ambiente de antes da Int
movwf STATUS
movf W_TEMP, w

bsf INTCON, GIE ;Liga todas as interrupções
bsf T1CON, 0 ;Liga Timer1

retfie

continua:
; Rotina de divisão
; Rotina de multiplicação por 60
movf TMR0, w
movwf VLL
call prepara_conversao
call converte_VLH
call converte_VLL
call transforma

bcf INTCON, GIE ;Desliga todas as interrupções
bcf T1CON, 0 ;Desliga Timer1
movlw low (.65536 - .62500) ;Valor inicial Timer1 = 65535 - 62500 = 3036
movwf TMR1L
movlw high (.65536 - .62500)
movwf TMR1H

movlw .2
movwf aux3 ; Carrega variável auxiliar com .2
clrf tmr0 ; zera Timer0

movf STATUS_TEMP, w ; Restaura ambiente de antes da Int
movwf STATUS
movf W_TEMP, w

bsf INTCON, GIE ;Liga todas as interrupções
bsf T1CON, 0 ;Liga Timer1

retfie

Obrigado

Fernando

Postado
Fervolt, não é necessário indicar o destino do resultado da instrução decfsz aux3?

Ou seja, não teria que ser assim:?

decfsz aux3,1

Mulder_Fox,

Acho que era isso mesmo! :unsure:

Compilei novamente e simulei no protheus, eu sei que não é certo, mas parece que está funcionando agora. Hoje a noite terei certeza quando gravar no PIC.

Valeu mm.

Fernando

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

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!