Aula 02 - Sistemas Embarcados Profissionais

Fazer download em pdf ou txt
Fazer download em pdf ou txt
Você está na página 1de 49

Curso de desenvolvimento profissional

de sistemas embarcados

Pedro Bertoleti

e-stude.com
Tópicos

 O que são interrupções?

 Interrupções externas: o que são e para que servem?

 O que são timers?

 Como utilizar timers visando boa performance de software


embarcado

e-stude.com
Observação 1
Esta aula tem todos os seus códigos feitos para microcontroladores
PIC utilizando a IDE MPLAB X, linguagem C e compilador XC8
(compilador grátis feito pela própria fabricante do PIC, a Microchip).

Como o foco deste curso não é ministrar lições de programação PIC


especificamente, recomendo a leitura destes artigos para
familiarização básica com programação PIC (para maior entendimento
e para conseguir realizar os exercícios da aula):

 http://www.embarcados.com.br/microchip-mplab-x-e-mplab-xc8-1/
 http://www.embarcados.com.br/microchip-mplab-x-e-mplab-xc-
parte-2/

e-stude.com
Observação 2
Todos os exercícios desta aula são simulados no Proteus 7.7 SP2.

Para maiores informações sobre como adquirir e utilizar esta


ferramenta, por favor consulte a página oficial do produto.

e-stude.com
Antes de começar, uma observação importantíssima!

Os microcontroladores possuem elementos chamados REGISTRADORES.

Um registrador é um espaço de memória (geralmente de 1 byte ou 1 word)


dedicado exclusivamente a uma função do microcontrolador (e acessivel somente
pelo software embarcado executado pelo microcontrolador).

Por exemplo, as configurações gerais de um microcontrolador, dados recebidos


em comunicações seriais, resultados de operações matemáticas e flags
importantes do microcontrolador (incluindo quais interrupções foram geradas) são
registradores.

Utilizar bem os registradores de um microcontrolador é essencial para um bom


software embarcado.

e-stude.com
Interrupções

e-stude.com
Interrupções – o que são?
Para ilustrar o que são interrupções, considere o seguinte exemplo: você é um
professor de uma sala com 40 alunos. Para sanar as dúvidas de todos, há duas
possibilidades:

Método 1: perguntar a todos os alunos (de Método 2: ficar atento para verificar se
forma periódica), um por um, se houve alguém levantou a mão e, se ocorer,
alguma dúvida. Se houver dúvida, saná-la. perguntar qual é a dúvida e saná-la.

Vantagens deste método:


Problemas deste método: - Gasta-se pouco tempo para atender às
- Gasta-se muito tempo dúvidas
- O método é ineficiente, uma vez que - Somente solicitações necessárias /
todos os alunos irão ter que esperar a perguntas necessárias são respondidas
rodada de checagem de dúvidas e quase
nunca todos os alunos tem dúvidas ao
mesmo tempo.

Método: Pooling Método: Interrupção

e-stude.com
Interrupções – o que são

Portanto, de forma geral:

Pooling: metodologia que verifica determinadas coisas / toma ações de tempos em


tempos, uma por uma.
Usa uma parcela preciosa do tempo de processamento para verificações, algumas
vezes, desnecessárias.

Interrupção: verificar somente as coisas que se manifestarem / requisitarem


verificação no momento.
Utiliza somente o necessário de tempo de processamento para atender às
solicitações, ficando o restante do tempo livre para processar coisas mais
importantes.

e-stude.com
Interrupções

Entretanto, em um software embarcado podemos ter as duas metodologias


combinadas (pooling e interrupção) para fins distintos.
Neste caso, seguem exemplos simples de quando se utiliza uma ou outra
metodologia:
Acontecimentos esperados: Acontecimentos inesperados:

- Execução de uma função que não - Fazer alguma ação ao se


gasta muito tempo para executar apertar um botão
- Leitura de um sensor em um - Tratar um dado que acabou de
momento desejado ser recebido (via comunicação
- Acionamento ou desacionamento serial, por exemplo)
de outputs em um momento - Tratar alguma coisa após certa
desejado temporização

POOLING INTERRUPÇÃO

e-stude.com
Interrupções - tipos

Em se tratando de sistemas embarcados, há dois tipos de interrupções:

