Tempos de execu¸
c˜
ao, programa¸
c˜
ao modular
e processamento de interrup¸
c˜
oes
[email protected]
Conte´
udo
1 Objectivos 2
2 Introdu¸c˜ao 2
3 Ciclos-m´aquina 2
3.1 C´alculo do tempo de execu¸c˜ao . . . 3 3.2 Ajuste do tempo de execu¸c˜ao . . . 3
4 Segmentos e programa¸c˜ao modular 4
4.1 Segmentos absolutos . . . 4 4.2 Segmentos recoloc´aveis . . . 5 4.3 Nomes externos . . . 6
5 Interrup¸c˜oes 8
6 Problemas 8
1
Objectivos
Consolida¸c˜ao de conhecimentos sobre a linguagem assembly da fam´ılia 51. Familiariza¸c˜ao com a tempo-riza¸c˜ao das instru¸c˜oes, alguns conceitos sobre programa¸c˜ao modular e o processamento de interrup¸c˜oes, particularmente as interrup¸c˜oes externas suportadas por esta fam´ılia de microcontroladores.
2
Introdu¸
c˜
ao
Os conceitos que se apresentam neste gui˜ao s˜ao completamente independentes estando agrupados num ´
unico documento somente por motivos de conveniˆencia do calend´ario lectivo. Alguns dos problemas pro-postos requerem apenas a contabiliza¸c˜ao do tempo de execu¸c˜ao das instru¸c˜oes, outros envolvem somente o atendimento de pedidos de interrup¸c˜ao e outros requerem o dom´ınio dos dois conceitos. A todos eles pode e deve ser aplicada uma metodologia de programa¸c˜ao modular.
Estude com cuidado os exemplos apresentados e resolva os problemas propostos na sec¸c˜ao 6.1. Poder´a tirar as d´uvidas que lhe surgirem procurando o seu professor no hor´ario de atendimento estipulado. Quando sentir que j´a domina os conceitos tente resolver o problema proposto na sec¸c˜ao 6.2.
3
Ciclos-m´
aquina
O tempo de execu¸c˜ao de uma instru¸c˜ao assembly mede-se habitualmente em ciclos-m´aquina, embora alguns autores e documentos de fabricantes utilizem directamente os ciclos de rel´ogio. Seja indicado de uma maneira, seja de outra, o tempo de execu¸c˜ao de uma instru¸c˜ao ´e sempre inversamente proporcional `
a frequˆencia de funcionamento do microcontrolador. De facto, na maior parte dos elementos da fam´ılia 51 um ciclo-m´aquina ´e o tempo equivalente a 12 ciclos de rel´ogio1. Seja T
M o tempo correspondente a
um ciclo m´aquina e TX o tempo correspondente a um ciclo de rel´ogio, ent˜ao
TM = 12 · TX=
12 fX
onde fX representa a frequˆencia de funcionamento (frequˆencia de rel´ogio) do microcontrolador, imposta
pelo cristal utilizado. Para um cristal de 12MHz, valor habitual nesta fam´ılia de microcontroladores, a dura¸c˜ao de um ciclo-m´aquina ´e de 1µs. A tabela 1 apresenta os tempos de ciclo-m´aquina para diversos valores habituais da frequˆencia de funcionamento. O manual de programa¸c˜ao [1] indica a dura¸c˜ao das
fX – Frequˆencia do cristal (M Hz) TM – Ciclo-m´aquina (µs)
14.7456 0.813802
12.0000 1.00000
11.0592 1.08507
7.3728 1.62760
3.6864 3.25521
Tabela 1: Ciclo-m´aquina versus frequˆencia do cristal
instru¸c˜oes em ciclos-m´aquina, enquanto o resumo de instru¸c˜oes [2] d´a essa indica¸c˜ao em ciclos de rel´ogio. Uma e outra s˜ao poss´ıveis desde que se saiba qual delas se est´a a utilizar.
3.1
C´
alculo do tempo de execu¸
c˜
ao
Um primeiro exemplo permite elucidar o processo de c´alculo do tempo de execu¸c˜ao de um programa e de uma rotina:
---- 1 cseg at 0
0000 7F0C 2 mov r7,#12 ; (1) Valor inicial
0002 12000B 3 call square ; (2+N) Calcula o quadrado
0005 EF 4 mov a,r7 ; (1) Prepara
0006 C3 5 clr c ; (1) para dividir
0007 13 6 rrc a ; (1) por 2
0008 FF 7 mov r7,a ; (1) Resultado de novo em R7
8
0009 80FE 9 stop: jmp stop ; (2) O programa "encrava" aqui
10
11 ;============================================================== 12 ; Rotina square: calcula o quadrado de um n´umero inferior a 16
13 ; Entrada: R7
14 ; Sa´ıda: R7
15 ; Recursos estragados: A,B
16 ; Tempo de execu¸c~ao: 9 ciclos m´aquina
17 ;==============================================================
000B EF 18 square: mov a,r7 ; (1) Prepara para
000C F5F0 19 mov b,a ; (1) multiplicar R7
000E A4 20 mul ab ; (4) por ele pr´oprio
000F FF 21 mov r7,a ; (1) Resultado em R7
0010 22 22 ret ; (2)
23
24 end
Neste exemplo incluiu-se no coment´ario de cada instru¸c˜ao o n´umero de ciclos-m´aquina correspondentes, de acordo com o indicado no manual de programa¸c˜ao [1]. Facilmente se conclui (somando) que a rotina square demora 9 ciclos m´aquina a ser executada e o programa principal demora 16 ciclos m´aquina entre as linhas 2 e 7 inclusiv´e. Na linha 3, onde est´a referida a dura¸c˜ao 2+N, o 2 refere-se `a dura¸c˜ao da instru¸c˜ao call e o N `a dura¸c˜ao da rotina chamada (9 ciclos neste caso).
As instru¸c˜oes assembly desta fam´ılia de microcontroladores tˆem um tempo de execu¸c˜ao que varia entre um ciclo-m´aquina (por exemplo para as instru¸c˜oes rrc a, mov a,#data, etc.) e quatro ciclos-m´aquina (para as instru¸c˜oes mul e div). O conhecimento do tempo de execu¸c˜ao das instru¸c˜oes permite conhecer (e em alguns casos ajustar) o tempo de execu¸c˜ao das rotinas e dos programas.
3.2
Ajuste do tempo de execu¸
c˜
ao
Considere-se um segundo exemplo, um pouco mais complexo do que o anterior, no qual aparece uma rotina que se pretende de dura¸c˜ao conhecida:
1 ;============================================================== 2 ; Rotina wait1ms: espera 1ms (supondo f=12MHz)
3 ; Entrada: R7
4 ; Sa´ıda: nenhuma
5 ; Recursos estragados: A,B
6 ; Tempo de execu¸c~ao [incluindo chamada]:
7 ; [2]+1+R7(1+1+1+2)+2 = 5R7+5 = 5(R7+1) ciclos m´aquina 8 ;==============================================================
0000 7FC7 9 wait1ms: mov r7,#199 ; (1) Iniciar contador
0002 00 10 next: nop ; (1) Gastar
0003 00 11 nop ; (1) algum
0004 00 12 nop ; (1) tempo
0005 DFFB 13 djnz r7,next ; (2) Repetir at´e R7=0
Algumas considera¸c˜oes relativas a este exemplo:
1. A instru¸c˜ao nop (linhas 10, 11 e 12) n˜ao faz nada, apenas gasta tempo. ´E aqui utilizada para ajustar o tempo total de execu¸c˜ao da rotina.
2. No c´alculo do tempo de execu¸c˜ao (linha 7) incluiu-se o tempo gasto pela instru¸c˜ao call (2 ciclos-m´aquina) que dever´a existir no programa principal para chamar esta rotina. Este rigor no c´alculo poder´a ser dispens´avel em determinadas aplica¸c˜oes, particularmente se as temporiza¸c˜oes em causa forem elevadas.
3. O valor inicial do contador (linha 9) ´e facilmente calculado em fun¸c˜ao do tempo de execu¸c˜ao pretendido. A 12 MHz, cada ciclo-m´aquina dura 1µs pelo que 1ms equivale a 1000 ciclos m´aquina. Logo,
5(R7 + 1) = 1000 ⇔ R7 =1000
5 − 1 = 199
Se a frequˆencia fosse diferente seria necess´ario inicializar o registo R7 com um outro valor. A t´ıtulo de exemplo veja-se o caso de fX= 7.3728 MHz,
TM = 12 fX = 1.6276µs; 1ms = 1000 1.6276= 614.4 ciclos 5(R7 + 1) = 614.4 ⇔ R7 = 614.4 5 − 1 = 121.88 ≈ 122
Neste caso o tempo conseguido n˜ao ser´a exactamente 1ms mas o erro cometido ´e pequeno, podendo at´e ser irrelevante para determinadas aplica¸c˜oes. De facto, com R7 = 122 obt´em-se um tempo de execu¸c˜ao de 1.00098ms, j´a incluindo o tempo de chamada, ou seja, um erro inferior a 0.1%.
4
Segmentos e programa¸
c˜
ao modular
Nesta sec¸c˜ao faz-se uma breve revis˜ao e sistematiza¸c˜ao dos segmentos absolutos, apresenta-se um outro tipo de segmento – o segmento recoloc´avel – e apresenta-se tamb´em uma metodologia que permite dis-tribuir um programa por diferentes ficheiros.
4.1
Segmentos absolutos
Ao programar em assembly o programador pode escolher os endere¸cos onde ficar´a o programa e onde ficar˜ao os dados. Para isso ´e necess´ario definir segmentos de mem´oria. J´a s˜ao conhecidos os segmentos absolutos: zonas de mem´oria com endere¸co inicial fixo. S˜ao definidos recorrendo, entre outros, aos comandos CSEG, DSEG e XSEG cuja sintaxe se depreende do exemplo apresentado:
; === Vari´aveis ======================================================== DSEG AT 40h ; Segmento com in´ıcio no endere¸co 40h da MDI
total: DS 2 ; Reserva dois bytes
contador: DS 1 ; Reserva um byte
XSEG AT 1000h ; Segmento com in´ıcio no endere¸co 1000h da MDE
points: DS 100 ; Reserva 100 bytes em MDE
; === Programa principal =============================================== CSEG AT 0000h ; Segmento no endere¸co 0000h da mem´oria
; --- Rotinas de E/S ---CSEG AT 007Fh ; Segmento no endere¸co 007Fh da MP
. . .
; === Mensagens do sistema ============================================= CSEG AT 0100h ; Segmento no endere¸co 0100h da MP pin_msg: DB "PIN: ",CR,LF ; Preenche 7 bytes em MP
No exemplo apresentado, a vari´avel total ocupa os endere¸cos 40h e 41h da mem´oria de dados interna e a vari´avel contador fica no endere¸co 42h. A vari´avel points ´e um vector de 100 bytes em mem´oria de dados externa, ocupando os endere¸cos 1000h a 1063h. O programa principal come¸ca no endere¸co 0000h da mem´oria de programas e h´a um conjunto de rotinas que ocupam uma zona com in´ıcio em 007Fh da mem´oria de programas. No endere¸co 0100h da mem´oria de programas residem vectores de constantes que representam as mensagens do sistema.
4.2
Segmentos recoloc´
aveis
Em programas complexos a atribui¸c˜ao de segmentos ´e uma tarefa delicada pois ´e necess´ario garantir que n˜ao haja sobreposi¸c˜ao de segmentos do mesmo tipo. Para evitar esse trabalho e facilitar a reutiliza¸c˜ao de c´odigo ´e recomend´avel trabalhar sempre que poss´ıvel com segmentos ditos recoloc´aveis. A defini¸c˜ao de um segmento recoloc´avel faz-se com o comando segment e a sua activa¸c˜ao com o comando rseg. O exemplo ilustra a sintaxe:
prog segment code ; Segmento de c´odigo recoloc´avel msgs segment code ; Segmento de c´odigo recoloc´avel vars segment data ; Segmento de dados recoloc´avel em MDI
rseg vars ; Activa o segmento dados3
total: DS 2 ; Reserva dois bytes em MDI
stack:
; === Entrada no programa principal ==================================== cseg at 0000h ; Segmento no endere¸co 0000h da mem´oria
jmp main ; de programas (MP)
. .
; --- Programa e subrotinas ---rseg prog ; Activa o segmento prog (em MP)
main: mov sp,#stack-1
. . .
; === Mensagens do sistema =============================================
rseg msgs ; Activa o segmento msgs
pin_msg: DB "PIN: ",CR,LF ; Preenche 7 bytes algures em MP
4.3
Nomes externos
A verdadeira utilidade dos segmentos recoloc´aveis revela-se em programas de maior complexidade nos quais, para aumentar a efic´acia do processo de desenvolvimento, ´e recomend´avel reutilizar c´odigo j´a desenvolvido anteriormente bem como a estruturar novo c´odigo em m´odulos que possam vir a ser utilizados em trabalhos futuros.
Quando a dimens˜ao e complexidade de um problema s˜ao consider´aveis2 ´e recomend´avel estruturar a
solu¸c˜ao em m´odulos. Neste contexto ´e frequente a necessidade de aceder a rotinas e vari´aveis que est˜ao em diferentes m´odulos, ou seja, frequentemente ´e necess´ario referenciar nomes simb´olicos externos. Para isso existem os qualificadores extrn e public, cuja sintaxe se depreende do exemplo seguinte, composto por dois m´odulos – MAIN.A51 com o programa principal e algumas rotinas, e ROT.A51 com as restantes rotinas:
; --- MAIN.A51 ---1 rotinas segment code ; Segmento recoloc´avel em MP
2 vars segment data ; Segmento recoloc´avel em MDI 3
---- 4 rseg vars ; Activa o segmento de dados declarado 0000 5 total: ds 2
0002 6 contador: ds 1 0003 7 teste: ds 1
8
9 public total,contador ; Estes nomes v~ao ser conhecidos de 10 public start ; outros m´odulos
11
12 extrn code(initvars,initsys) ; Rotinas de outros m´odulos 13 extrn data(x,y) ; Vari´aveis definidas noutros 14 extrn xdata(z) ; m´odulos (data=MDI, xdata=MDE) 15 extrn number(SIZE) ; Constantes de outros m´odulos 16
17
---- 18 cseg at 0000h ; Programa principal come¸ca em 0000h 0000 75812F 19 start: mov sp,#2Fh ; Stack come¸ca em 30h
0003 120000 F 20 lcall initvars ; Inicializa vari´aveis 0006 120000 F 21 lcall initsys ; Inicializa resto do sistema 0009 E500 F 22 mov a,x ; Acc fica com o valor da vari´avel x 000B 900000 F 23 mov dptr,#z ; DPTR aponta primeira posi¸c~ao de z
24 ; . 25 ; . 26
---- 27 rseg rotinas ; Activa o segmento rotinas 28
0000 3098FD 29 getch: jnb ri,getch ; Esta rotina ´e local 0003 C298 30 clr ri
0005 E599 31 mov a,sbuf 0007 22 32 ret
33 ; . 34 ; . 35
36 end
Algumas considera¸c˜oes sobre o m´odulo MAIN.A51:
1. A declara¸c˜ao dos nomes total e contador como p´ublicos (linha 9) permite que eles sejam conhecidos fora deste m´odulo. Em consequˆencia pode concluir-se que das 3 vari´aveis declaradas nas linhas 5 a 7, teste ´e local a este m´odulo enquanto que total e contador podem ser acedidas por outros m´odulos.
2. O mesmo se pode dizer do segmento de c´odigo identificado pela etiqueta start. Pelo facto de ter sido declarada p´ublica (linha 10) ser´a poss´ıvel referenci´a-la a partir de outros m´odulos.
2Embora a complexidade de um problema se possa exprimir em termos formais, nestas aulas ficaremos apenas por uma
3. A rotina getch n˜ao ´e p´ublica, ou seja, ´e local a este m´odulo. Por este motivo n˜ao poder´a ser chamada de outro m´odulo.
4. Nas linhas 12 a 15 est´a a indica¸c˜ao dos nomes simb´olicos externos (isto ´e, definidos noutros m´odulos como p´ublicos) que este m´odulo vai aceder. Para cada um ´e necess´ario indicar o tipo respectivo.
; --- ROT.A51 ---1 public initvars,initsys ; Estes nomes v~ao ser conhecidos de 2 public x,y,z,SIZE ; outros m´odulos
3
4 extrn code(start) ; Rotinas de outros m´odulos 5 extrn data(total,contador) ; Vari´aveis de outros m´odulos 6
7 rotinas segment code ; Segmento recoloc´avel em MP 8 vars segment data ; Segmento recoloc´avel em MDI 9 xvars segment xdata ; Segmento recoloc´avel em MDE 10
0064 11 SIZE equ 100 12
---- 13 rseg vars ; Activa o segmento vars 0000 14 x: ds 1
0001 15 y: ds 1 0002 16 cont: ds 1
17
---- 18 rseg xvars ; Activa o segmento xvars 0000 19 z: ds SIZE
20 21
---- 22 rseg rotinas ; Activa o segmento rotinas 23 0000 E4 24 initvars: clr a 0001 F500 F 25 mov x,a 0003 F500 F 26 mov y,a 0005 F500 F 27 mov contador,a 0007 F500 F 28 mov total,a 0009 F500 F 29 mov total+1,a 30 000B 750064 F 31 mov cont,#SIZE 000E 900000 F 32 mov dptr,#z 33
0011 F0 34 clean: movx @dptr,a 0012 A3 35 inc dptr 0013 D500FB F 36 djnz cont,clean 37 ; . 38 ; . 0016 22 39 ret 40 0017 C3 41 initsys: clr c 0018 E4 42 clr a 43 ; . 44 ; . 0019 22 45 ret 46 47 end
Algumas considera¸c˜oes sobre o m´odulo ROT.A51:
1. Repare-se que os nomes que em MAIN.A51 eram extrn aqui s˜ao public e vice-versa.
2. A etiqueta clean (linha 34) ´e um nome local. Poder˜ao existir outros m´odulos com o mesmo nome local definido sem que isso provoque conflitos.
Considera¸c˜oes gerais:
1. Deve existir um segmento de c´odigo absoluto com in´ıcio no endere¸co 0000h que garante o arranque do microcontrolador. Nada impede que outros segmentos de c´odigo possam ser recoloc´aveis. 2. Quando se referem nomes simb´olicos externos ou definidos em segmentos de mem´oria recoloc´aveis,
31 e 32 de ROT.A51). De modo semelhante, os endere¸cos das instru¸c˜oes residentes em segmentos de c´odigo recoloc´aveis s˜ao referidos ao in´ıcio do respectivo segmento (linhas 29 a 32 de MAIN.A51 e linhas 24 a 39 de ROT.A51). Os verdadeiros endere¸cos podem ser consultados no mapa de s´ımbolos gerado automaticamente (ficheiro .m51).
5
Interrup¸
c˜
oes
´
E essencial perceber bem o conceito de interrup¸c˜ao para ser poss´ıvel analisar um sistema baseado num microprocessador ou num microcontrolador.
Uma interrup¸c˜ao acontece quando um circuito exterior ao CPU3pede para ser atendido. Por defini¸c˜ao ´e
um acontecimento inesperado para o CPU e como tal ele deve estar sempre preparado para interromper o funcionamento normal e atender os pedidos de interrup¸c˜ao que lhe v˜ao surgindo. No caso da fam´ılia 51 as fontes de interrup¸c˜ao s˜ao cinco – duas externas ao microcontrolador e trˆes internas. D´a-se um pedido de interrup¸c˜ao sempre que:
• os pinos INT0 (P3.2) ou INT1 (P3.3) v˜ao ao n´ıvel l´ogico zero;
• acontece um overflow (ou rollover) das contagens efectuadas pelo Timer 0 ou pelo Timer 1; • se acaba de receber ou enviar um novo byte pela interface s´erie.
Ainda que estes acontecimentos gerem sempre um pedido de interrup¸c˜ao, o CPU pode ou n˜ao atendˆe-lo e, no caso de haver mais do que um pedido pendente, pode atribuir diferentes prioridades ao atendimento. Esta gest˜ao do sistema de interrup¸c˜oes ´e efectuada recorrendo a dois registos de configura¸c˜ao: o registo IE e o registo IP. O primeiro permite definir quais os pedidos que ser˜ao atendidos e o segundo qual a prioridade do atendimento. Parte de um outro registo (o registo TCON) permite ainda configurar o modo como s˜ao reconhecidos os pedidos de interrup¸c˜ao externos: quando os pinos INT0 e INT1 est˜ao no n´ıvel l´ogico zero ou quando se d´a uma transi¸c˜ao descendente nesses pinos.
O atendimento dos pedidos de interrup¸c˜ao da fam´ılia 51 baseia-se na invoca¸c˜ao autom´atica4 de rotinas
residentes em endere¸cos pr´e-definidos, habitualmente designadas por rotinas de atendimento. Este mecan-ismo obriga a utilizar segmentos de c´odigo absolutos para as rotinas de atendimento ou, pelo menos, para o in´ıcio dessas rotinas.
6
Problemas
Para a resolu¸c˜ao destes problemas ser´a necess´ario conhecer o tempo de execu¸c˜ao das instru¸c˜oes. No resumo de instru¸c˜oes [2] esse tempo est´a expresso em ciclos de rel´ogio; pelo contr´ario, no manual de programa¸c˜ao [1] esse tempo est´a expresso em ciclos-m´aquina.
Todos os problemas deste gui˜ao devem ser testados no simulador dScope–51. Na janela dos registos aparece um contador de ciclos m´aquina e um rel´ogio de tempo simulado que permitem confirmar e/ou calibrar as temporiza¸c˜oes. A frequˆencia de funcionamento ´e definida pelo comando xtal=n, dado na janela de comandos do simulador, onde n representa a frequˆencia pretendida, expressa em Hz; por exemplo o comando xtal=3686400 define 3.6864Mhz como frequˆencia de trabalho.
3No caso dos microcontroladores esse circuito pode estar inclu´ıdo na mesma pastilha de sil´ıcio mas em termos
arquitec-turais ´e externo `a unidade central de processamento.
6.1
Para preparar em casa e fazer na aula
1. Considere j´a existente a rotina delay5 que demora exactamente 5ms a ser executada e n˜ao estraga nenhum recurso. Recorrendo a essa rotina escreva a rotina delay500 que demora aproximadamente 0.5s a ser executada.
2. Escreva a rotina delay5 que demora exactamente 5ms a ser executada e n˜ao estraga nenhum recurso, considerando como frequˆencia de trabalho:
(a) 12 MHz (b) 11.0592 MHz
(c) 3.6864 MHz
3. Recorrendo `a rotina delay500 escreva um programa que de 0.5 em 0.5s incrementa a vari´avel cont, residente em mem´oria de dados interna.
4. Altere o programa anterior de modo a que sempre que se provoca uma interrup¸c˜ao externa em INT0 a ac¸c˜ao sobre a vari´avel cont alterne entre incrementar e decrementar. Nota: utilize uma vari´avel auxiliar (por exemplo a flag F0 no registo PSW), complementada pela rotina de atendimento da interrup¸c˜ao, que indica ao programa principal se a vari´avel cont deve ser incementada (F0=1) ou decrementada (F0=0).
5. Acrescente ao programa anterior a seguinte funcionalidade: sempre que se provoca uma interrup¸c˜ao externa em INT1 os pedidos de interrup¸c˜ao em INT0 comutam entre atendidos e n˜ao atendidos.
6.2
Para ir mais longe
Este problema requer um bom dom´ınio dos conceitos abordados ao longo do gui˜ao.
6. Considere uma linha de lavagem de garrafas em que o tapete transportador ´e controlado por um motor el´ectrico que roda a uma velocidade nominal de 300 rpm. O motor ´e comandado por um sistema electr´onico baseado num microcontrolador da fam´ılia 51 que controla o arranque e a paragem e detecta eventuais sobrecargas e encravamentos nos diversos org˜aos mecˆanicos do tapete. O sistema disp˜oe de:
• uma tecla para arrancar o motor e outra para o fazer parar,
• dois indicadores luminosos: um indica que o motor ainda est´a em fase de arranque e o outro indica que o motor atingiu a sua velocidade nominal de funcionamento,
• uma sirene.
A sirene, as teclas e os indicadores s˜ao activos a zero.
Carregando em START o motor deve come¸car a andar e o indicador de arranque deve acender. Uma vez atingida a velocidade nominal de funcionamento o indicador de arranque apaga e o indicador de velocidade nominal acende. Carregando em STOP o motor deve parar e todos os indicadores devem apagar. Caso se dˆe uma sobrecarga ou at´e um encravamento mecˆanico que possa danificar o motor, este deve ser desligado e deve ser activada a sirene na forma de 100 ms de som, 100 ms de silˆencio. A sirene ´e desactivada quando se carrega em STOP.
(a) Supondo que o sensor est´a ligado ao pino INT0 (P3.2), escreva a rotina mede que, incremen-tando de 1 em 1 ms a vari´avel tempo mede o tempo que decorre entre duas interrup¸c˜oes consecutivas. Nota: se tempo ultrapassar o valor 255 deve ser activada a flag CY.
(b) Escreva a rotina alarme que, recorrendo `a rotina delay5, implemente o alarme descrito an-teriormente, isto ´e, ligue e desligue a sirene `a frequˆencia de 5 Hz at´e que a tecla STOP seja actuada.
(c) Escreva o programa que controla todo o sistema por forma a respeitar as funcionalidades descritas.