Página 1 de 2
Timer Infinito no pic16f877a

Enviado:
23 Jan 2010 15:08
por Francys Reymer
Olá pessoal, preciso de um timer infinito (como se fosse um relógio) no pic16f877a, já implementei o timer0 e o timer2, também dei uma estudada no timer1 porém estes timers vc tem q predefinir o valor até onde ele vai contar, precisaria de uma rotina em assembly q fizesse isso...

Enviado:
23 Jan 2010 15:18
por ze
amigo coloca assembly no título do post pra filtrar o tipo de ajudante e principalmente pra eu não perder meu tempo clicando.
obrigado!

Enviado:
23 Jan 2010 16:36
por Djalma Toledo Rodrigues
Use Interrupção e Recarga
isso se for valor parcial
DJ

Enviado:
23 Jan 2010 16:40
por Francys Reymer
como assim interrupção e recarga poderia me dar um exemplo?

Enviado:
23 Jan 2010 20:13
por Andre_Cruz
Francys Reymer,
Interupção e recarga, funciona assim:
1) Você escolhe com qual timer vai trabalhar, timer0, timer1 ou timer2.
2) Configura o timer, para gerar interupção acada XmS.
3) Cada vez que ocorrer um interupção do timer selecionado, você sabe que passou XmS, e incrementa um variavel.
Por exemplo.
1) Você escolheu o Timer 0.
2) O timer 0 gera uma interupção a cada 100 mS.
Para contar um segundo, você precisa de 10 interupções.
Você pode criar uma variavel que fará tipo um prescaler, cada vez que entrar na interupção do timer 0 você usa a instrução
DECFSZ variavel_prescaler,F
GOTO SAI
;RECAREGA A VARIAVEL
;CHEGA AQUI QUANDO ATINGI 1 SEGUNDO
Usando essa lógica você consegue, criar um relógio.
Passa mais detalhes desse seu contador, permite uma resposta mais clara.
Abraço
André

Enviado:
23 Jan 2010 20:40
por Djalma Toledo Rodrigues
SE você quer aprender, mas aprender mesmo, não é exemplo o melhor caminho.
Veja, estude, Datasheet Contador Programável TTL ou CMOS
DJ