Interrupções de hardware:
Interrupções geradas por estímulos no hardware do sistema, fazendo uma
determinada ação somente mediante este estímulo (não sendo necessário verificar
toda hora o hardware, e sim “esperar ser avisado pela interrupção”).
Tais interrupções são chamadas de IRQ (Interrupt ReQuest, onde o hardware solicita
a CPU que atenda uma chamada de hardware)
Ex: interrupção externa, transmissão/recepção serial, estouro de timers e contadores,
etc.

Interrupções de software:
Interrupções geradas mediante acontecimentos específicos no software. Presente em
sistemas que rodam um sistema operacional, onde o mesmo envia uma mensagem a
aplicação sobre algum evento específico.

e-stude.com
Interrupções – em resumo...

Curso normal do programa

Trata a interrupção
Uma interrupção ocorre! ocorrida

Retorno ao curso normal do programa

e-stude.com
Dica do Pedrão!
Como as interrupções podem ser geradas a
qualquer momento (e, posteriormente, o
software volta a fazer o que estava fazendo
antes de atender a interrupção), é essencial
que o tratamento da interrupção seja o mais
veloz e eficiente possivel para que o software
embarcado como um todo tenha boa
performance.

Ou seja, as rotinas de tratamento de


interrupção devem ser, obrigatoriamente, as
menores possíveis.

Caso contrário, a performance do software


embarcado será drasticamente reduzida (o
software ficará “encarroçado”).

e-stude.com
Interrupções: concorrência

Em softwares embarcados é muito comum utilizarmos duas ou mais interrupções. Ou


seja, pode-se receber pedidos de tratamento de diversas interrupções diferentes.

Portanto, há chances de interrupções concorrerem / acontecerem ao mesmo tempo.


Em softwares embarcados bem planejados isto é raro, mas há chance acontecer.

Para resolver este problema, os microcontroladores mais modernos possuem um


recurso chamado prioridade de interrupções.

As prioridades de interrupções são usadas como critério de desempate para o


microcontrolador saber qual interrupção deve tratar em caso de concorrência.

Infelizmente, se isto ocorrer, somente uma interrupção é tratada e as outras são


ignoradas.

e-stude.com
Interrupções externas
Das interrupções de hardware mais comuns em softwares embarcados, uma das
mais importantes e utilizadas é a interrupção externa.

Esta interrupção tem por função avisar a CPU que um determinado pino do
microcontrolador sofreu uma transição de sinal. Ou seja:

a) Quando foi de nível lógico alto (1) para baixo (0)


b) Quando foi de nível lógico baixo (0) para baixo (1)

É possível configurar em qual transição de nível lógico a interrupção ocorrerá. A esta


transição, dá-se normalmente o nome de EDGE (ou borda). Observe:

Rising Edge Falling Edge

Portanto, esta interrupção tem como função alertar a CPU do microcontrolador que
algo aconteceu em um dos pinos.
e-stude.com
Interrupções externas

Isto leva a uma série de vantagens em um software embarcado, tais como:

a) Não é preciso gastar tempo e processamento lendo o nível lógico de um


determinado pino do microcontrolador todo o tempo.

b) É possível se tomar uma ação diretamente da transição de nível lógico desejado


(1-> 0 ou 0-> 1, falling edge ou rising edge).

c) É um recurso extremamente útil na contabilização de frequência de um sinal


digital (ou contador digital)

IMPORTANTE:
Os microcontroladores normalmente possuem um número limitado de pinos capazes
de gerar interrupção externa. Portanto, antes de fazer um projeto que exija uso de um
certo número de interrupções externas, deve atentar para este fato ao escolher um
microcontrolador para o projeto.

e-stude.com
Dica do Pedrão!
Como as interrupções (seja interrupções
externas ou não) em seu tratamento manipulam
uma ou mais variáveis, é necessário que tais
variáveis sejam globais.

Como variáveis globais são “alocadas para


sempre em memória RAM” (ou seja, ocupam um
espaço reservado da memória RAM durante
todo ciclo de vida do programa executado), é
altamente recomendável que estas sejam as
menores possíveis. Em outras palavras, evitar
arrays, variáveis float e double.

Lembre-se: microcontroladores tem ordem de


