> For the complete documentation index, see [llms.txt](https://bit-by-bit.gitbook.io/embedded-systems/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bit-by-bit.gitbook.io/embedded-systems/intel-msc-51/interrupcoes.md).

# Interrupções

Vimos que na condição de reset o sistema é iniciado a partir do endereço zero da memória de programa. Isso ocorre devido à localização dos vetores de interrupção. Especificamente, os vetores de interrupção ocupam posições fixas na memória de programa, e o reset é considerado uma "interrupção" estabelecida no endereço zero.

![Interrupções e Subrotinas no Intel 8051 - Localização dos vetores de interrupção \[1\].](https://www.embarcados.com.br/wp-content/uploads/2016/10/InterruptLocation.png)

Alguns periféricos podem gerar interrupções e para isso alguns endereços são reservados:

* IE0: 0x0003, Interrupção externa 0;
* TF0: 0x000B, Interrupção por overflow do timer 0;
* IE1: 0x0013, Interrupção externa 1;
* TF1: 0x001B, Interrupção por overflow do timer 1;
* RI e TI: 0x0023, Interrupção do canal serial.

Se a interrupção não é utilizada, seu endereço é considerado de propósito geral. Além disso, os vetores são espaçados em 8 bytes. Portanto, se a rotina de interrupção é curta, essa região de 8 bytes pode ser utilizada, já as rotinas longas podem utilizar instruções de jump.

### Registradores

As interrupções são controladas pelos registradores Interrupt Enable (IE) e Interrupt Priority (IP). O registrador IE, ilustrado na Figura abaixo, pode ser endereçado bit a bit e está localizado no endereço A8H. Esse registrador tem como função controlar as interrupções que o sistema deve atender.

![Registrador IE \[1\].](https://www.embarcados.com.br/wp-content/uploads/2016/10/SFR_IE.png)

* 7 - EA: Interrupções globais
* 4 - ES: Interrupção do canal serial
* 3 - ET1: Interrupção do temporizador/contador 1
* 2 - EX1: Interrupção externa 1
* 1 - ET0: Interrupção do temporizador/contador 0
* 0 - EX0: Interrupção externa 0

O registrador IP, ilustrado na Figura abaixo, também pode ser endereçado bit a bit e está localizado no endereço B8H. Esse registrador tem como função determinar a prioridade de uma fonte de interrupção, podendo ser alta ou baixa.

![Registrador IP \[1\].](https://www.embarcados.com.br/wp-content/uploads/2016/10/SFR_IP.png)

* 4 – PS: Prioridade da interrupção do canal serial
* 3 – PT1: Prioridade da interrupção do temporizador/contador 1
* 2 – PX1: Prioridade da interrupção externa 1
* 1 – PT0: Prioridade da interrupção do temporizador/contador 0
* 0 – PX0: Prioridade da interrupção externa 0

Para utilizar uma interrupção deve-se:

1. Escrever a rotina de interrupção com início no endereço do vetor correspondente. Isso é feito a partir da diretiva ORG \<endereço da interrupção>;
2. O bit correspondente a interrupção desejada deve ser habilitado no registrador IE;
3. O bit EA (Enable All) deve ser ativado no registrador IE.

Além desses dois registradores, é importante citar a função do Program Status Word (PSW). Esse registrador, ilustrado na Figura abaixo, contém as flags de estado da CPU, pode ser endereçado bit a bit e está localizado no endereço D0H.

![Registrador PSW \[1\].](https://www.embarcados.com.br/wp-content/uploads/2016/10/SFR_PSW.png)

* 7 - CY: Flag de Carry out
* 6 - AC: Flag auxiliar de Carry out - operações de adição
* 5 - F0: Flag de propóstio geral
* 4 e 3 - RS1 e RS0: Seleção do banco de registradores
* 2 - OV: Overflow de operações aritméticas
* 1 - x : Flag definida pelo usuário
* 0 - P: Flag de paridade – É definida pelo hardware (é igual a 1 quando o acumulador possui um número ímpar de bits em 1)

Cabe ressaltar que esse registrador determina qual banco de registradores está sendo utilizado. Isso implica na referência dos nomes dos registradores R0\~R7.

![Banco de Registradores \[1\].](https://www.embarcados.com.br/wp-content/uploads/2016/10/SFR_PSW_RB.png)

### O Sistema de Interrupção

A Figura 6 mostra o sistema de interrupção. Nessa figura é possível observar a função dos registradores Interrupt Enable (IE) e Interrupt Priority (IP). Mas o que acontece quando interrupções simultâneas são capturadas? Bom, nesse caso é necessário avaliar a prioridade da interrupção, e no caso de interrupções com a mesma prioridade a seguinte ordem de avaliação é estabelecida: primeiro IE0, em seguida TF0, IE1, TF1, RI e por ultimo, TI.

![Sistema de Interrupções \[1\].](https://www.embarcados.com.br/wp-content/uploads/2016/10/InterruptSystem.png)

Quando a interrupção é disparada, uma operação LCALL é realizada com destino ao vetor de interrupção correspondente. Durante a execução de LCALL, somente o contador de programas (PC) é armazenado na pilha. Portanto, os registradores PSW, Acumulado e B não são gravados na pilha durante a chamada de uma rotina de interrupção.

### O Ponteiro de Pilha (Stack Pointer)

O Stack Pointer é um registrador que possui uma função muito importante na CPU. Esse registrador, que é inicializado com o valor 07H durante a operação de Reset, tem como função gerenciar a chamada e o retorno de eventos de interrupção e chamada de subrotinas. O valor 07H indica que o registrador aponta para o endereço 07H, isto é, para o registrador R0 do segundo banco de registradores. Nesse sentido, o endereço armazenado em SP é chamado de topo da pilha. Para isso acontecer, duas instruções operam diretamente sobre esse registrador, são elas: PUSH e POP:&#x20;

* A operação PUSH faz com que um dado seja armazenado no endereço seguinte ao indicado pelo SP, isto é, no topo da pilha. Após essa operação o registrador SP é incrementado;
* A operação POP recupera o valor armazenado no topo da pilha. Após essa operação o registrador SP é decrementado.

Sabendo dessas duas operações, e tendo em vista um evento de interrupção, como será que a CPU gerencia o fluxo de execução do programa no momento de uma interrupção? Foi dito que durante a interrupção o programa é desviado por meio LCALL para o endereço do vetor de interrupção. Nesse momento, o contador de programa, que indica a próxima instrução que será buscada na memória, é armazenado na pilha.

Quando a instrução RETI é executada, o contador de programa é restabelecido com os valores que estavam armazenados na pilha, isto é, o endereço da próxima instrução que seria executada antes de ocorrer a interrupção! Esse mesmo procedimento ocorre com as outras instruções de chamada de subrotina, contudo a instrução de retorno deve ser RET, pois RETI é restrito ao contexto das interrupções. É importante lembrar que a pilha não fica limitada a essas funções, e pode ser utilizada normalmente pelo programador.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://bit-by-bit.gitbook.io/embedded-systems/intel-msc-51/interrupcoes.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