Enviado:
24 Jan 2010 12:45
por Vonnilmam
O lellis PEGA LEVE! TÁ NERVOSO VAI "PESCAR"
Aquí é um site de ajuda sobre mcus pic, não importa se o cidadão programa em assembler ou outra linguagem! No final dá tudo na mesma, mesmo...
Então faz assim com o andré indicou, aquí vai uma dica prática:
; ***************************************************************
; * PROJECT BY........: Vonnilmam *
; * DATA E REVISÃO....: 25/01/2009 - 23:12 / xx-xx-xx *
; * CLOCK.............: EXTERNO DE 20.000.000 HZ *
; * CRISTAL MCU.......: 20.000.000 HZ *
; * ANDAMENTO.........: APROVADO *
; ***************************************************************
; TABELA DE FRQ COM ESCALA LINEAR DE 49 STEPS
; ESSA VERSÃO UTILIZA O TIMER 1 (16BITS)
;-----------
__config b'00000100000010' ; 014F
; 0000---------- [CP1:0] Code Protection 1 = OFF
; ----0--------- --- * ---
; -----1-------- [CPD] Data Code Protection 0 = OFF
; ------0------- [LVP] Low Voltage Programming 0 = OFF
; -------1------ [BODEN] Brown-out Detect 0 = OFF
; --------0----- [MCLRE] RA5/MCLR pin function select = RA5
; ----------0--- [PWRTE] Power-up Timer disable
; -----------0-- [WDTE] Watchdog Timer disable
; ---------0--10 [FOSC2:0] HS, pin15 = pin16 = HighSpeedCrystal
;-----------
ERRORLEVEL -302, -306
#INCLUDE <P16F628.INC>
#INCLUDE <RAM.INC>
#INCLUDE <DEFINE.INC>
#INCLUDE <MACROS.INC>
#include <Ramclear.inc>
;---------------
ORG 00H
CLRF PCLATH
GOTO SETUP
ORG 04H
INT_TMR1:
MOVWF W_TEMP ; salva o conteúdo do w em w_temp
SWAPF STATUS, W ; salva o conteúdo do status ...
MOVWF STATUS_TEMP ; ... em status_temp
INCF PORTA, F ; A0=2",A1=4",A2=8",A3=16" PÉS...
;
BTFSC ANT_RELOAD ; BLOQUEIRA ATUALIZAÇÃO DOS
GOTO NOT_RELOAD ; REGISTROS DE CONTAGEM
;
MOVF TEMP_LSB, W
MOVWF RELOAD_LSB
MOVWF TMR1L
MOVF TEMP_MSB, W
MOVWF RELOAD_MSB
MOVWF TMR1H
BCF PIR1, TMR1IF ; APAGA FLAG DE INTERRUPÇÃO
SWAPF STATUS_TEMP, W ; restaura o conteúdo do ...
MOVWF STATUS ; ... registrador status
SWAPF W_TEMP, F ; restaura o conteúdo ...
SWAPF W_TEMP, W ; ... do registrador w
RETFIE
NOT_RELOAD:
MOVF RELOAD_LSB, W
MOVWF TMR1L
MOVF RELOAD_MSB, W
MOVWF TMR1H
BCF PIR1, TMR1IF ; APAGA FLAG DE INTERRUPÇÃO
SWAPF STATUS_TEMP, W ; restaura o conteúdo do ...
MOVWF STATUS ; ... registrador status
SWAPF W_TEMP, F ; restaura o conteúdo ...
SWAPF W_TEMP, W ; ... do registrador w
RETFIE
;---------------
#INCLUDE <FRQTON.INC>
ORG .256
;---------------
#INCLUDE <Ponteiro.INC>
;---------------
#INCLUDE <BOOT.INC>
;---------------
CLRF PORTA
CLRF BANDEIRA_1
BCF INTCON, GIE
BCF T1CON, T1CKPS0 ; PRESCALER 1/1=00 * 1/2=10 * 1/4=01 * 1/8=11
BCF T1CON, T1CKPS1 ; ...
BCF T1CON, T1OSCEN ; OSC INTERNO DISABLE
BSF T1CON, NOT_T1SYNC ; TIMER ASSINCRONO
BSF T1CON, TMR1CS ; CKL EXTERNO VIA T1OSO (RB6)
BCF T1CON, TMR1ON ; TIMER DISABLE
BCF PIR1, TMR1IF ; FLAG DE INTERRUPÇÃO
BSF STATUS, RP0
BSF PIE1, TMR1IE ; HABILITA INTERRUPÇÃO TIMER 1
BCF STATUS, RP0
BSF INTCON, GIE
BSF INTCON, PEIE ; INTERRUPÇÕES PERIFERICAS ENABLE
BSF T1CON, TMR1ON ; ENABLE TIMER 1
;---------------
INICIO:
;---------------
Essa rotina é um fragmento de um programa que faz o pic um timer counter programável desde 1 htz até 16khz, quero lembrar que o timer do pic ou de qualquer outro mcu de 8 bts não possui uma precisão exata, isso é devido ao fato de a recarga do timer ser feita através de software, a recarga ideal seria via hardware com o reload automático, e essa função só tem no timer 0 se não estou enganado e só no modo de 8 bits...
Dependendo da aplicação eu aconcelho utilizar um clock externo, se no caso de um relógio por exemplo utilize um chipset específico para isso...

Enviado:
24 Jan 2010 13:44
por vtrx
O Lellis não ta nervoso não,apenas não tem informações suficiente para ajudar...