grandeza de memória RAM de KiloBytes, logo
economizar nas variáveis globais é uma ótima
idéia!

e-stude.com
Interrupções externas - exemplo

e-stude.com
Interrupções externas - exemplo

Desenvolver um software embarcado para microcontrolador PIC 16F628A capaz de:

a) Contar pulsos de um sinal digital


b) Com base na contagem, tomar as seguintes ações:

b.1) Se forem contados até 100 pulsos (0 até 100), colocar em nível lógico 1 a saída
RB1 e em nível lógico 0 a saída RB2
b.2) Após esta contagem inicial (número de pulsos > 100), aguardar mais 100 pulsos
serem contados. Feito isso, colocar em nível lógico 0 a saida RB1 e em nível lógico 1
a saída RB2.
b.3) Refazer as ações “eternamente” (ou seja, voltar a condição do item b.1 e repetir
indefinidamente).

Deve ser utilizado o oscilador interno do PIC (4MHz) como clock geral.

e-stude.com
Interrupções externas - exemplo
Solução – 1/3: definições gerais e variáveis globais

#include <xc.h> //include obrigatório para compilação no XC8

// CONFIG
#pragma config FOSC = INTOSCCLK // Oscilador interno
#pragma config WDTE = OFF // Watchdog Timer Desabilitado
#pragma config PWRTE = OFF // Power-up Timer desabilitado
#pragma config MCLRE = OFF // Função MCLR desabilitada
#pragma config BOREN = OFF // Operando sem Brown-out detection
#pragma config LVP = OFF // Baixa tensão de programação desabilitada
#pragma config CPD = OFF // Sem proteção de código
#pragma config CP = OFF // Sem proteção de código

#define _XTAL_FREQ 4000000 //operando com clock geral de 4MHz (interno)

//variaveis globais:
Por ser usada em vários pontos do programa, esta variável é
char NumeroPulsos; global

e-stude.com
Interrupções externas - exemplo
Solução – 2/3: tratamento da interrupção externa
//Função: função de tratamento de interrupções do PIC
// (chamada automaticamente no acionamento de toda e qualquer interrupção
// do PIC, cabendo ao programador verificar dentro desta função qual interrupção
// que foi gerada)
// Para esta função ser chamada automaticamente na ocorrência de qualquer
// interrupção, basta a diretiva "interrupt" antes de seu nome.
//Parâmetros: nenhum
//Retorno: nenhum
void interrupt isr(void) Esta função será chamada sempre que ocorrer uma interrupção
{
//primeiro passo: verificar se a interrupção gerada foi mesmo uma interrupção externa
if (INTCONbits.INTF == 1)
{
//trata-se de uma interrupção externa. Faz o tratamento da mesma.
NumeroPulsos++; Como dito anteriormente, o tratamento da interrupção deve ser
} o mais rápido/breve possível

//Limpa flag de interrupção extrna (sinaliza que a interrupção já foi tratada)


INTCONbits.INTF = 0; Na grande maioria dos compiladores, é necessário informar que a
} interrupção já foi tratada

e-stude.com
Interrupções externas - exemplo
Solução – 3/3: Programa principal
void main(void)
{
//configura registrador de direção do PORTB
TRISB = 0x0b11111001; //configura RB1 e RB2 como saídas (0 para saída e 1 para entrada) Diz quais pinos (do PORTB) são
inputs e quais são output
//inicialização da variável global e do estado das saídas RB1 e RB2
NumeroPulsos = 0;
RB1 = 1; Garante que as saídas RB1 e RB2 iniciarão no estado desejado e inicializa número de
RB2 = 0; pulsos contados

//configuração da interrupção externa


INTCONbits.INTF = 0; //Limpa flag de interrupção externa Configs da
OPTION_REGbits.INTEDG = 1; //A interrupção ocorrerá na borda de subida (0->1) Interrupção
INTCONbits.INTE = 1; //Habilita a geração de interrupção externa Externa
INTCONbits.GIE = 1; //Liga as interrupções globais (necessário para ser gerada qualquer interrupção)
while(1)
{
//checa se o contador já chegou em dez
if (NumeroPulsos == 100)
{ Executa “eternamente” a lógica principal do programa, sendo esta
NumeroPulsos = 0; baseada em um contador gerado pela interrupção externa.
RB1 = ~RB1; Logo, o programa principal somente “analisa” a informação do contador
RB2 = ~RB2;
(gerada pelo tratamento da interrupção), tendo assim mais tempo e
}
} processamento livres para outras tarefas futuras
}

