Escolar Documentos
Profissional Documentos
Cultura Documentos
Escrito por Gabriel Yoshiaki Hotta em 2013/12/17, sugestes, correes, comentrios, etc, podem ser enviadas para anoxya@gmail.com
Requisitos
Este artigo supe que o leitor j possui o conhecimento bsico sobre interrupes: o que uma interrupo, como trata-las (attachInterrupt() e detachInterrupt()). Tambm recomendado o conhecimento bsico da linguagem Assembly para melhor compreenso, embora no seja estritamente necessrio.
Introduo
Interrupes no Arduino so simples de usar e na maioria das vezes no precisamos nos preocupar com muitos detalhes. Entretanto, quando passam a ser utilizadas vrias interrupes, caractersticas importantes e que no so to evidentes passam a possuir grande relevncia. Uma delas a prioridade das interrupes, bem como a necessidade de interrupes aninhadas (nested interruptions). Pouco material sobre o assunto est disponvel, e de forma dispersa e fragmentada. Este artigo tenta reunir informaes sobre o tema, boa parte do material se baseia na traduo/interpretao do Datasheet.
Terminologia
Capturar interrupo: tratamento de um evento associado a uma interrupo. Condio de interrupo: circunstancias na qual uma interrupo deve ser efetuada. Habilitao de interrupo: circunstancias na qual o processador capaz de efetuar a captura de uma interrupo. Rotina de interrupo: conjunto de comandos/instrues que sero executados quando houver captura de interrupo.
Os tipos de interrupo
Existem basicamente dois tipos de interrupo. O primeiro tipo capturado por um evento que seta o respectivo bit na "Flag Interrupt". Quando isso acontece a rotina de interrupo associada executada e o bit na "Flag Interrupt" limpo (zerado). Se durante a execuo da rotina de interrupo houver uma nova condio de interrupo, o bit ser novamente setado e manter seu valor at a interrupo ser novamente habilitada (tambm possvel limpar o bit explicitamente dentro da rotina, impedindo a execuo posterior da rotina de interrupo). O segundo tipo de interrupo capturado to logo a condio de interrupo esteja presente, elas no utilizam necessariamente a "Flag Interrupt". Se a condio de interrupo
surgir e desaparecer antes da interrupo estar habilitada a rotina de interrupo associada no ser executada. Se duas ou mais condies de interrupo ocorrerem simultaneamente haver uma prioridade de execuo entre as interrupes. Ao sair de uma rotina de interrupo o AVR ir retornar ao programa principal e executar uma instruo antes de executar a prxima rotina de interrupo. Ou seja, se houver duas condies de interrupo, a rotina de interrupo da primeira (com maior prioridade) ser executada, em seguida uma, e somente uma, instruo do programa principal ser executado e apenas depois disso a segunda rotina de interrupo ser executada. O "Status Register" no automaticamente armazenado ao entrar em uma rotina de interrupo, nem restaurado ao sair da Rotina de interrupo. Cabe ao programador faze-lo caso seja do seu interesse.
Prioridade de interrupes
A prioridade de execues dada pela posio no "Interruption Vector", quanto menor a posio ocupada, maior a prioridade. Para o ATmega2560 (usado no Arduino Mega 2560, em outros modelos deve-se consultar o respectivo Datasheet) temos a seguinte tabela:
Ao sair de uma rotina de interrupo executada a instruo "RETI" que reabilita as interrupes. Este o comportamento desejado na maioria das vezes, pois espera o termino de uma rotina de interrupo para, em seguida, executar uma outra rotina de interrupo. Entretanto, se o programador desejar pode-se reabilitar a captura de interrupo dentro de uma rotina de interrupo. A isso d-se o nome de interrupes aninhadas (nested interruptions). Para habilitar interrupes aninhadas o programador deve explicitamente utilizar a instruo responsvel por habilitar interrupes: sei(). Note ainda que o uso incorreto pode acarretar em infinitas interrupes recursivas. Ainda h outro porm, mesmo utilizado a instruo "sei()" no incio de uma rotina de interrupo ainda permanecem algumas instrues geradas pelo compilador antes da instruo Assembly "SEI", ou seja, algumas poucas instrues ainda so executadas com a interrupo desativada. O cdigo em C
ISR(TIM0_OVF_vect) { sei(); //do nothing }
Fontes
Datasheet do ATmega2560 http://www.carlosdelfino.eti.br/eletronica/item/89-prioridade-dasinterrup%C3%A7%C3%B5es-em-microcontroladores-atmega http://stackoverflow.com/questions/5111393/do-interrupts-interrupt-other-interrupts-onarduino http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html http://ucexperiment.wordpress.com/2013/05/20/nested-interrupts/