interrupções 16f877a

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

interrupções 16f877a

Mensagempor diogo_18sp » 16 Jul 2012 22:01

ola galera ... to com uma duvida sobre interrupções do pic 18f877a...esta hj desenvolvendo um programa em asm...dai me deparei com uma duvida meu circuito esta usando tmr0 com estouro a cada 500us dai entro dentro do vetor de interrupçao org 0x004 e trato este timer que relacionado a multiplexaçao dos display de sete segmentos....mas oq acontece vou agora usar tbm o tmr1 so que para contar 1seg....a duvida seria seguinte se estiver dentro do vetor de interrupção tratando do tmr0 e ocorrer o estouro do timer1 meu vetor de interrupçao org 0x004 voltara para inicio da interrupçao??
ou seja quando estiver no endereço org 0x004 todas as interrupçao que se ocasionar vai voltar no inicio do endereço ??
devo desabilitar as interrupçao quando entrar neste endereço??
diogo_18sp
Byte
 
Mensagens: 117
Registrado em: 14 Jan 2008 18:12
Localização: Amparo ,SP

Mensagempor jorgeluiz » 17 Jul 2012 01:19

se ocorrer a interrupçao no tmr0, e ocorrer uma outra qualquer enquanto o programa trata da interrupçao, apos o RETFIE ele retorna pra 0x04 pra tratar todas interrupçoes que estao pendentes, isto é, com os flags setados.
Só depois que todos flags de interrupçoes foram limpos, ele retorna ao programa.
Avatar do usuário
jorgeluiz
Byte
 
Mensagens: 448
Registrado em: 26 Mar 2007 02:26

Mensagempor tcpipchip » 17 Jul 2012 04:09

Será que ao termino de um interrupção nao chega a executar um instrução do programa ?
Avatar do usuário
tcpipchip
Dword
 
Mensagens: 6560
Registrado em: 11 Out 2006 22:32
Localização: TCPIPCHIPizinho!

Mensagempor diogo_18sp » 17 Jul 2012 21:40

Galera ja fiz a previa do programa que é um temporizador e ficou show ...agora vou terminar de colocar funçoes na placa como botao stop valeu pela duvida sanada...



;*********************************** placa teste***************************************
;
; diogo franscisco da silva 5/07/2010
;
; DISPLAY
;
;******************************************************************************************

;***********************************descriçoes das portas**********************************
; rb7 saida display
; rb6 saida display
; rb5 saida display
; rb4 saida display
; re0 display unidade
; re1 display dezena
; re2 display centena
;********************************************************************************************

;*********************************configuraçoes do pic***************************************

#include <p16f877a.inc>
__config _xt_osc&_cp_off&_wdt_off&_pwrte_on&_debug_off&_lvp_off&_wrt_off&_boden_on&_cpd_off

;*********************************************************************************************

;**********************************registradores de uso geral*********************************

cblock 0x20 ;posiçao inicial do banco de memoria ram

contro_disp ;variavel que controla posiçao dos displays
unidade ;variavel que controla os valores unidade
dezena ;variavel que controla os valores dezena
centena ;variavel que controla os valores centena
disp_out ;variavel que controla os valores display
tempo
tempo1
divisor_tmr1
flag_timer
endc
;*********************************************************************************************



;************************************definiçao************************************************

#define duni porte,0
#define ddez porte,1
#define dcen porte,2
#define rele portc,5
;*********************************************************************************************
;valor passado ao timer2 65536 - 62500 = 3036 0xbdc

; high equ 0x0b ;guarda a parte alta do valor do temporizador 11
; low equ 0xdc ;guarda a parte baixa do valor do temporizador 220
; seg equ 0x02 ;valor que auxiliana contagem de 1 segundo

;************************************definiçao entradas***************************************

#define bt_up portd,0 ;define botao incremento
#define bt_dw portd,1 ;define botao decremento
#define bt_start portd,2 ;define botao start timmer

;*********************************************************************************************


;************************************inicio programa**********************************************
org 0x0000
goto configi

;*********************************************************************************************


;************************************interrupçao**********************************************
org 0x0004


btfss pie1,tmr1if ;estouro que ocorreu e do timer 1?
goto int_display ;verifica se foi interrupçao do tmr0 para atualizar display

movlw 0x0b ;carrega valor da parte alta
movwf tmr1h ;parte alta do timer
movlw 0xdc
movwf tmr1l ;parte baixa do timer