e-stude.com
Interrupções externas – simulação

e-stude.com
Timers

e-stude.com
Timers – o que são?
Os Timers são poderosos recursos dos microcontroladores. Eles são capazes de
permitir temporizações (curtas) sem comprometer o processamento do
microcontrolador (de forma simultânea ao processamento do programa
executado).

A temporização gerada é na ordem de microsegundos a milisegundos.

e-stude.com
Timers

e-stude.com
Timers – como são especificados?
Os Timers são, na verdade, contadores comuns. Porém, cada passo da
contagem ocorre em tempos fixos (os intervalos de contagem ocorrem em
tempos definidos)

Exemplo: Bit 3 Bit 2 Bit 1 Bit 0

0 0 0 0
ΔTempo
0 0 0 1
ΔTempo
0 0 1 0
Contagem

ΔTempo
0 0 1 1

ΔTempo
0 1 0 0

0 1 0 1
ΔTempo

0 1 1 1
ΔTempo

ΔTempo
...
e-stude.com
Timers – como são especificados?
Logo, se entre dois números em sequencia deste contador há um período de
tempo fixo, pode-se contabilizar tempo da forma:

cada passo = período de tempo fixo


Logo:
X passos = X * períodos de tempo

Isto é muito similar a um relógio de ponteiros comum: o ponteiro dos segundos


percorre 360º para contabilizar 60 segundos, logo cada segundo é equivalente a
6º percorridos (6º = período de tempo igual a um segundo).

Por esta razão, os timers são especificados em bits, da mesma forma que é
especificado um contador. E a especificação em bits nada mais é que a
informação do valor máximo que o contador pode assumir.

Por exemplo:
- Um timer de 16 bits pode contar até 65536 (2^16) intervalos de tempo.
- Um timer de 8 bits pode contar até 256 (2^8) intervalos de tempo.
e-stude.com
Timers – observação

Conforme foi visto, um Timer nada mais é que um


contador.

Quando o Timer atinge seu valor de contagem de


tempo máximo, é ocorrido o que é chamado de
estouro de timer.

Nessa hora é gerada uma interrupção (comummente


chamada de interrupção de estouro de timer).

e-stude.com
Timers – como se apresentam no microcontrolador?

Os Timers são unidades “isoladas” em um microcontrolador.


Ou seja, são blocos dentro de um microcontolador dedicados à temporização
(“blocos de hardware” mesmo).

Por este fato, os Timers são limitados em número (o número varia de acordo
com o modelo de microcontrolador). Logo, devem ser sempre sabiamente
utilizados.

Além disso, para permitirem uma gama maior de temporizações possíveis, é


comum encontrar Timers de diferentes números de bits em um mesmo
microcontrolador, sendo mais comuns os Timers de 8 bits e de 16 bits.

e-stude.com
Timers – observação

Dependendo do modelo do microcontrolador, um ou


mais Timers podem ser de uso compartilhado.

Isso significa que um Timer pode tanto ser de uso


geral quanto pode ser usado em algum recurso
específico do microcontolador (como Watchdog, por
exemplo).

Portanto, é de suma importância que o projetista


verifique se o Timer que deseja usar estará
disponível para uso (se não está sendo utilizado
em outro recurso).
Não observar isto pode fazer um software
embarcado apresentar um comportamento
totalmente inaceitável / errado e de difícil depuração.

e-stude.com
Timers – como transformam contador em tempo?

Frequência
Pre-scaler
Timer
Valor inicial de
contagem

e-stude.com
Timers – como transformam contador em tempo?
1) Frequência de entrada do timer: frequência que será o clock-base para o contador
(de tempo) realizar a contagem. Os valores de frequência aceitáveis (e as formas de se
inserir essa frequência no microcontrolador) variam de modelo para modelo de
microcontrolador.

Por exemplo, em boa parte dos microcontroladores PIC 8-bits, a frequência que vai para
os Timers (e que é usada no softwre embarcado todo) é ¼ da frequência de clock.

