Você está na página 1de 7

Interrupes

O que uma interrupo?


Irei agora comear a falar de interrupes a partir do mais bsico o que uma interrupo? Uma interrupo basicamente uma pausa no programa, enquanto o processador trata de outra coisa mais importante. Um exemplo da ida real! "ttp!##$$$.%outube.com#$atc"? &'()*+U,--r' .este caso a interrupo foi o toque com o pato que interrompeu o discurso.

Como funciona uma interrupo no AVR?


.os '/0s, as interrupes t1m rias particularidades, pois necessrio acti ar as interrupes globais, as interrupes particulares e criar uma rotina para lidar com cada interrupo. 2ada microcontrolador '/0 tem um con3unto de registers cu3os bits controlam rios aspectos do seu funcionamento 4por exemplo, no tutorial que coloquei no meu primeiro post, esto explicados os que controlam os pinos de I.*U5#6U5*U57. 6 mesmo acontece com as interrupes. .o caso do atmega89:, o bit I do register ;0)< controla as interrupes a n= el global. >uando o seu alor ?, estas esto ligadas, e ice@ ersa. .o entanto, " uma instruo mais simples para ligar as interrupes globais do que terem de se lembrar que no bit I do register ;0)<, que simplesmente AseiB 4funciona tanto em assembl% como em 2, sC que em 2 uma funo inclu=da no "eader Da r#interrupt."E7. Fepois de ligadas as interrupes globais, ainda necessrio ligar interrupes indi iduais. *ara isso, necessrio encontrar qual o bit que liga certa interrupo 4encontra@se na datas"eet facilmente na Gona dos registers no cap=tulo acerca da funcionalidade procurada7. Fepois de ligadas as interrupes globais e particulares, o processador procura por mudanas de estado em bits de certos registers 4flags7, definidos pelas interrupes indi iduais. >uando esses bits tornam@se em ?, a interrupo gerada 4independentemente do que este3a a acontecer, o programa pra7. Has falta aqui uma coisa I o que acontece quando essa interrupo ocorre? ' AInterrupt ;er ice 0outineB 4I;07 definida para aquela interrupo executada. .o final disto tudo, a flag fica com o alor , no amente, e o programa continua a sua execuo a partir do ponto em que esta a. .ota! )nquanto o processador est a executar a interrupo, as interrupes globais esto desligadas. >uando acaba@se de executar a interrupo, as interrupes globais so ligadas no amente.

Como lidar com uma interrupo no AVR?


'gora que 3 sabemos como funciona uma interrupo, temos de aprender a programar de forma a lidar com as mesmas. *rimeiro, iremos comear por definir o pseudo@cCdigo! // Iniciar o programa // (cdigo que inicialize variveis, LEDs, etc. aqui) // Ligar interrup !es particulares // Ligar interrup !es glo"ais // De#inir I$% para lidar com as interrup !es particulares ligadas. *ara lidar com registos e interrupes, iremos precisar dos seguintes "eaders! Da r#io."E e Da r#interrupt."E 43 podemos tambm adicionar a funo main47, e um loop eterno7! // Iniciar o programa &include 'avr/io.() &include 'avr/interrupt.() int main(void) * // (cdigo que inicialize variveis, LEDs, etc. aqui) // Ligar interrup !es particulares // Ligar interrup !es glo"ais #or(++)+ , // De#inir I$% para lidar com as interrup !es particulares ligadas. 4como a I;0 uma funo, definimos fora do main7. 2omo expliquei anteriormente, ligam@se as interrupes globais atra s da funo sei47 // Iniciar o programa &include 'avr/io.() &include 'avr/interrupt.() int main(void) * // (cdigo que inicialize variveis, LEDs, etc. aqui) // Ligar interrup !es particulares sei()+ #or(++)+ , // De#inir I$% para lidar com as interrup !es particulares ligadas. .este tCpico, amos ignorar as interrupes indi iduais, pois ainda no falmos de nen"uma