decfsz divisor_tmr1,f ;decrementa divisor
goto sai_int ;nao acabou ainda nao é 1 segundo

movlw 0x02 ;recarrega com 2
movwf divisor_tmr1 ; carrega com 2

;######################################################################################################


movf unidade,f ;testa para ver se unidade e zero
btfss status,z ;a unidade tem valor 0
goto dec_unid_int ;decrementa unidade pois nao e zero seu valor

movlw 0x09 ;carrega com 9 w
movwf unidade ;carrega valor em registrador
goto trata_dec_dez_int ;decrementa unidade

dec_unid_int
decf unidade,f ;decrementa unidade
goto comp ;volta para varredura dos botoes


trata_dec_dez_int
movf dezena,f ;testa para ver se dezena e zero
btfss status,z ;a unidade tem valor 0
goto dec_dezen_int ;decrementa unidade pois nao e zero seu valor

movlw 0x09 ;carrega com 9 w
movwf dezena ;carrega valor em registrador
goto trata_dec_cen_int ;decrementa dezena

dec_dezen_int
decf dezena,f ;decrementa unidade
goto comp ;volta para varredura dos botoes

trata_dec_cen_int
movf centena,f ;testa para ver se dezena e zero
btfss status,z ;a unidade tem valor 0
goto dec_cent_int ;decrementa unidade pois nao e zero seu valor

movlw 0x09 ;carrega com 9 w
movwf centena ;carrega valor em registrador
goto comp ;decrementa dezena

dec_cent_int
decf centena,f ;decrementa unidade
goto comp ;volta para varredura dos botoes

comp
movf unidade,f ;coloca unidade em f para ver se e 0
btfss status,z ;é 1?
goto sai_int ;inicia temporizaçao

movf dezena,f ;coloca unidade em f para ver se e 0
btfss status,z ;é 1?
goto sai_int ;inicia temporizaçao

movf centena,f ;coloca unidade em f para ver se e 0
btfss status,z ;é 1?
goto sai_int

bcf t1con,tmr1on ;desliga timer1
bsf status,rp0 ;seleciona banco 1
bcf pie1,tmr1ie ;habilita chave tmrlie para interrupçao
bcf status,rp0 ;seleciona banco zero
bcf flag_timer,0 ;avisa que o rele e para ser desligado
bcf rele
goto sai_int

sai_int
bcf pir1,tmr1if ;limpa flag da interrupçao do timer1
retfie


;***********************************************************************************************
; interrupçao do display tmr0 aqui onde ira ser tratadas as rotinas desta interrupçao
;***********************************************************************************************
int_display

btfss intcon,t0if ;estouro que ocorreu e do timer 0
retfie ;nao foi do timer 0
call atualiza ;atualiza os display
retfie

;*********************************************************************************************



;*************************************configuraçao das I/O************************************
configi

bcf status,rp0 ;banco 0
bsf status,rp0 ;banco 1

movlw 0x81 ;10000001
movwf option_reg ;pull up desabilitado,1:4,tmr0

movlw 0x07 ;carrega com 00000111
movwf adcon1 ;todos pinios como I/O digital

movlw 0x00 ;carrega com 0000 000
movwf intcon ;nao sera tratada nenhuma interrupçao

movlw 0x00 ;carrega com 0
movlw pie1 ;nao sera tratada nenhuma interrupçao

movlw 0xff ;carrega com 1111 1111
movwf trisa

movlw 0x0f
movwf trisb ;carrega com 0000 1111

movlw 0xdf
movwf trisc ;carrega com 1111 1111

movlw 0x0f
movwf trisd ;carrega com 0000 1111

movlw 0x00
movwf trise ;carrega com

bcf status,rp0 ;banco 0

movlw 0x30 ;carrega com valor 0011 0000
movwf t1con ;prescale 1:8 ,tmr1 desligado

;limpa as variaveis que serao inicializadas

clrf porta ;limpa porta
clrf portb ;limpa porta
clrf portc ;limpa porta
clrf portd ;limpa porta
clrf porte ;limpa porta
clrf unidade ;limpa variavel
clrf dezena ;limpa variavel
clrf centena ;limpa variavel
clrf contro_disp ;limpa variavel
clrf flag_timer
call config_display ;configuraçao inial do timer do display
goto inicio ;inicio programa principal

;********************************programa principal*************************************************

inicio