2) Pre-scaler / divisor de frequência: valor pelo qual a frequência de entrada é dividida,


para assim permitir temporizações mais lentas.

Observação: o pre-scaler normalmente é um valor pré-definido (ou seja, não é qualquer


valor que o projetista desejar), sendo que os valores mais comuns são: 1,4,16, 32, 128 e
256.

3) Valor inicial do contador: valor que o contador vai iniciar a contagem. Quanto maior
este valor inicial, menor será a temporização. Em outras palavras, menor será o tempo para
atingir o valor máximo do contador (estouro de Timer)

Este serve para melhor ajustar a temporização (isso ficará mais claro no exemplo).

e-stude.com
Timers – como transformam um contador em tempo?
Passo-a-passo do cálculo de tempo de estouro Timer0 do PIC16F628A. O clock considerado
no exemplo é 4MHz:

a) o Timer0 tem 8 bits, logo o valor de seu "contador interno" (o registrador TMR0) vai de 00h
até FFh.
b) Neste caso, usaremos Pre-scaler igual a 1:32 (a frequência usada pelo Timer é 1/32 da
frequência útil). Sendo assim, o valor preScaler usado nos cálculos a seguir é preScaler = 32
c) Segundo a documentação, neste PIC uma instrução é executada somente após 4
oscilações do clock. Logo, é correto dizer que a frequência útil do PIC (que vai pro Timer0) é
1/4 da frequência de entrada. Portanto:
TempoCicloMaquina = 4*CicloOsc = 4*(1/Fosc) = 4 / Fosc = 4/4MHz = 0,000001
d) O tempo de estouro (para o registrador TMR0 chegar até seu valor FFh) é calculado pela
seguinte fórmula:

Testouro = (256 – ValorInicialTMR0)* TempoCicloMaquina * preScaler

onde: 256 = FFh, valor de TMR0 para dar tempo máximo de estouro

O tempo de estouro máximo é dado quando o valor inicial do timer é 0. Portanto, temos :
Testouromaximo = (256 - 0)* 0,000001 * 32 = 8,192ms

e-stude.com
Timers – dicas gerais:
• Sempre que possível, evite ficar reconfigurando um Timer durante a execução do
programa. Isso aumenta o risco de serem gerados bugs de temporização de
difícil depuração.

• Sempre utilize o recurso de interrupção de estouro de Timer (ou seja, nunca


fique verificando o valor do registrador de timer “por fora”, gastando tempo de
processamento a toa). Assim, garante-se a máxima performance possível.
Portanto, sempre dimensione/configure os Timers para a temporização desejada.

• Dica precisosa: conforme visto, Timers tem temporização na ordem de


milissegundos ou até mesmo microsegundos.
Logo, para temporizar tempos maiores (ordem de segundos ou mais), utilize uma
variável global que contabiliza quantos estouros ocorreram, assim permitindo
contabilizar temporizações maiores.

Exemplo: No exemplo anterior de configuração de timer, vimos que era possível


temporizar, no máximo, 8,192ms.
Se quisessemos temporizar, por exemplo, 8,192s, deveriamos contabilizar 1.000
estouros de Timer (valor este contabilizado por uma variável global).
e-stude.com
Dica do Pedrão!
A temporização feita pelos Timers, conforme visto, é
diretamente dependente do clock do microcontrolador.

Portanto, quanto “pior” (mais impreciso) for o clock,


pior será a temporização.

Sendo assim, se em um projeto for exigida uma


temporização com alto grau de precisão, deve-se
utilizar um oscilador a cristal (ou seja, deve-se evitar
nestes casos usar oscilador interno do
microcontrolador).

As consequências de se usar este tipo de oscilador


são:

- Aumento do preço final do hardware do projeto


- Aumento do consumo energético do microcontrolador
(quanto maior a frequência, maior o consumo)
- Maiores preocupações com a mecânica do projeto
(pois cristais são muito sensiveis a impacto e variação
de temperatura).

e-stude.com
Timers – como trabalhar com eles?

O conceito de interrupção é o conceito-chave quando se trabalha com Timers.


Quando um Timer atinge seu máximo valor (ou seja, ocorrer estouro de timer), é
possível gerar uma interrupção específica (interrupção de estouro de timer).