interessante, e amos concentrar@nos nas I;0. ' biblioteca do a r d@nos uma macro muito Jtil para definir uma I;0, e tem o nome I;047 4espertos, no so? xF7, com um argumento! o nome do ector da interrupo. 6 ector da interrupo basicamente o que identifica qual a interrupo com que estamos a lidar. )sta informao encontra@se na pgina KL do datas"eet que eu ten"o 4in=cio do cap=tulo sobre interrupes#cap=tulo (7, numa tabela, na coluna ;ource. *or exemplo, no tCpico a seguir, amos lidar com a interrupo que ocorre no pino digital 9. )ste pino tem o nome de I.5,. 'o ol"armos para a tabela, emos que a source da interrupo I.5,. *ara usarmos isto como argumento para a macro I;0, basta adicionar AM ectB. 'ssim, o ector ! I.5,M ect! // Iniciar o programa &include 'avr/io.() &include 'avr/interrupt.() int main(void) * // (cdigo que inicialize variveis, LEDs, etc. aqui) // Ligar interrup !es particulares sei()+ #or(++)+ , I$%(I-./0vect) * // De#inir o que #azer quando acontece esta interrup 1o , 4para alguns, esta declarao da funo I;0 pode ser confusa, pois no tem tipo. .o entanto, lembrem@se que uma macro, e por isso I;0 no realmente o que fica no cCdigo final7. .ota! ;e notarem, alguns dos /ectores na datas"eet t1m espaos ou =rgulas no nome. -asta substituir esses por M. *or exemplo, para a interrupo gerada quando se recebem dados por serial, temos o seguinte ;ource! U;'05, 0N. 6 argumento que usamos para a macro I;0 ! U;'05M0NM ect.

Exemplo de interrupo atravs do pino di ital ! "I#$%&


/amos agora faGer algo mais interessante, e codificar uma interrupo. 2omecemos com o cCdigo do tCpico anterior!

// Iniciar o programa &include 'avr/io.() &include 'avr/interrupt.()

int main(void) * // (cdigo que inicialize variveis, LEDs, etc. aqui) // Ligar interrup !es particulares sei()+ #or(++)+ , I$%(I-./0vect) * // De#inir o que #azer quando acontece esta interrup 1o , /amos usar para este efeito o pino 9 4podia ser feito com o pino 8 tambm, com poucas diferenas7. 6 ob3ecti o deste cCdigo ai ser mudar o estado de um O)F quando se toca num boto ligado ao pino 9. 6 O)F ai estar ligado ao pino digital P 4*FP7. /amos comear por criar uma ari el global, com o estado do pino e inicialiGar esse pino como output 4 ai comear desligado7 4para mais informaes sobre <*I6s, ler o tutorial que pus no primeiro post7, e 3 amos colocar o cCdigo necessrio para faGer toggle ao pino na I;0. // Iniciar o programa &include 'avr/io.() &include 'avr/interrupt.() c(ar output 2 /+ // Estado do led. int main(void) * DD%D 32 (4''5D6)+ // Inicializar o pino digital 6 como output. 57%.D 82 9(4''5D6)+ // Inicializar o pino digital 6 como desligado. // Ligar interrup !es particulares sei()+ #or(++)+ , I$%(I-./0vect) * // De#inir o que #azer quando acontece esta interrup 1o output 2 9output+ // :lterar o estado 57%.D 82 9(4''5D6)+ // Desligar o pino ; isto < necessrio para quando o output < / se poder desligar. 57%.D 32 ((output84)''5D6) // output84 pois s nos interessa o primeiro "it, assim evitamos me=er nos outros pinos. , 'gora sC nos falta mesmo inicialiGar a interrupo particular para o I.5,.

'o pesquisarmos na datas"eet, podemos obser ar um pormenor acerca dos interrupts externos I.5, e I.5?! eles podem ser ligados por P estados diferentes! quando o pino est lo$, quando o pino transita para "ig", quando o pino transita para lo$ e quando o pino muda de estado 4lo$@"ig" e ice@ ersa7. 2omo estamos a usar um boto, o mais fcil que este ligue o pino Q corrente, colocando@o em RI<R. 'ssim, queremos gerar o interrupt quando o pino transita para RI<R. 6 estado escol"ido para o I.5, est nos bits I;2,, e I;2,? do register )I20' 4para o pino I.5?, est nesse mesmo register, mas nos bits I;2?, e I;2??7. 6 estado que dese3amos corresponde a colocar ambos os bits em ?. Oogo, adicionamos isso ao cCdigo! // Iniciar o programa &include 'avr/io.() &include 'avr/interrupt.() c(ar output 2 /+ // Estado do led. int main(void) * DD%D 32 (4''5D6)+ // Inicializar o pino digital 6 como output. 57%.D 82 9(4''5D6)+ // Inicializar o pino digital 6 como desligado. EI>%: 32 ((4''I$>//) 3 (4''I$>/4))+ // >on#igurar interrup 1o no pino I-./ para quando este transita para ?I@? // Ligar interrup !es particulares sei()+ #or(++)+ , I$%(I-./0vect) * // De#inir o que #azer quando acontece esta interrup 1o output 2 9output+ // :lterar o estado 57%.D 82 9(4''5D6)+ // Desligar o pino ; isto < necessrio para quando o output < / se poder desligar. 57%.D 32 ((output84)''5D6) // output84 pois s nos interessa o primeiro "it, assim evitamos me=er nos outros pinos. , 'gora sC nos falta mesmo ligar a interrupo associada ao I.5,. 6 bit que controla isto o I.5, no register )IH;S. 'ssim, sC modificar o cCdigo, e fica completo! // Iniciar o programa &include 'avr/io.() &include 'avr/interrupt.() c(ar output 2 /+ // Estado do led.

