Você está na página 1de 10

MINISTRIO DA EDUCAO MEC UNIVERSIDADE FEDERAL DE JUIZ DE FORA UFJF FACULDADE DE ENGENHARIA

LABORATRIO DE MICROCONTROLADORES
Interrupo por Hardware

MARCELLA LHAMAS ALHADAS

200450032

21/09/2011

ndice

1. Introduo
Frequentemente temos que reagir a condies de hardware e outros eventos. Um exemplo a alterao em um pino de entrada. Voc pode programar uma reao como um loop, sempre verificando se houve alterao em um pino. Este mtodo chamado de busca, como uma abelha voando em crculos procurando por novas flores. Se voc tem que detectar pulsos curtos com durao inferior a microssegundos, este mtodo intil. Neste caso, voc ter que programar uma interrupo. As interrupes permitem o processamento adequado em resposta a eventos internos ou externos, aumentado a possibilidade de interao com o meio. Uma interrupo disparada por alguma condio de hardware. Os bits respectivos da porta, para est condio, que habilitam a resposta interrupo devem ser habilitados primeiro, todas as interrupes de hardware so desabilitadas por padro, no momento do reset. O processador tem um bit no seu registrador de status que o habilita a responder interrupo de qualquer componente, a flag de habilitao de interrupo (Interrupt Enable Flag). De acordo com [Atmel 2004], como medida de segurana, existe para cada interrupo um vetor de registradores nico. Essa configurao impede a execuo de uma nova instncia da mesma interrupo quando outra estiver sendo executada.

2. Habilitando a Interrupo
Para cada fonte de interrupo, existe um bit responsvel por sua habilitao. Este bit fica em algum dos registros do perifrico associado interrupo. Mas tambm existe o bit I do registro SREG, Figura 1, (registro de estado do microcontrolador) que, quando setado em 1, habilita a ocorrncia de qualquer interrupo que tenha sido habilitada em seu perifrico responsvel. Se este bit for colocado em 0, ento nenhuma solicitao de interrupo ser atendida, mesmo se a interrupo for habilitada em seu perifrico. Se ocorrer uma solicitao de interrupo habilitada com o bit I em 0, ento o atendimento somente ocorrer quando o bit I for colocado em 1. Para garantir automatismo no procedimento de alterao do bit I em linguagem C, devem-se usar as funes sei() e cli(), que correspondem s instrues assembly sei (set I bit) e cli (clear I bit ). Assim, sei() habilita globalmente as interrupes, enquanto que cli() desabilita globalmente as interrupes. H outras formas de habilitar o bit I. Uma delas o tratamento da interrupo para terminar com o comando RETI, este comando retorna o bit I depois do contador de programa ter sido restabelecido com o valor do endereo de retorno. E outra habilitar o bit I pela instruo SEI (Habilita bit de Interrupo) e RET (Retorna). Isto no faz mesma coisa que o RETI, pois interrupes subsequentes estaro habilitadas antes do contador de programa ser recarregado com o endereo de retorno. Se outra interrupo estiver pendente, sua execuo j inicia antes que o endereo de retorno seja removido da pilha. Dois ou mais endereos de retorno permanecem na pilha. Isto no causa bug imediato, mas um risco desnecessrio. Portanto, use a instruo RETI para evitar fluxo desnecessrio na pilha.

Figura 1 Registro de Estado do ATmega8

3. Prioridades da Interrupo
Se uma condio de interrupo ocorre, houve mudana no bit da porta, o processador coloca o contador de programa atual na pilha (que deve ser habilitada primeiro). Sem isso, o processador no seria capaz de retornar ao ponto onde estava quando ocorreu a interrupo (o que pode ocorrer a qualquer momento em qualquer lugar da execuo do programa). Depois, o processamento salta para a localizao predefinida, o vetor de interrupo, e a executa as instrues. Um vetor de interrupo tem capacidade para apenas uma instruo de salto para a rotina de servio. Se certa interrupo no usada ou indefinida, colocamos simplesmente uma instruo RETI ali, no caso de uma falsa interrupo ocorrer. o caso da execuo do servio respectivo no resetar automaticamente a condio de interrupo do perifrico. Neste caso, um simples RETI causaria um loop contnuo de resets. Este o caso com algumas interrupes da UART. Uma regra muito importante para o tratamento de interrupes : A primeira instruo sempre tem que guardar o registrador de status na pilha, antes de voc utilizar instrues que possam alterar as flags do registrador de status. O programa principal, que foi interrompido, pode precisar utilizar uma flag que estava setada, para tomar alguma deciso, e a interrupo alterou justamente esta flag. Coisas engraadas podem acontecer de tempos em tempos. A ltima instruo antes de RETI dever ser recuperar o contedo do registrador de status da pilha e restaurar seu contedo original.

4. Configurao da Interrupo
A localizao do vetor de interrupo especfica do processador, e dependente dos componentes de hardware e da condio que levou interrupo. Quanto mais componentes de hardware e mais condies, mais vetores. Os diferentes vetores para o ATmega8 esto listados na tabela a seguir (o primeiro vetor no uma interrupo, mas sim o vetor de reset, que no faz operao com a pilha).