Como é conhecido pelo projetista o tempo total para o Timer estourar e se sabe
exatamente o tempo decorrido desde a inicilização/reinício do timer até o
momento da interrupção, logo é possível desenvolver um software embarcado
confiável quanto à temporização (sem perda de processamento).

Este tipo de técnica de programação (orientar eventos e ações mediante


interrupções de timer) é o segredo do funcionamento dos sistemas
operacionais de tempo real (RTOS).

Utilizar este recurso é fundamental para uma boa performance de um software


embarcado, no qual as ações são dependentes de tempo.

e-stude.com
Timers – exemplo

e-stude.com
Timers – exemplo

Desenvolver um software embarcado para rodar no PIC 16F628A.


O software deve ser capaz de piscar um LED controlado pela saída RB5. O LED
deve piscar a uma frequência de 0,5Hz (1 segundo de LED aceso e 1 segundo
de LED apagado, ou seja, 1 piscada a cada dois segundos).

Observação: o LED deve ser ligado juntamente com um resistor (limitador de


corrente elétrica para o LED).

IMPORTANTE: Para a temporização, deve ser usado, obrigatoriamente, um dos


timers disponíveis no microcontrolador.

e-stude.com
Timers – exemplo
Solução – 1/4: definições gerais e variáveis globais
#include <xc.h>

#pragma config FOSC = XT


#pragma config WDTE = OFF // Watchdog Timer Desabilitado
#pragma config PWRTE = OFF // Power-up Timer desabilitado
#pragma config MCLRE = OFF // Função MCLR desabilitada
#pragma config BOREN = OFF // Operando sem Brown-out detection
#pragma config LVP = OFF // Baixa tensão de programação desabilitada
#pragma config CPD = OFF // Sem proteção de código
#pragma config CP = OFF // Sem proteção de código

#define _XTAL_FREQ 4000000 //define para utilizar funções de tempo


#define CICLO_MAQUINA (4/_XTAL_FREQ) //nos PICs, uma insctrução é executada a cada 4 oscilações do
clock (ou, em outras palavras, a cada 4 ciclos de máquina)
#define SIM 1
#define NAO 0

//variáveis globais
charContaEstourosTimer0; //contabiliza quantas vezes o Timer0 estourou
char FlagGerouInterrupcaoTimer0; //sinaliza se foi gerada interrupção de TImer0

//prototypes das funções


void ConfiguraTimer0(void);

e-stude.com
Timers – exemplo
Solução – 2/4: inicialização do Timer e tratamento da interrupção de Timer
//Função: configura todos os registradores necessários para colocar o Timer0 operante (em modo temporizador)
//Parâmetros: nenhum
//Retorno: nenhum
void ConfiguraTimer0(void)
{
//Para o cálculo do Timer0, considerar as seguintes fórmulas e observações:
//- o Timer0 tem 8 bits, logo o valor de seu "contador interno" (o registrador TMR0) vai de 00h até FFh no máximo
//- Neste caso, usaremos Pre-scaler igual a 1:32. Logo, o valor preScaler usado nos calculos a seguir é preScaler = 32
//- Nos PICs 8bits, 1 instrução é executada somente após 4 oscilações do clock. Logo, é correto dizer que a frequência útil do PIC é 1/4 da
frequência de entrada. Portanto:
// TempoCicloMaquina = 4*CicloOsc) = 4*(1/Fosc) = 4 / Fosc
//- O tempo de estouro (para o registrador TMR0 chegar até seu valor FFh) é calculado pela seguinte fórmula:
// Testouro = (256-ValorInicialTImer0) * TempoCicloMaquina * preScaler (eq. 1)
// (256 = FFh, valor de TMR0 para dar tempo máximo de estouro)
// Neste caso, temos: Testouromaximo = (256 – 0) * 0,000001 * 32 = 8,192ms
//
// Para atingir 1 seg. precisamos de 122,07 estouros. Para atingir 1s precisamos de um valor inicialdo registro TMR0 de form a que a
quantidade de estouros seja um número inteiro. Logo, vamos mudar o
// tempo de estouro para 8ms, assim precisaremos de 125 estouros para completar 1s temporizado. Assim, utilizando a equação (1):
// 0,008 = (256-TMR0) * 0,000001 * 32 -> TMR0 = 6

OPTION_REGbits.PS = 0b100; //configuração do pre-scaler em 1:32


OPTION_REGbits.PSA = 0; //O pre-scaler setado será usado para o timer0 (necessário definir isso pois, neste PIC, o Timer0 pode ser usado
ou para Timer de propósito geral ou para o Watchdog)
OPTION_REGbits.T0CS=0; //O timer0 considera como clock a frequência util do microcontrolador
INTCONbits.TMR0IE =1; //Habilita interrupção de estouro do Timer0
INTCONbits.GIE=1; //Habilita TODAS as interrupções (exigÊncia do compilador XC8 para habilitar toda e qualquer interrupção)
TMR0=6; //Inicialização do registrador TMR0
}