btfsc bt_start ;botao start foi pressionado??
goto nao_btstart ;botao start nao foi pressionado
call liga_timer

nao_btstart

btfsc bt_up ;botao up esta pressionado
goto ve_bt_dw ;trata botao decrementa para ver se esta pressionado
goto bot_inc ;trata botao incremento

ve_bt_dw

btfsc bt_dw ;botao decremento foi pressionado
goto inicio ;nao foi pressionado volta fazer leitura dos botoes
goto bot_dec ;foi pressionado trata para ver se nao foi ruido


;****************************************************************************************************
; trata botao decremento
;****************************************************************************************************

bot_dec

btfsc bt_dw ;botao decremento foi pressionado e continua pressionado
call atraso ;filtro para botao para nao fazer leitura de ruido
btfsc bt_dw ;cotinua pressionado botao?????
goto inicio ;botao esta solto entao era ruido
btfss bt_dw ; botao ja foi solto para decrementar?
goto $-1 ;botao continua pressionado

movf unidade,f ;testa para ver se unidade e zero
btfss status,z ;a unidade tem valor 0
goto dec_unid ;decrementa unidade pois nao e zero seu valor

movlw 0x09 ;carrega com 9 w
movwf unidade ;carrega valor em registrador
goto trata_dec_dez ;decrementa unidade

dec_unid
decf unidade,f ;decrementa unidade
goto inicio ;volta para varredura dos botoes


trata_dec_dez
movf dezena,f ;testa para ver se dezena e zero
btfss status,z ;a unidade tem valor 0
goto dec_dezen ;decrementa unidade pois nao e zero seu valor

movlw 0x09 ;carrega com 9 w
movwf dezena ;carrega valor em registrador
goto trata_dec_cen ;decrementa dezena

dec_dezen
decf dezena,f ;decrementa unidade
goto inicio ;volta para varredura dos botoes

trata_dec_cen
movf centena,f ;testa para ver se dezena e zero
btfss status,z ;a unidade tem valor 0
goto dec_cent ;decrementa unidade pois nao e zero seu valor

movlw 0x09 ;carrega com 9 w
movwf centena ;carrega valor em registrador
goto inicio ;decrementa dezena

dec_cent
decf centena,f ;decrementa unidade
goto inicio ;volta para varredura dos botoes


;****************************************************************************************************
; trata botao incremento
;****************************************************************************************************
bot_inc

btfsc bt_up ;botao continua pressionado
call atraso ;filtro para botao para nao fazer leitura de ruido
btfsc bt_up ;cotinua pressionado botao?????
goto inicio ;botao esta solto entao era ruido
btfss bt_up ; botao ja foi solto para incrementar?
goto $-1 ;botao continua pressionado

movf unidade,w ;coloca valor de unidade em w
xorlw 0x09 ;compara para ver se valor de unidade é 9
btfss status,z ;a comparaçao e igual valor unidade maximo 9
goto inc_uni ;comparaçao nao e igual entao incrementa unidade
goto zera_uni ;zera unidade e começa a incrementar dezena pois a comparaçao foi igual

inc_uni

incf unidade,f ;incrementa unidade
goto inicio ;volta fazer a leitura das chaves

zera_uni

clrf unidade ;apaga unidade
goto trata_deze ;trata display dezena

;******************************************************************************************************

trata_deze

movf dezena,w ;coloca valor de unidade em w
xorlw 0x09 ;compara para ver se valor de unidade é 9
btfss status,z ;a comparaçao e igual valor unidade maximo 9
goto inc_dez ;comparaçao nao e igual entao incrementa unidade
goto zera_dez ;zera unidade e começa a incrementar dezena pois a comparaçao foi igual

inc_dez
incf dezena,f ;incrementa dezena
goto inicio ;volta fazer a leitura das chaves

zera_dez

clrf dezena ;limpa dezena
goto trata_cent ;trata display centena

;******************************************************************************************************

trata_cent

movf centena,w ;coloca valor de unidade em w
xorlw 0x09 ;compara para ver se valor de unidade é 9
btfss status,z ;a comparaçao e igual valor unidade maximo 9
goto inc_cen ;comparaçao nao e igual entao incrementa unidade
goto zera_cen ;zera unidade e começa a incrementar dezena pois a comparaçao foi igual

inc_cen
incf centena,f ;incrementa dezena
goto inicio ;volta fazer a leitura das chaves

zera_cen
clrf centena ;limpa dezena
goto inicio ;trata display centena