Tabela 1- Vetores de Interrupo do ATmega8

Note que a capacidade de reagir a eventos muito diferente entre os tipos. Os endereos so sequenciais, mas no idnticos para diferentes tipos. Consulte o datasheet para cada tipo de AVR. Quanto mais alto um vetor na lista, maior sua prioridade. Se dois ou mais componentes tm uma condio de interrupo ao mesmo tempo, o vetor com o menor endereo vence. A interrupo, com prioridade, inferior tem que esperar at que a primeira tenha sido tratada. Para evitar que as interrupes de menor prioridade interrompam a execuo do tratamento de uma interrupo de maior prioridade, a primeira interrupo desabilita a flag I (interrupo) do processador. A rotina deve reabilitar esta flag aps o trmino do trabalho. Todos os registradores usados no tratamento da interrupo devem ser reservados exclusivamente para aquele propsito, ou salvos na pilha e restaurados ao fim da rotina. Nunca altere o contedo de um registrador dentro de um tratamento de interrupo que for usado em outras partes do programa, sem restaur-lo antes.

Devido a todas estas necessidades, um exemplo mais sofisticado de tratamento de interrupo, mostrado aqui.

Cdigo 1

Parece um pouco complicado, mas um pr-requisito para usar interrupes sem produzir srios bugs. Ignore PUSH R16 e POP R16 se voc pode reservar este registrador exclusivamente para uso no tratamento das interrupes. Como o tratamento da interrupo no pode ser interrompido (a no ser que voc permita, no cdigo), todas as rotinas de tratamento de interrupo podem usar o mesmo registrador. Para configurar uma interrupo externa, necessrio atentar aos registradores MCUCR (Figura 2) e GICR (Figura 3). O registrador MCUCR contm os bits que configuram o modo de ativao das interrupes 0 e 1, que so associadas a eventos externos. Em outras palavras, alterando os bits ISCxx, segundo o External Interrupts de [Atmel 2004], pode-se configurar a interrupo para ocorrer quando h transio de subida ou de descida do sinal, ou mesmo quando ele se mantm em nvel baixo. J o registrador GICR aquele em que se permite a ocorrncia de determinada interrupo, por meio dos bits INT1 e INT0.

Figura 2- Registro de Controle MCU do ATmega8

Figura 3 Registro de Controle Geral de Interrupo do Atmega8

O trecho de cdigo abaixo ilustra um simples exemplo de utilizao de interrupes: utiliza-se um boto para alterar o estado de um LED. SIGNAL(SIG_INTERRUPT0){ // Funo que responde a interrupo externa 0 PORTB = ~PORTB; } void main(void){ // Configurando a interrupo MCUCR = _BV(ISC01) | _BV(ISC00); // Transio positiva em PD2 (INT0) GICR = _BV(INT0); // habilita interrupo INT0 sei(); // habilitao global das interrupes // Definindo Port B como sada DDRB = _BV(DDB1); for(;;){ } }
Cdigo 2

No programa acima, a macro SIGNAL(SIG_INTERRUPT0) permite definir a funo que far o processamento da interrupo externa 0 quando ela ocorrer. De acordo com o manual da biblioteca LibC, disponvel em \WinAVR\doc\avr-libc\avr-libc-user-manual\index.html, existem duas macros para definir a funo que ir tratar uma determinada interrupo: SIGNAL() e INTERRUPT(). A principal diferena entre as duas que INTERRUPT() define uma funo de processamento de interrupo que executada com a mscara global de interrupes ativada, o que permite que outras interrupes ocorram durante a execuo da rotina de interrupo. Se isto ocorrer, diz-se que o sistema permite ninho de interrupes. Com SIGNAL(), a mscara global de interrupes desativada, impedindo assim o atendimento de outras interrupes durante a execuo da rotina de interrupo. Se ocorrer uma solicitao de interrupo durante a execuo de uma rotina SIGNAL(), a mesma somente ser atendida quando a rotina atual se encerrar. A desvantagem do uso de SIGNAL() est em um maior atraso ao atendimento de interrupes, mas isto apresenta vantagem, pois reduz a necessidade de quantidade de memria RAM necessria para armazenar o contexto das instncias interrompidas.

Um outro uso das interrupes externas a emulao da instruo assembly SWI (Software Interrupt), que no existe no conjunto de instrues do AVR. Para tal, basta setar o pino PD2 como sada e ativar a interrupo INT0, por exemplo. Nesta situao, poder executar o cdigo da interrupo controlando o estado do pino PD2 por meio de instrues de escrita a este pino. Este mtodo de interrupo foi realizado dentro de sala de aula e as configuraes do Code Vision AVR so as seguintes:

Figura 4

Dando um zoom na parte destacada tem-se:

Figura 5

Na seta 1 mostramos a ativao da Interrupo INT0 e na seta 2 mostramos quando a interrupo ir atuar, no caso, na borda de descida (Falling Edge) do pino PD2. Abaixo mostrado o esquema do AVR ATmega8:

Figura 6

10

Você também pode gostar