e-stude.com
Timers – exemplo
Solução – 3/4: tratamento da interrupção de Timer
//Função: função de tratamento de interrupções do PIC (chamda automaticamente no acionamento de toda e qualquer interrupção
do PIC, cabendo ao programador verificar dentro desta função qual interrupção que foi gerada)
//Parâmetros: nenhum
//Retorno: nenhum
void interrupt isr(void)
{
//se o TMR0 foi a FFh (indicado pelo sinalizador TMR0IF) e o sinalizador de interrupção de estouro de timer0 (T0IF) indicou estouro
de Timer0, logo houve estouro de timer.
if (TMR0IF && T0IF)
{
ContaEstourosTimer0++;

if (ContaEstourosTimer0 == 125)
{
FlagGerouInterrupcaoTimer0 = SIM; //sinaliza, pelo flag, que as operações vinculadas ao Timer0 devem ser realizadas no
loop principal
ContaEstourosTimer0 = 0; //reinicia contador de estouros
}

TMR0=6; //Inicialização do registrador TMR0


T0IF = 0; //indica que o timer0 deve ser reiniciado para uma futura interrupção (se isto não for feito, nenhuma outra
interrupção de Timer0 será gerada)
INTCONbits.TMR0IF = 0; // reabilita interrup. TMR0
}

} Recarga (reload) do Timer0

e-stude.com
Timers – exemplo
Solução – 4/4: inicializações gerais e programa principal

void main(void) {
TRISB = 0x0b11011111; //configura RB5 como saída (0 para saída e 1 para entrada)
PORTB = 0; //força todas as saídas do PORTB para 0
FlagGerouInterrupcaoTimer0 = NAO; //inicia flag de tratamento de ações vinculadas a interrupção de timer0
ContaEstourosTimer0 = 0; //inicializa contador de estouros do Timer0
ConfiguraTimer0(); //configura Timer0 para ser acionado conforme desejamos neste programa

while(1) //loop principal


{
//verifica continuamente se deve realizar a operação vinculada ao timer0
if (FlagGerouInterrupcaoTimer0 == SIM) Ponto alto do software:
{ a lógica principal roda em
FlagGerouInterrupcaoTimer0 = NAO; cima de variáveis
RB5 = ~RB5; //inverte estado lógico do pino do LED manipuladas na
} interrupção.
Toda a temporização é
} feita por interrupção,
} poupando assim
processamento.

e-stude.com
Timers – simulação

e-stude.com
Exercícios propostos – interrupção externa
1) Desenvolver um software embarcado para o PIC 16F628A capaz de:
a) Contabilizar pulsos de um sinal digital
b) A cada 15 pulsos contabilizados, o estado da saída RB5 é invertido.
c) Após 10 inversões, RB5 e RB6 ficam permanentemente em nível alto.

Observações:
- Utilizar interrupção externa
- Inicialmente, as saídas RB5 e RB6 devem estar em nível baixo
- Utilizar o oscilador interno do microcontrolador (configurado em 4MHz).

2) Desenvolver um software embarcado para o PIC 16F628A capaz de ler o estado de um


botão. Enquanto o botão não estiver pressionado, a saída RB5 deve alternar seu estado lógico
da seguinte forma: 1 segundo em nível lógico alto e 1 segundo em nível lógico baixo.
Uma vez pressionado o botão, a saída não deve mais alternar o estado lógico.

