Atividade de laboratório 003 Prof: Carlos Eduardo de Brito Novaes 29 de abril de 2016 Alunos RA Nome Curso Semestre Resumo Atividade da unidade curricular: Laboratório Integrado de Microprocessadores e Microcontroladores. O objetivo desta atividade é praticar e escrever funções na linguagem C para a plataforma Arduíno. Parte I Descrição No link https://123d.circuits.io/circuits/2057110-atividade_laboratorio_003 esta disponível uma montagem com o Arduíno Uno. Vamos utilizar essa montagem para trabalhar com interrupções externas. O seguinte código já esta programado no Arduíno 1
Rotinas setup() e loop() / / I n c l u i a b i b l i o t e c a p a r a a c e s s a r o d i s p l a y / / I n s t r u ç õ e s de uso e exemplos em h t t p s : / / www. a r d u i n o. cc / en / R e f e r e n c e / L i q u i d C r y s t a l # i n c l u d e < L i q u i d C r y s t a l. h> / / i n i c i a l i z a e c o n f i g u r a os p i n o s u s a d o s p a r a c o n t r o l a r o D i s p l a y / / DisplayLCD é d e c l a r a d a como uma v a r i á v e l g l o b a l e / / p oderá s e r chamada de q u a l q u e r o u t r a f u n ç ã o. L i q u i d C r y s t a l DisplayLCD ( 1 3, 12, 11, 10, 9, 8 ) ; / / d e f i n e nomes p a r a os p i n o s de E / S u t i l i z a d o s # d e f i n e s a i d a 0 # d e f i n e e n t r a d a A 2 # d e f i n e e n t r a d a B 3 / / v a r i á v e l g l o b a l v o l a t i l e i n t c o n t a d o r ; void s e t u p ( ) { / / c o n f i g u r a o D i s p l a y que estamos usando, 16 c o l u n a s e 2 l i n h a s. DisplayLCD. b e g i n ( 1 6, 2 ) ; / / c o n f i g u r a p i n o s de s a i d a pinmode ( s a i d a, OUTPUT ) ; / / c o n f i g u r a p i n o s de e n t r a d a / / pinmode ( entradaa, INPUT ) ; / / pinmode ( entradab, INPUT ) ; / / c o n f i g u r a i n t e r r u p ç õ e s / / RISING : T r a n s i ç ã o de s u b i d a / / FALLING : T r a n s i ç ã o de d e s c i d a / / CHANGE: Mudança de n í v e l l ó g i c o a t t a c h I n t e r r u p t ( d i g i t a l P i n T o I n t e r r u p t ( 2 ), i s r _ p i n o 2, RISING ) ; a t t a c h I n t e r r u p t ( d i g i t a l P i n T o I n t e r r u p t ( 3 ), i s r _ p i n o 3, RISING ) ; / / p o s i c i o n a o c u r s o r do d i s p l a y na c o l u n a 0 e na l i n h a 0 DisplayLCD. s e t C u r s o r ( 0, 0 ) ; / / E s c r e v e uma mensagem de boas v i n d a s DisplayLCD. p r i n t ( Boa n o i t e ) ; DisplayLCD. p r i n t ( Turma ) ; void loop ( ) { DisplayLCD. s e t C u r s o r ( 0, 1 ) ; DisplayLCD. p r i n t ( c o n t a d o r = ) ; DisplayLCD. p r i n t ( c o n t a d o r ) ; DisplayLCD. p r i n t ( ) ; c o n t a d o r ++; d e l a y ( 2 0 0 ) ; / / d e s a b i l i t a a i n t e r r u p ç ã o do pino 2 se a contagem c h e g a r a 20 / / i f ( c o n t a d o r ==20){ / / d e t a c h I n t e r r u p t ( d i g i t a l P i n T o I n t e r r u p t ( 2 ) ) ; / / / / d e s a b i l i t a a i n t e r r u p ç ã o do pino 3 se a contagem c h e g a r a 120 / / i f ( c o n t a d o r ==120){ / / d e t a c h I n t e r r u p t ( d i g i t a l P i n T o I n t e r r u p t ( 3 ) ) ; / / 2
Rotinas de serviço de interrupção (ISRs ou Interrupt Service Routines) void i s r _ p i n o 2 ( ) { c o n t a d o r = 0 ; void i s r _ p i n o 3 ( ) { c o n t a d o r = 100; Interrupções externas no Arduíno Uno Esta atividade deve levar o aluno a compreender o conceito de interrupções e como elas funcionam no Arduíno Uno. Sabemos que o Arduíno Uno possui dois pinos que podem ser configurados para aceitar interrupções externas. Além disso, quatro modos de operação podem ser utilizados, a saber: LOW: Ativa a interrupção quando o pino esta em nível lógico baixo RISING: Ativa a interrupção quando o nível lógico presente no pino passa de baixo para alto FALLING: Ativa a interrupção quando o nível lógico presente no pino passa de alto para baixo CHANGE: Ativa a interrupção quando há mudança no nível lógico presente no pino. OBSERVAÇÃO: Por algum motivo, provavelmente um BUG no simulador, o modo LOW não esta funcionando. Neste programa declaramos uma variável global e volátil do tipo inteiro, que será acessada pelo programa principal e pelas rotinas de serviço de interrupção v o l a t i l e i n t c o n t a d o r ; Dentro da rotina setup(), fazemos a inicialização do display de cristal líquido. Em seguida utilizamos as rotinas attachinterrupt para configurar as interrupções nos pinos 2 e 3. a t t a c h I n t e r r u p t ( d i g i t a l P i n T o I n t e r r u p t ( 2 ), i s r _ p i n o 2, FALLING ) ; a t t a c h I n t e r r u p t ( d i g i t a l P i n T o I n t e r r u p t ( 3 ), i s r _ p i n o 3, FALLING ) ; Além disso, é necessário declarar e implementar as rotinas de serviço de interrupção, no caso isr_pino2 e isr_pino3. Para nossa atividade, ao ocorrer uma interrupção no pino 2, o contador será zerado. Já ao ocorrer uma interrupção no pino 3, o contador deve ser feito igual a 100. void i s r _ p i n o 2 ( ) { c o n t a d o r = 0 ; void i s r _ p i n o 3 ( ) { c o n t a d o r = 100; Finalmente, dentro da rotina loop efetuamos as tarefas de incrementar o contador, realizar um delay de 200ms e atualizar o valor no display. Além disso, será possível desabilitar as interrupções descomentando (retirando as barras duplas // que iniciam as linhas) as linhas 52, 53, 54, 56, 57 e 58, por meio da rotina detachinterrupt / / d e s a b i l i t a a i n t e r r u p ç ã o do pino 2 se a contagem c h e g a r a 20 i f ( c o n t a d o r ==20){ d e t a c h I n t e r r u p t ( d i g i t a l P i n T o I n t e r r u p t ( 2 ) ) ; / / d e s a b i l i t a a i n t e r r u p ç ã o do pino 3 se a contagem c h e g a r a 120 i f ( c o n t a d o r ==120){ d e t a c h I n t e r r u p t ( d i g i t a l P i n T o I n t e r r u p t ( 3 ) ) ; 3
1 Verifique o comportamento do programa Acesse a montagem disponível em https://123d.circuits.io/circuits/2057110-atividade_laboratorio_003 e duplique o projeto para sua conta na plataforma 123d.circuits.io. Dessa maneira será possível editar o projeto. 1.1 Inicie a simulação e responda: 1. O que você observa no display? 2. Ao pressionar o botão da esquerda, geramos uma interrupção no pino 2. O que se observa no display? 3. Ao pressionar o botão da esquerda, geramos uma interrupção no pino 3. O que se observa no display? 2 Sobre os modos de operação das interrupções externas Vamos verificar o comportamento das interrupções conforme o modo de operação. 2.1 Inicialmente as interrupções foram configuradas como sendo do tipo RISING. Inicie a simulação e responda: 1. Com a simulação rodando, aguarde a contagem por alguns instantes e então, pressione e mantenha pressionado o botão da esquerda. O que você observa no display? 2. Em seguida solte o botão da esquerda. A contagem foi alterada? 3. Com a simulação rodando, aguarde a contagem por alguns instantes e então, pressione e mantenha pressionado o botão da direita. O que você observa no display? 4. Em seguida solte o botão da direita. A contagem foi alterada? 4
2.2 Modifique o modo de operação para FALLING, para isso, basta modificar o último parâmetro passado para a rotina attachinterrupt, nas linhas 32 e 33. Inicie a simulação e responda: 1. Com a simulação rodando, aguarde a contagem por alguns instantes e então, pressione e mantenha pressionado o botão da esquerda. O que você observa no display? 2. Em seguida solte o botão da esquerda. A contagem foi alterada? 3. Com a simulação rodando, aguarde a contagem por alguns instantes e então, pressione e mantenha pressionado o botão da direita. O que você observa no display? 4. Em seguida solte o botão da direita. A contagem foi alterada? 2.3 Modifique o modo de operação para CHANGE, para isso, basta modificar o último parâmetro passado para a rotina attachinterrupt, nas linhas 32 e 33. Inicie a simulação e responda: 1. Com a simulação rodando, aguarde a contagem por alguns instantes e então, pressione e mantenha pressionado o botão da esquerda. O que você observa no display? 2. Em seguida solte o botão da esquerda. A contagem foi alterada? 3. Com a simulação rodando, aguarde a contagem por alguns instantes e então, pressione e mantenha pressionado o botão da direita. O que você observa no display? 4. Em seguida solte o botão da direita. A contagem foi alterada? 5
3 Desabilitando as interrupções Durante a operação do programa principal, é possível desabilitar uma ou mais interrupções, fazendo uso da rotina detachinterrupt. Nesta atividade, vamos descomentar as linhas 52, 53, 54, 56, 57 e 58. O trecho de código descomentado irá desabilitar a interrupção do pino 2 quando a contagem for igual a 20 e irá desabilitar a interrupção no pino 3 quando a contagem for igual a 120. Note que uma vez que a interrupção foi desabilitada pela rotina detachinterrupt, ela permanece assim até que seja novamente configurada por outra chamada à rotina attachinterrupt. 3.1 Modifique o modo de operação para RISING, alterando o último parâmetro passado para a rotina attachinterrupt, nas linhas 32 e 33. Em seguida, descomente as linhas 52, 53, 54, 56, 57, 58 e inicie a simulação. Responda: 1. Com a simulação rodando, pressione o botão da esquerda antes da contagem atingir 20. O que se observa? 2. Aguarde a contagem atingir 20 para pressionar o botão da esquerda. O que se observa? 3. Antes da contagem atingir o valor 120, pressione o botão da direita. O que se observa? 4. Aguarde a contagem atingir o valor 120 e pressione o botão da direita. O que se observa? 4 Modifique o código da rotina de serviço de interrupção associada ao pino 2, de modo que o led conectado ao pino 0 acenda sempre que a contagem for par, e se apague caso a contagem seja impar. Escreva abaixo a nova implementação. Note que, para efeito de teste no simulador, será interessante aumentar o tempo de delay na linha 49, de forma a tornar a contagem mais lenta. Dica: o operador de módulo (ou resto), representado pelo sinal % retorna o resto de uma divisão inteira. Assim, se 5/2 retorna o valor inteiro dois, 5%2 retorna o valor inteiro um (referente ao resto da divisão de 5 por 2). Podemos utilizar o operador de módulo em uma divisão por dois, para determinar se a variável contador armazena um valor par ou impar. Assim, contador%2 será igual a zero sempre que o valor armazenado em na variável contador for par. 6