;***************************************************************************************************
; timmer inicial para display
;***************************************************************************************************
;configuraçao inicial para timer e display

config_display
bsf contro_disp,0 ;seta o bit 0 para referencia do display
bcf intcon,t0if ;limpa flag do timer
clrf tmr0 ;limpa timer
movlw 0x7d ;carrega com 125
movwf tmr0 ;coloca valor em timer que equivale a 500us
movlw 0Xe0 ;carrega com 1110 0000
movwf intcon ;foram habilitada as chaves GIE,TOIE,TOIF PARA PODER OCORRER INTERRUPÇAO

return

;****************************************************************************************************
; trata Filtro botao
;****************************************************************************************************

atraso

movlw 0x19 ;carrega variavel com 25
movwf tempo1

volta_1
movlw 0xfa ;carrega variavel com 250
movwf tempo

volta

nop
decfsz tempo,f
goto volta

decfsz tempo1,f
goto volta_1
return ;sai da subrotina

;****************************************************************************************************


;_______________________________________________________________________________________________________
; on_timmer
;-------------------------------------------------------------------------------------------------------
liga_timer

btfsc bt_start ; chave start continua pressionada
call atraso ;gera atraso para depois verificar se nao foi um ruido
btfsc bt_start ;achave start continua pressionada?
return ;nao entao poderia ser ruido
; btfss bt_start ;botao start foi solto
; goto $-1

movf unidade,f ;coloca unidade em f para ver se e 0
btfss status,z ;é 1?
goto start_timer ;inicia temporizaçao

movf dezena,f ;coloca unidade em f para ver se e 0
btfss status,z ;é 1?
goto start_timer ;inicia temporizaçao

movf centena,f ;coloca unidade em f para ver se e 0
btfss status,z ;é 1?
goto start_timer
return ;nao inicia timmer pois o valor é 000

start_timer
;configuraçao das chaves de interrupçao

bcf status,rp0 ;seleciona banco 0
movlw 0xe0 ;carrega valor 1110 0000
movwf intcon ;habilita chave geie,peie,toie
bsf status,rp0 ;seleciona banco 1
bsf pie1,tmr1ie ;habilita chave tmrlie para interrupçao
bcf status,rp0 ;seleciona banco zero
;fim da seleçao de chaves
;*********************************************

movlw 0x02 ;valor 2
movwf divisor_tmr1 ;esta variavel ira conter a comparaçao para 1 segundo

bcf pir1,tmr1if ;apaga flag timer 1
movlw 0x0b ;carrega valor da parte alta
movwf tmr1h ;parte alta do timer

movlw 0xdc
movwf tmr1l ;parte baixa do timer
bsf t1con,tmr1on ;liga timer para 500 ms
bsf flag_timer,0

bsf rele
btfsc flag_timer,0
goto $-1
nop
goto $
;***********************************************************************************************************




;************************************Atualiza********************************************************
;esta subrotina tem a funçao de atualizar os display multiplexados
;nao houve estouro
atualiza
bcf status,rp0 ;seleciona banco 0
btfss contro_disp,0 ;bit 0 e igual a 1
goto ve_dez ;vai ver se e dezena
goto trata_uni ;e 1 entao atualiza unidade

ve_dez
btfss contro_disp,1 ;bit 0 e igual a 1
goto ve_cen ;vai ver se e centena
goto trata_dez ;e 1 entao atualiza dezena

ve_cen
btfss contro_disp,2 ;bit 0 e igual a 1
goto timer ;hove erro?
goto trata_cen ;e 1 entao atualiza centena

trata_uni
bcf duni ;apaga display unidade
bcf ddez ;apaga display dezena
bcf dcen ;apaga display centena
movlw 0x02 ;carrega com 2 010
movwf contro_disp ;indica que na proxima atualizaçao ea dezena
movf unidade,w ;coloca o valor de unidade em w
movwf disp_out ;coloca o valor na variavel
swapf disp_out,f ;inverte bits
movf disp_out,w ;coloca o valor invertido em w
movwf portb ;coloca valor no portb
bsf duni ;liga display unidade
goto timer ;vai para timer