int main(void) * DD%D 32 (4''5D6)+ // Inicializar o pino digital 6 como output. 57%.D 82 9(4''5D6)+ // Inicializar o pino digital 6 como desligado. EI>%: 32 ((4''I$>//) 3 (4''I$>/4))+ // >on#igurar interrup 1o no pino I-./ para quando este transita para ?I@? EIA$B 32 (4''I-./)+ // Ligar interrup !es particulares sei()+ #or(++)+ , I$%(I-./0vect) * // De#inir o que #azer quando acontece esta interrup 1o output 2 9output+ // :lterar o estado 57%.D 82 9(4''5D6)+ // Desligar o pino ; isto < necessrio para quando o output < / se poder desligar. 57%.D 32 ((output84)''5D6) // output84 pois s nos interessa o primeiro "it, assim evitamos me=er nos outros pinos. , 'gora temos um cCdigo que, ao clicarmos num boto que liga o pino digital 9 e o pClo positi o, faG toggle do pino digital P 4nota! isto que no fiGemos nada para tratar do bouncing, podem "a er resultados inesperados. .o entanto, como isto sC para exemplo, no considermos muito importante7. *ara experimentarem, podem montar o seguinte circuito!

Cuidados a ter na utili'ao de interrupes


/ou deixar aqui duas situaes a terem em ateno quando esto a lidar com interrupes! ?. 6 compilador optimiGa bastante o cCdigo. Isto quase sempre uma antagem, no entanto, por eGes no . UtiliGando o exemplo do tCpico anterior, se ti ssemos de aceder a ari el output

no cCdigo do main47, no estar=amos a aceder ao alor correcto da ari el. Isto acontece porque o compilador no considera que podemos aceder Q funo I;0 sC com aquele cCdigo, logo apenas carrega a ari el da memCria ram para os registers uma eG, e depois no actualiGa o seu alor, que alterado na I;0. *ara resol er isto, diGemos ao cCdigo que a declarando@a assim! olatile c"ar outputT Isto indica ao compilador que a ari el pode ser alterada de formas inesperadas, e por isso de e sempre actualiGar o seu alor da ram. 9. 6 processador '/0 do 'rduino funciona a : bits. Isto quer diGer que ele sC pode lidar com : bits de cada eG. .o pode, por exemplo, carregar um int da memCria numa sC instruo, pois estes t1m ?+ bits. Has as interrupes podem ocorrer em qualquer parte do programa I logo o que pensam que acontece se tirarmos a primeira metade de um inteiro da memCria, e antes de tirarmos a segunda metade ocorrer uma interrupo que altere essa ari el? 0esultados no pre is= eis ob iamente I Oogo, o que podemos faGer para e itar isto? 6 que podemos faGer desligar interrupes nesses blocos de cCdigo que no podem ser perturbados 4nota! se esti erem a carregar um c"ar no de e "a er problemas, isto ter apenas : bits7. Isto feito facilmente com a funo cli47 4tambm no "eader Da r#interrupt."E7. Fepois do cCdigo efectuado, basta ligar no amente as interrupes com sei47. *or exemplo! //... int i,C+ #or(++) * cli()+ C 2 i+ // o i < alterado numa interrup 1o sei()+ // , //... ) com isto acabamos a base das interrupes. Fecidi comear com estas, pois nos prCximos tutoriais, explicarei as interrupes indi iduais de rias funcionalidades. ari el output olatile,

Você também pode gostar