junho 2005 por
alvaro luiz
"O trabalho voluntário é para mim uma prece silenciosa. Deveis encontrar uma causa generosa
à qual sacrificareis tempo e dinheiro, porque é só assim que conhecereis a alegria de dar.
Mais do que vossas posses, é quando derdes de vós próprios é que realmente dareis."
(Gibran Khalil Gibran (1893 - 1931), poeta escritor e filósofo libanês)
Estudar aqui como gerar ISR com TIMER1, operando em modo COMPARE com
o CCP1, com cristal de 20MHz e gerando tempos precisos de 100ms
Importante aqui é tomarmos conhecimento que é possível dividir a freq do oscilador por qualquer
número de 1 até 65534, assim temos ajuste do tempo de ISR sem muito trabalho.
Utilizaremos o mesmo software feito na PARTE-1 com algumas modificações.
Devemos saber que neste exemplo não atuará mais PWM, poís utilizaremos o TIMER1 para atuar como
comparador e gerar a ISR.
Quem irá gerar a isr agora não é mais o overflow do timer0 e sim agora quando os valores (16 bits)
de TMR1 for igual a CCPR1. O TMR1 é o contador do TIMER1 só aqui não opera por overflow que seria
o bit bandeira TMR1F no registro PIR1 e sim o comparador que é o bit bandeira CCP1IF do mesmo registro.
Alterações:
Primeiro altera-se o valor de _CONFIG para trabalhar com cristal externo cujo valor será 20MHz
__CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF &
_HS_OSC & _LVP_OFF ;
O nome do LABEL de isr mudou para:
;
org 4
goto isr_ccp1
;
Pelo fato de aumentar a frequência de 4 para 20 MHz (5 vezes) devemos alterar o valor do
divisor gerador do baud rate para comunicação 9600bpd para o valor (129)
; ------------------------
; Set baud rate = 9600, no parity, 1 stop bit
; 20MHz usando intermo oscilador
; ------------------------
movlw .129 ;com cristal de 20MHz vide pag.72 do
movwf SPBRG ;manual assincrono BRGH=1 erro de 0,16%
;
Devemos retirar toda aquela área de inicialização de PWM, pois agora não teremos mais, e também
a habilitação de ISR TIMER0 que vem logo a seguir.
; -------------------------------------------------------
; inicializando PWM
; fazendo PWM com xlt internom de 4MHz
; a freq será = (4MHz/4)/63~15K87 HZ com timer2 prescaler=1
; exemplo reconstruido0 com algumas alterações do manual do
; 16F628 page 65 code DS40300C e do PICmicro example 14.5 PWM
; Initialization code DS31014A page 14-14
; ---------------------------------------------------------
; clrf status ;bank0
; clrf CCP1CON ;CCP module is OFF
; clrf TMR2 ;clear timer2
;
; movlw 0xff
; movwf PR2 ;fazendo periodo do PWM
; clrf CCPR1L ;inicar ativo PWM = 0%
; clrf INTCON ;para prog daqui em diante sem interrupts
; bsf status,RP0 ;bank1
; bcf TRISB,3 ;fazendo RB3 out PWM
; clrf PIE1 ;desabilitando perifico interrupts
; clrf status ;bank0
; clrf PIR1 ;clear periferico flags interrupts
; movlw 0x2c ;mode PWM
; movwf CCP1CON
;
; clrf T2CON ;prescaler 1:1 timer2=on
; bsf T2CON,TMR2ON ;start timer2 and PWM
; ============================================================
; habilitando interrupt para timer0
; ============================================================
; movlw b'10100000' ;habilita global interrupt +
; movwf INTCON ;habilita interrupt timer0 pagina 21 manual
Agora vamos ativar MODO COMPARADOR de CCP1
;
; compare mode with isr
;
clrf status ;garantir bank 0
movlw 0x0b
movwf CCP1CON ;solicitando CCP1 modo Comparador, com especial trigger
; ;veja pag.61 do manual
;
bsf T1CON,TMR1ON ;ligar TIMER1
;
bsf status,RP0 ;passar para bank 1
bsf PIE1,CCP1IE ;habilitar ISR CCP1IE comparador
;
clrf status ;voltar bank 0
movlw high(.50000) ;vamos aprender como se escreve um número em decimal e deixar que
movwf CCPR1H ; o MPLAB ajuste-o para binário
movlw low (.50000) ;primeiro a parte alta do num 50.000 para CCPR1H depois a parte baixa
movwf CCPR1L ;para CCPR1L assim temos (20Mhz/4/5000)=100Hz
;
bsf INTCON,PEIE ;habilitar isr periférico
bsf INTCON,GIE ;habilitar isr geral
O valor a ser comparado será o número 50.000, TIMER1 parte do valor 0000 quando atingir 50000 gera ISR e
se zera automáticamente, então teremos ISR na razão de 100Hz ou seja 100ms.
a chamada de sci e a sub-rotina SCI não mudam
;
st1:
call sci ;deverá sempre ser visto se tem dados pendentes
goto st1
;
;
isr_ccp1:
bsf PORTB,5
;
movwf wr ;salvar o reg W
swapf STATUS,W ;preservando de STATUS, pegamos este invertido
movwf st ;e o salvamos invertido
clrf STATUS ;aqui salvamos wr,status e FSR
movf FSR,W ;esta inscrução altera STATUS, mas este já foi salvo
movwf fsrr ;podemos salvar FSR, e deixa-lo livre para ISR usa-lo
;
; bcf INTCON,T0IF ;tirando requesição ISR,do contrário não sai mais daqui
; bcf PIR1,TMR1IF ;caso fosse ISR por overflow de TIMER1
;
bcf PIR1,CCP1IF ;tirar quem causou esta ISR
;
; =============================================================================
; ISR (aqui Interrupt Service Request) aqui deve ser colocado o serviço
; de interrupt, que nao pode ser grande, ou seja, levar mais que 20% do
; tempo entre chamadas de ISR, no caso este tempo vale
; RB5 está sendo usado como monitoração para tempo, poderá ser visto em um
; oscilóscopio.
; =============================================================================
bsf PORTB,5 ; continua sendo usado
;
movf down1,f ;vendo se donw1 é dif de zero com Z, é um modo rápido de
; ;ver se um reg é zero movendo ele para ele mesmo.
btfsc status,z ;depois o BIT Z/STATUS a instrução SKIP NEXT ADDRESS
goto int1 ;if not equ 0, então conclui-se que down1=0 e nada a fazer
;
decf down1,f ;else -> donw1 dif de zero decrementar este
;
goto int1
int1:
;
; AQUI FOI COLOCADO UM DELAY PARA SER OBSERVADO NO OSCILÓSCOPIO
; criando um tempo maior que 2000 instruções
;
;
movlw high(.500)
movwf ria
;
movlw low(.500)
movwf rib
;
wait:
nop
nop
decfsz rib,f
goto wait
;
decfsz ria,f
goto wait
;
; ===================================================
; fim do ISR reponha todos registros de forma que o operacional
; não note nenhuma modificação
;
intf:
movf fsrr,W ;repor FSR
movwf FSR
swapf st,W ;como o salvamos invertido agora o reavemos
movwf STATUS ;invertido também logo nada mudou
swapf wr,F ;e o último a ser reposto é o reg W.
swapf wr,W ;está tudo reposto
;
bcf PORTB,5
;
retfie ;retorne pegando o endereço do STACK POINT
;
============================================================================================
Assim terminamos mais esse exemplo.
abraços