trata_dez
bcf duni ;apaga display unidade
bcf ddez ;apaga display dezena
bcf dcen ;apaga display centena
movlw 0x04 ;carrega com 4 100
movwf contro_disp ;indica que na proxima atualizaçao ea dezena
movf dezena,w ;coloca o valor de dezena em w
movwf disp_out ;coloca o valor na variavel
swapf disp_out,f ;inverte bits
movf disp_out,w ;coloca o valor invertido em w
movwf portb ;coloca valor no portb
bsf ddez ;liga display dezena
goto timer ;vai para timer

trata_cen
bcf duni ;apaga display unidade
bcf ddez ;apaga display dezena
bcf dcen ;apaga display centena
movlw 0x01 ;carrega com 1 001
movwf contro_disp ;indica que na proxima atualizaçao ea dezena
movf centena,w ;coloca o valor de centena em w
movwf disp_out ;coloca o valor na variavel
swapf disp_out,f ;inverte bits
movf disp_out,w ;coloca o valor invertido em w
movwf portb ;coloca valor no portb
bsf dcen ;liga display centena
goto timer ;vai para timer
;********************************************Timer******************************************************
;aqui sera programado o tempo que cada display permanecera aceso na multiplexaçao de 500 us
timer

bcf intcon,t0if ;limpa flag do timer
clrf tmr0 ;limpa timer
movlw 0x7d ;carrega com 125
movwf tmr0 ;coloca valor em timer que equivale a 500us

return
;********************************************************************************************************************************************
end
diogo_18sp
Byte
 
Mensagens: 117
Registrado em: 14 Jan 2008 18:12
Localização: Amparo ,SP

Re: interrupções 16f877a

Mensagempor rafael l » 18 Jul 2012 20:11

diogo_18sp escreveu:ou seja quando estiver no endereço org 0x004 todas as interrupçao que se ocasionar vai voltar no inicio do endereço ??
devo desabilitar as interrupçao quando entrar neste endereço??


Em ASM nao sei dizer, mas qualquer outro compilador de outra linguagem adota como padrao desabilitar a chave GIE quando se entra em uma interrupçao.

Porque nao usou o TMR0 para gerar 1s tambem?
rafael l
Bit
 
Mensagens: 8
Registrado em: 19 Jun 2012 21:19

Re: interrupções 16f877a

Mensagempor diogo_18sp » 19 Jul 2012 12:09

rafael l escreveu:
diogo_18sp escreveu:ou seja quando estiver no endereço org 0x004 todas as interrupçao que se ocasionar vai voltar no inicio do endereço ??
devo desabilitar as interrupçao quando entrar neste endereço??


Em ASM nao sei dizer, mas qualquer outro compilador de outra linguagem adota como padrao desabilitar a chave GIE quando se entra em uma interrupçao.

Porque nao usou o TMR0 para gerar 1s tambem?



entao pq o timer0 to usando para multiplexar o display que esta programado em 500us cada se fosse usar esta base de tempo teria que ter 2000 estouro do timer para conseguir 1 segundo...ja com timer 1 so tenho que monitorar 2 interrupçao que ja tenho 1 segundo alem de ser mais preciso pois ele e de 16 bits
diogo_18sp
Byte
 
Mensagens: 117
Registrado em: 14 Jan 2008 18:12
Localização: Amparo ,SP

Mensagempor RobL » 20 Jul 2012 21:31

Em ASM nao sei dizer, mas qualquer outro compilador de outra linguagem adota como padrao desabilitar a chave GIE quando se entra em uma interrupçao.


Não. Isso é feito pelo hardware do micro.


entao pq o timer0 to usando para multiplexar o display que esta programado em 500us cada se fosse usar esta base de tempo teria que ter 2000 estouro do timer para conseguir 1 segundo...ja com timer 1 so tenho que monitorar 2 interrupçao que ja tenho 1 segundo alem de ser mais preciso pois ele e de 16 bits


No teu caso a precisão vai depender somente do clock (cristal ou seja lá a sua fonte). Tanto faz um timer de 8, 16, 32 bits.

Interrupções com intervalos de 500us pode parar seu processamento. A cada interrupção, salvará o contexto. O trabalho vai se concentrar em somente salvar contexto. Procure usar a menor frequência possível, que não cause cintilação no display.
Se não tiver um cristal com "número mágico" (base 2) aí o de maior quantidade de bits pode melhorar, se usar o modo comparador.
Em outros casos, como PWM, aí sim, uma maior "granulação" (mais números) aumenta sua precisão.
RobL
Dword
 
Mensagens: 1546
Registrado em: 20 Fev 2007 17:56


Voltar para PIC

Quem está online

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

cron

x