Enviado:
24 Jan 2010 15:01
por Francys Reymer
desculpe djalma mas li o datasheet do 16f877a e ñ vi nada sobre recarga lá.
lellis da proxima vez faço isso, é q sou novato aqui e ñ sabia pode ficar tranquilo.
obrigado vonnilman, mas prefiro utilizar o timer2 que é mais simples de implementar, só reforçando que estou utilizando apenas clock interno. é q no projeto estou utilizanndo 2 ldr's quando a luz diminuir no 1º ldr o timer ira ativar e ira parar quando a luz diminuir no 2º ldr, este tempo deverá ser transmitido a outro mcu.
;//FUNCAO QUE ATIVA O TIMER2 PARA CONTAR 20us
TIMER2_20us
BANK1;
MOVLW D'20';
MOVWF PR2; CONTA 20us
BANK0;
CLRF TMR2; LIMPANDO TIMER2
MOVLW B'0000100';
MOVWF T2CON; TIMER2 HABILITADO E CONFIGURADO O PRESCALER EM 1:1
BTFSS PIR1,TMR2IF; TERMINOU TEMPO?
GOTO $-1; NAO, VOLTA E CONTINUA TESTANDO
MOVLW B'0000000';
MOVWF T2CON; SIM, TIMER2 DESABILITADO
BCF PIR1,TMR2IF; LIMPA FLAG
RETURN;

Enviado:
24 Jan 2010 22:55
por Vonnilmam
num entendi, mas eu acho que tanto faz vc utilizar o timer 1 ou 2, em todo o caso, fica aí uma boa rotina de timer....

Enviado:
03 Fev 2010 20:14
por Francys Reymer
vonnilman, kra eu ñ entendi algumas coisas nesse seu código, da erro, por exemplo:
";
BTFSC ANT_RELOAD; BLOQUEIRA ATUALIZAÇÃO DOS
GOTO NOT_RELOAD; REGISTROS DE CONTAGEM
;"
"NOT_RELOAD: "
"CLRF PORTA
CLRF BANDEIRA_1 "

Enviado:
03 Fev 2010 22:59
por Vonnilmam
Me desculpe colega,
É que esse treco é um fraguimento de um programa que realiza a geração de frequencia para a escala musical, por isso do "incf portA"...
Segue agora bem mastigadinho para vc entender, note que utilizo o mode de interrupção no timer1, aliás tanto faz o timer 1 ou 2...a recarga de ser feita por software já que via hardware a microchip pisou na bola!
Em relação ao ant_reload é afim de acertar os erros que esse ou outro timer de mcus de 8 bits realizam ao perder tempo quando recarregados via software, sendo assim esse flag ant_reload compara a frequencia anterior que a frequencia nova e caso sejam iguais não atualiza o timer, enfim deixa isso para lá, presta a atenão abaixo:
OBSERVA QUE EU ESTOU HABILITANDO O CLOCK PARA VIR EXTERNAMENTE, CASO DESEJE UTILIZAR O CLOCK DO MCU DIRECIONE O CONFIG PARA ISSO.
AS VARIAVEIS TEMP_LSB E _MSB DEVEM SER PREVIAMENTE CARREGADAS NO MAIN "LOOP" DO SEU PROGRAMA TRATA-SE DO VALOR DE RECARGA DO TIMER.
COMO O ILUSTRE FABIN DIZ: MOLEZA MAIOR NUM EXISTE!
;---------------
ORG 00H
CLRF PCLATH
GOTO SETUP
ORG 04H
INT_TMR1:
MOVWF W_TEMP ; salva o conteúdo do w em w_temp
SWAPF STATUS, W ; salva o conteúdo do status ...
MOVWF STATUS_TEMP ; ... em status_temp
;
MOVF TEMP_LSB, W
MOVWF TMR1L
MOVF TEMP_MSB, W
MOVWF TMR1H
BCF PIR1, TMR1IF ; APAGA FLAG DE INTERRUPÇÃO
SWAPF STATUS_TEMP, W ; restaura o conteúdo do ...
MOVWF STATUS ; ... registrador status
SWAPF W_TEMP, F ; restaura o conteúdo ...
SWAPF W_TEMP, W ; ... do registrador w
RETFIE
;---------------
BCF INTCON, GIE
BCF T1CON, T1CKPS0 ; PRESCALER 1/1=00 * 1/2=10 * 1/4=01 * 1/8=11
BCF T1CON, T1CKPS1 ; ...
BCF T1CON, T1OSCEN ; OSC INTERNO DISABLE
BSF T1CON, NOT_T1SYNC ; TIMER ASSINCRONO
BSF T1CON, TMR1CS ; CKL EXTERNO VIA T1OSO (RB6)
BCF T1CON, TMR1ON ; TIMER DISABLE
BCF PIR1, TMR1IF ; FLAG DE INTERRUPÇÃO
BSF STATUS, RP0
BSF PIE1, TMR1IE ; HABILITA INTERRUPÇÃO TIMER 1
BCF STATUS, RP0
BSF INTCON, GIE
BSF INTCON, PEIE ; INTERRUPÇÕES PERIFERICAS ENABLE
BSF T1CON, TMR1ON ; ENABLE TIMER 1
;---------------
INICIO:
;---------------
MAIN:

Enviado:
04 Fev 2010 03:31
por Francys Reymer
observe o q estou fazendo apenas adaptei esse seu código para o timer 2:
INT_TMR2
MOVWF W_TEMP; salva o conteúdo do w em w_temp
SWAPF STATUS,W; salva o conteúdo do status ...
MOVWF STATUS_TEMP; ... em status_temp
MOVLW D'04';
MOVWF PR2; CONTA DE 1us EM 1us
INCF CONT,F;
BCF PIR1,TMR2IF; LIMPA FLAG DE INTERRUPÇÃO
SWAPF STATUS_TEMP,W; restaura o conteúdo do ...
MOVWF STATUS; ... registrador status
SWAPF W_TEMP,F; restaura o conteúdo ...
SWAPF W_TEMP,W; ... do registrador w
RETFIE
quando tento incrementar a variável CONT ele ñ incrementa, o q devo fazer?

Enviado:
04 Fev 2010 07:31
por Andre_Cruz
Francys Reymer,
Antes de colocar sua lógica dentro da interupção, experimenta testar pra ver se esta entrando na interupção, e não esqueça de limpar o flag que gerou a interupção.
Os registradores de configuração do TIMER2 estão configurados corretamente ?
Ja precisei gerar uma interupção a cada de 10 uS, usei clock externo de 20MHz, você precisa de 1 uS ??
Abraço
André

Enviado:
04 Fev 2010 17:26
por Francys Reymer
eu testei no proteus ele funcionou, entrou na interrupçao só ñ incrementa o meu CONT dentro da interrupção, bom vou tentar explicar o melhor possível do q estou tentando fazer, acho q me confundi na hora de explicar agora q entendi como funciona o esquema da interrupção e recarga, acho q sei o q realmente preciso, me acompanhem:
1º meu circuito é constituido de 2 ldr (sensor q aumenta a resistencia conforme incide a luz sobre ele) ligados ao meu pic16f877a.
2º quando a luz incide sobre o primeiro ldr a tensão diminuirá no meu conversor a/d e quando essa tensão chegar a um nível q eu determinei o timer2 irá ativar e começará a contar.
3º quando a luz incidir no segundo ldr a tensão diminuirá no meu conversor a/d e quando essa tensão chegar a um nível q eu determinei o timer2 terá q parar de contar e meu programa terá q passar o tempo registrado para outro microcontrolador. o problema é q como eu iria fazer isso pois o tempo q pode levar para a luz incidir de 1 ldr para o segundo seria indeterminado (mas ñ q eu queria fazer um relógio em si).
4º então acho q no meu caso eu teria q carregar o valor máximo no PR2 (registrador de 8 bits) q seria de 255 em decimal e então fazer a recarga quando houvesse interrupão e incrementar a minha variável CONT (para saber a quantidade exata de tempo) caso ñ tenha ocorrido incidencia de luz ainda no segundo ldr. o tempo q eu determinei é de 1 us, ñ sei se seria o tempo mais correto pois mesmo ñ sabendo quanto tempo exato isso demoraria eu sei q seria muito rápido, acho q talvez seja uma questão de millisegundos.
mas o caso é q o incremento da minha variável CONT ñ funcionou, mesmo o meu timer2 funcionado de boa e entrando na interrupçao, será q tenho fazer algo diferente?