Observações:
- Utilizar interrupção externa para ler o botão (utilizar borda de subida)
- Inicialmente, a saída RB5 está em nível baixo
- Neste exercício, pode-se tanto usar a função delay (do compilador XC8) para temporização
quanto interrupção de Timer.

e-stude.com
Exercícios propostos – timers
1) Desenvolver um software embarcado para o PIC 16F628A capaz de piscar um LED (ligado na saída RB5)
somente se a entrada RB4 estiver em nível alto.
O LED deve piscar a uma frequência de 1Hz (0,5s aceso, 0,5s apagado).

Observações:
- Na temporização,utilizar um dos timers do microcontrolador
- Inicialmente, a saída RB5 deve estar em nível baixo
- Utilizar o oscilador externo à cristal (configurado em 10MHz).
- IMPORTANTE: se o valor de cristal exigido não permitir temporização exata de 0,5s (2Hz), é admitido um
erro de até 10%.

2) Desenvolver um software embarcado para o PIC 16F628A capaz de esperar por 10 segundos até que a
entrada RB4 entre em nível lógico alto.
Se a entrada RB4 ficar em nível alto dentro deste tempo, colocar RB3 em nível alto indefinidamente (e RB5
em nível baixo). Caso contrário (demorar mais que 10 segundos para a entrada RB4 ir a nível alto), deve-se
colocar em nível alto a saída RB5 indefinidamente (e RB3 em nível baixo).

Observações:
- Na temporização,utilizar um dos timers do microcontrolador
- Inicialmente, as saídas RB5 e RB3 devem estar em nível baixo
- A leitura da entrada RB4 pode ser tanto em pooling quanto por interrupção externa. Não é preciso considerar
trepidação / bouncing na leitura da entrada.
- Utilizar o oscilador externo (configurado em 20MHz).

e-stude.com
Exercício desafio

e-stude.com
Exercício desafio – parte prática
Imagine que você é um projetista e deve desenvolver um sistema embarcado automotivo com foco em segurança. Este sistema
é responsável por sinalizar (através de um LED) para o motorista quando a velocidade de um determinado modelo de carro for
superior a 120km/h.

Neste modelo de carro, sabe-se que é disponível ao seu sistema um sinal elétrico pulsante diretamente proporcional à
velocidade do veículo. Sabe-se que quatro pulsos lidos equivalem a uma volta completa da roda. Além disso, sabe -se também
que o diâmetro da roda do veículo (desconsiderando o desgaste por rodagem) é de 59cm.

Com isso, pede-se:

a) A expressão matemática mais otimizada possível para cálculo da velocidade (em m/s) em função do número de pulsos
lidos (em um segundo de leitura).
Lembrete: mais otimizada possível = contém o menor número de multiplicações e divisões possíveis.
b) Com base na expressão obtida no item anterior, determinar quantos pulsos por segundo devem ser lidos para ser
contabilizada velocidade de 120km/h.
c) Desenvolver o software embarcado (no PIC16F628A) para realizar a tarefa descrita (utilizandoa fórmula obtida no item a e
o resultado do item b), assumindo que o LED está na saída RB5 do microcontrolador.

Observações:
- Assumir que os pulsos já possuem tensão elétrica máxima igual a de entrada (5V, no caso) e que já são perfeitamente
quadrados. Ou seja, os pulsos estão em condições ideais de leitura.
- Ter muita atenção com os tipos das variáveis!!!
- Tudo que envolver temporização deve, obrigatoriamente, utilizar Timer (operando por interrupção)
- A leitura dos pulsos deve ser feita, obrigatoriamente, por interrupção externa.
- Considere que a velocidade deve ser calculada e também seu valor analisado a cada segundo.
- A escolha do tipo de oscilador e frequência do mesmo é livre.
- Assumir que o erro máximo permitido é de 2km/h
- Assuma a velocidade máxima do veículo igual a 200km/h
- Lembre-se: 1m/s = 3,6km/h

e-stude.com
Exercício desafio – parte teórica

Há um grande risco neste microcontrolador quando se trata de utilizar dois tipos de


interrupções ao mesm o tempo.

Qual é este risco?

Dica: verificar se este microcontrolador possui prioridade de interrupção.

e-stude.com
Fim da segunda aula!

e-stude.com

Você também pode gostar