Você está na página 1de 34

Microcontroladores PIC18

com Linguagem C
Uma Abordagem Prática e Objetiva
com Base no PIC18F4520

Wagner da Silva Zanco

Respostas dos Exercícios

Editora Érica Ltda.

Respostas dos Exercícios \1\


Capítulo 1

1. 40MHz com o PLL ativo.


2. 36 pinos, divididos em cinco grupos denominados Ports. São eles: Port A, Port B, Port C, Port D e
Port E.
3. Dez configurações diferentes. São elas:
LP: cristal de baixa potência (até 200KHz).
XT: cristal/ressonador (até 4MHz).
HS: cristal/ressonador de alta frequência (acima de 4MHz).
HSPLL: cristal/ressonador de alta frequência com o PLL habilitado.
RC: RC externo com saída de clock. Essa opção fornece ao pino OSC2CLKO/RA6 um sinal
digital com frequência quatro vezes menor que a do oscilador principal (Fosc/4).
RCIO: RC externo. Nessa opção o RA6 funciona como pino digital.
INTIO1: oscilador interno com Fosc/4 no pino RA6 e pino RA7 configurado como digital.
INTIO2: oscilador interno com RA6 e RA7 configurados como pinos digitais.
EC: oscilador externo com saída de clock. Essa opção fornece no pino OSC2CLKO/RA6 um
sinal digital com frequência quatro vezes menor que a do oscilador principal.
ECIO: oscilador externo. Nessa opção o pino RA6 funciona como digital.
4. Quando a aplicação exige um bom nível de precisão para o oscilador, como no caso de
aplicações que envolvem comunicação de dados ou temporizadores.
5. O PIC18F4520 possui dois osciladores internos que, se ativados, dispensam a utilização de
componentes externos. São eles o INTOSC e o INTRC. O oscilador principal, o INTOSC, possui
uma frequência de 8MHz e pode ser utilizado como oscilador de clock. Esse oscilador tem
associado o recurso postscaler que permite prover frequências na faixa de 31kHz-4MHz.
O oscilador principal INTOSC é habilitado quando é selecionada uma frequência de clock dentro
da faixa de 125kHz a 8MHz. O outro oscilador interno, o INTRC, provê uma frequência de 31kHz.
O oscilador INTRC é habilitado se ele for selecionado como origem do sinal de clock.
6. O PIC18F4520 possui três fontes diferentes que podem gerar o sinal de clock. O sinal de clock
pode vir do oscilador primário, do oscilador secundário ou de um dos osciladores internos.
O oscilador primário inclui as opções cristal/ressonador externo, RC externo, oscilador externo e
os osciladores internos. O oscilador secundário é associado ao módulo Timer1 e inclui a conexão
de um cristal de baixa frequência entre os pinos T1OSO e T1OS1. Para que o oscilador
secundário possa ser utilizado, é necessário que o módulo Timer1 esteja habilitado. O cristal de
baixa frequência conectado entre os pinos T1OSO e T1OS1 normalmente é de 32,768kHz e pode
ser utilizado como base de tempo para um RTC (Real Time Clock).
Os osciladores internos, além de fazerem parte do set de opções do oscilador primário, estão
disponíveis como fontes de clock para o modo de energia gerenciado (power-managed).

\ 2 \ Microcontroladores PIC18 com Linguagem C


7.
OSCCON<7,1:0> Sinal de clock Disponibilidade do clock
Modo
IDLEN SCS1:SCS0 CPU Periféricos e origem do oscilador
Sleep 0 N/A Off Off Nenhum - todos os clocks estão desligados
Primário - LP, XT, HS, HSPLL, RC, EC e
PRI_RUN N/A 00 Recebe Recebe oscilador interno
Este é o modo de execução normal
SEC_RUN N/A 01 Recebe Recebe Secundário - oscilador do TIMER 1
RC_RUN N/A 1x Recebe Recebe Osciladores internos
PRI_IDLE 1 00 Off Recebe Primário - LP, XT, HS, HSPLL, RC, EC
SEC_IDLE 1 01 Off Recebe Secundário - oscilador do TIMER 1
RC_IDLE 1 1x Off Recebe Osciladores internos

Capítulo 2

1. O PIC18F4520 possui três tipos de memória integrados. São elas: memória de programa
Flash-ROM, memória de dados RAM e memória não volátil EEPROM. A memória nesse
microcontrolador está dividida da seguinte forma:
Memória de programa (Flash-ROM): 32kx16
Memória RAM (de dados): 1536x8
Memória EEPROM: 256x8
2. Na localidade 0000h da memória de programa.
3. Até 31 chamadas.
4. A memória de dados do PIC18F4520 é implementada em memória SRAM e está dividida em 16
bancos de 256 localidades cada, com capacidade de armazenamento de 8 bits em cada
localidade.
5. É um tipo de acesso à memória em que não é necessário o chaveamento entre bancos para acessar
uma localidade de memória. O Access Bank, como é chamado, utiliza um segmento do banco 0 e um
segmento do banco 15 para formar um único banco de memória no qual podemos acessar tanto os
SFRs quanto os GPRs. O acesso à memória de dados via Access Bank não leva em consideração o
valor armazenado no registrador BSR.
6. Registrador BSR.
7. A memória EEPROM interna é classificada na arquitetura do PIC18F4520 como um periférico e
ocupa a faixa de endereços 00h - FFh.

Respostas dos Exercícios \3\


Capítulo 3

1. Power-on Reset (POR).


2.
Contador de Registrador RCON Registrador STKPTR
Condição
Programa RI TO PD POR BOR STKFUL STKUNF
Power-on Reset 0000h 1 1 1 0 0 0 0
Instrução RESET 0000h 0 u u u u u u
Brown-out Reset 0000h 1 1 1 u 0 u u
MCLR Reset durante a execução dos 0000h u 1 u u u u u
power-managed modes
MCLR Reset durante os power-managed idle 0000h u 1 0 u u u u
modes and sleep mode
WDT time-out durante a execução do full power
0000h u 0 u u u u u
or power-managed mode
MCLR Reset durante a execução em full power 0000h u u u u u u u
Stack full Reset (STVREN = 1) 0000h u u u u u 1 u
Stack underflow Reset (STVREN = 1) 0000h u u u u u u 1
Stack underflow error (não um Reset atual,
0000h u u u u u u 1
STVREN = 0)
WDT time-out durante os power-managed idle
PC + 2 u 0 0 u u u u
or sleep modes
Saída da interrupção dos power-managed
PC + 2(1) u u 0 u u u u
modes
Legenda: u - não é alterado.
Nota 1: Quando um wake-up ocorre devido a uma interrupção e os bits GIEH e GIEL estão setados, o PC é carregado com vetor de interrupção
(008h ou 0018h).

3. O Power-up Timer (PWRT) provê um time-out típico de 72ms após o POR. Um circuito RC
interno é o responsável pela temporização. O PWRT é um recurso que precisa ser ativado e o
seu objetivo é manter o microcontrolador em Reset até que a tensão de alimentação esteja
estabilizada.
4. O Oscillator Start-up Timer é um circuito que provê um delay de 1024 ciclos de clock do oscilador
principal, após o Power-up Timer, antes de colocar o circuito oscilador em funcionamento. Isso
garante que o oscilador esteja estabilizado na sua partida, evitando travamento.
O Oscillator Start-up Timer só é invocado para os modos de funcionamento do oscilador XT, LP e
HS no POR ou quando o microcontrolador acorda após ter entrado no modo Sleep.
5. Quando o PLL está habilitado, a sequência time-out (temporização) que segue o POR é diferente
dos outros modos de funcionamento do oscilador. Uma parte do Power-up Timer é utilizada para
prover um time-out suficiente para o PLL estabilizar a frequência do oscilador principal. O delay
gerado para o PLL é de 2ms e ocorre após o Start-up Timer-out (OST).

\ 4 \ Microcontroladores PIC18 com Linguagem C


6. Em funcionamento normal, o pino /MCLR (Master Clear) precisa estar recebendo nível '1'.
Quando o nível lógico nele é forçado a '0', o microcontrolador é resetado e só sai do Reset
quando o nível lógico retornar a '1'.
7. O Brown-out Reset é um recurso que, quando está ativado, faz o microcontrolador resetar caso a
tensão de alimentação caia abaixo de um determinado valor, que pode ser configurado por
software. Uma vez que o microcontrolador entrou em Reset devido ao Brown-out Reset, ele só
volta ao seu funcionamento normal, ou seja, a executar o programa, quando a tensão de
alimentação voltar ao nível especificado pelo fabricante para correto funcionamento do
microcontrolador.
8. Este é um recurso muito poderoso utilizado para evitar a paralisação do sistema em caso de
travamento do oscilador devido a uma interferência eletromagnética, ou qualquer outro tipo de
ruído que o faça parar de oscilar, exceto em caso de defeito no circuito oscilador. O WDT é um
temporizador que provoca um Reset no programa sempre que ele produzir um time-out, ou seja,
quando o tempo programado para o time-out terminar sem que seja executada a instrução
CLRWDT.
9. A instrução RESET pertence ao set de instruções dos microcontroladores da série PIC18. Essa
instrução, quando executada, provoca um /MCLR Reset por software. O bit RCON</RI>=0
sinaliza que o último Reset foi provocado pela instrução RESET.
10. O Reset ligado aos eventos Stack Full RESET e Stack Underflow RESET está associado ao recurso
Return Adress Stack, o qual permite ao programa efetuar até 31 chamadas à sub-rotina ou a
funções associadas à ocorrência de uma interrupção. Quando é executada a instrução CALL, a
instrução RECALL ou quando ocorre uma interrupção, o programa sai da sequência normal de
execução e é desviado para outro ponto. Antes de ocorrer o desvio, no entanto, o endereço de
retorno é armazenado em uma pilha, chamada Return Adress Stack, para que o programa possa
voltar ao ponto de onde ocorreu o desvio.
O registrador STKPTR<4:0> é um ponteiro para a posição da pilha onde está armazenado o próximo
endereço de retorno. Quando ocorre um desvio com retorno, o endereço de retorno é armazenado
na pilha e o registrador STKPTR<4:0> é incrementado. Da mesma forma, quando ocorre um retorno
de uma sub-rotina, o endereço de retorno é retirado da pilha e o registrador STKPTR<4:0> é
decrementado. Se no registrador STKPTR<4:0> for armazenado o valor 31 quando for executado
um desvio com retorno, ocorre um overflow no Return Adress Stack. Na sequência, o bit STKFUL
(STKPTR<7>) será setado e ocorrerá um Reset se o bit de configuração Stack Overflow Reset
estiver ativado.
Da mesma forma, se no registrador STKPTR<4:0> for armazenado o valor 0 quando for
executado um retorno, ocorre um underflow no Return Adress Stack. Na sequência, o bit
STKUNF (STKPTR<6>) será setado e ocorrerá um Reset se o bit de configuração Stack Overflow
Reset estiver ativado.
Os bits STKFUL e STKUNF podem ser testados após a ocorrência de um Reset para o programa
detectar se o Reset foi provocado por um overflow ou por um underflow no Return Adress Stack e
tomar as devidas providências.

Respostas dos Exercícios \5\


Capítulo 4

1. Quando configurados como digitais, os pinos do PIC18F4520 são divididos em cinco grupos
chamados Ports de I/O, identificados como Port A, Port B, Port C, Port D e Port E. O Port A é
composto pelos pinos RA7:RA0. O Port B pelos pinos RB7:RB0. O Port C pelos pinos RC7:RC0.
O Port D pelos pinos RD7:RD0. O Port E pelos pinos RE3:RE0.
2. O registrador TRISx. O TRISA configura os pinos do Port A, o TRISB os pinos do Port B e assim
sucessivamente.
3. Eles são o elo entre o software e o hardware, ou seja, entre o programa e os pinos do
microcontrolador.
4. Significa que é preciso conectar uma fonte de alimentação externa no pino.
5. Porque os resistores de pull-up são implementados na pastilha de silício e por isso possuem uma
potência muito pequena. Qualquer sobrecarga de corrente pode queimá-los.
6. Pino RE3. Para ativar a função digital desse pino, é preciso desabilitar a função /MCLR.
7. Um Schmitt Trigger é um circuito comparador incorporado de realimentação positiva. Quando o
nível de tensão de entrada é maior que um limiar escolhido, a saída está em nível alto; quando a
entrada está abaixo de outro limiar, a saída está em nível baixo; quando a entrada se encontra
entre os dois limiares, a saída retém o valor anterior até a entrada se alterar suficientemente para
mudar o estado do Trigger.
8. Parallel Slave Port.

Capítulo 5

1. Um compilador executado em um computador que pode gerar códigos que são executados em
um diferente tipo de computador.
2. Um bloco de código escrito em linguagem Assembly contém um menor número de instruções,
sendo, consequentemente, executado mais rapidamente do que um bloco de códigos escrito em
linguagem C que executa a mesma tarefa.
3. Suporte para microcontroladores de 8 bits, MPLAB IDE, MPLAB SIM, MPASM, MPLAB ICD 2
(opcional se for utilizar um gravador/debugger compatível com o ICD 2).
4. Project Wizard. Clicar no menu Project/Project Wizard.

\ 6 \ Microcontroladores PIC18 com Linguagem C


5.
Arquivo Caminho
MPASMWIN.exe C:\MCC18\mpasm\MPASMWIN.exe
mplink.exe C:\MCC18\bin\mplink.exe
mcc18.exe C:\MCC18\bin\mcc18.exe
mplib.exe C:\MCC18\bin\mplib.exe

6. Criar o programa-fonte, criar o projeto e configurar o MPLAB IDE, associar o programa-fonte ao


projeto, compilar o projeto, debugar o projeto e, finalmente, gravar o programa no microcon-
trolador.
7. Neles o MPLAB irá procurar os arquivos cabeçalho e os arquivos biblioteca incluídos na
aplicação.
8. MPLAB SIM.

Capítulo 6

1. enum, const, signed, void e volatile.


2. Função main().
3. São informações que a função pode receber quando for chamada para que ela seja executada
corretamente. As informações recebidas podem ser qualquer tipo de dado válido em C. Para não
receber nenhum valor, lista_de_parametros deve ser declarada como void.
4. Um bloco de código é uma sequência de comandos compreendidos entre chaves, o qual é visto
como uma unidade única.
5. A linguagem C possui cinco tipos básicos de dados: caractere, inteiro, ponto flutuante, ponto
flutuante de precisão dupla e sem valor. São eles, respectivamente, char (8 bits), int (16 bits),
float (32 bits), double (32 bits) e void (sem valor).
6. Chamamos de identificador o nome atribuído a uma variável, constante, função, label e a outros
elementos do sistema. Um identificador pode conter letras, números e o caractere alfanumérico
underline _. Ele deve começar com uma letra ou com o caractere underline. É proibido na
linguagem C um identificador iniciar com um valor numérico.
7. Uma variável global é aquela que foi declarada fora de qualquer função, inclusive da função
main(). A variável global se mantém ativa durante toda a execução do programa. Uma variável é
local quando ela é declarada dentro de uma função. A variável local é destruída na saída da
função. Além disso, uma variável local só é reconhecida dentro da função na qual ela foi criada.
8. A principal componente da linguagem C é a função. Uma função é formada por um conjunto de
comandos que são agrupados em um ou mais blocos de código. A função executa uma tarefa
bem definida dentro do programa.

Respostas dos Exercícios \7\


9. Do ponto de vista lógico uma função é um bloco de comandos que executa uma tarefa bem definida.
10. Comentário de linha única. Começa com dois caracteres barra // e identifica como comentário
tudo que vier após as duas barras até o final da linha.
Comentário de linha múltipla. Deve sempre começar com os caracteres /* e terminar com os
caracteres */. Além disso, ele pode conter várias linhas.
/*Comentário...
Comentário...
Comentário...*/

11. O arquivo cabeçalho disponibiliza ao projeto uma biblioteca de funções que podem ser utilizadas
quando solicitadas. Para incluir um arquivo cabeçalho no projeto deve-se utilizar a diretiva
#include.
#include <stdio.h>

A linha anterior inclui no projeto as funções prototipadas no arquivo cabeçalho stdio.h, dentre as
quais podemos citar a função printf().
12. tipo nome_da_função (lista_de_parâmetros)
{
//sequência de comandos
}

13. São eles os signed, unsigned, long e short.


14. Variáveis são localidades de memória reservadas para armazenamento de dados que serão
manipulados durante a execução do programa, o que chamamos de tempo de execução. Quando
uma variável é declarada, é necessário informar o tipo de dado que ela irá receber, ou seja,
definir o tipo da variável. Além disso, uma variável pode ter escopo global ou local. A variável
global é reconhecidada por todo o programa. A variável local só é reconhecida dentro da função
na qual ela foi criada.
15. tipo lista_de_ variáveis;
tipo: é um tipo de dado válido em C, com exceção do tipo void.
lista_de_variáveis: o nome das variáveis que serão declaradas. Se mais de uma variável
for declarada, elas devem estar separadas por vírgula.
16. O modificador de tipo de acesso const é utilizado quando desejamos criar uma variável e não
permitir que o seu conteúdo seja alterado por algum elemento do sistema durante o tempo de
execução. Quando uma variável é declarada com o modificador const, após a inicialização,
ninguém pode alterar o seu conteúdo.
O modificador de tipo de acesso volatile é utilizado quando uma determinada variável pode ser
alterada por algum elemento externo ao programa, sem que seja utilizado um comando de
atribuição. O comando de atribuição é utilizado no programa para armazenar, por meio de uma
instrução de programa, uma informação na variável. Uma variável que é atualizada automa-
ticamente por um relógio/calendário é um exemplo de uma variável que deveria ser declarada
com o modificador volatile.

\ 8 \ Microcontroladores PIC18 com Linguagem C


17. extern, static, register, auto
18. O especificador extern é utilizado na declaração da variável quando ela for criada em um
determinado arquivo e precisar ser acessada de outro arquivo. O procedimento correto nesse
caso é declarar a variável em um arquivo e declará-la com o especificador extern no outro
arquivo em que ela será acessada. O compilador saberá que a variável foi declarada em outro
arquivo por causa do especificador extern. O especificador extern só funciona quando a variável
é declarada como global no arquivo de origem.
19. Quando uma variável local é declarada como static, o compilador aloca memória como se ela
fosse uma variável global. Em outras palavras, ela se manterá ativa durante todo o tempo de
execução. Mas, pelo fato de a variável ser do tipo local, ela só será reconhecida dentro do bloco
de código no qual ela foi criada.
20. Sim. Uma variável global static só é reconhecida dentro do arquivo no qual ela foi criada. A
variável local static só é reconhecida dentro da função na qual ela foi criada. No entanto, ambas
se mantêm ativas durante todo o tempo de execução.
21. Uma variável register é armazenada dentro da CPU. O objetivo é aumentar a velocidade no
processamento da informação armazenada na variável. Esse especificador foi criado na época
em que os microprocessadores tinham uns poucos registradores internos que poderiam ser
utilizados para o armazenamento de dados temporários. Os microcontroladores de hoje possuem
menória RAM interna, o que elimina a necessidade do especificador register.
22. Dar à variável um escopo local. Não é necessário, no entanto, a utilização desse especificador,
uma vez que uma variável local, quando é criada, é automaticamente definida como automática.
23. É um valor numérico que não pode ser alterado. Uma constante pode ser também uma string. Da
mesma forma que o valor numérico, a constante string não pode ser alterada.
24.
Decimal: YY
Hexadecimal: 0xYY
Octal: OYY
Binário: 0bYYYYYYYY
ASCII: 'Y'
Y: valor numérico
25. Associa um valor numérico a uma string.
26. A forma com que eles são representados. Um caractere é representado entre apóstrofos e uma
string é representada entre aspas.

Respostas dos Exercícios \9\


Capítulo 7

1. Lógico, relacionais, bit a bit, operadores especiais.


2. Atribuir a uma variável o resultado de uma expressão.
int x;
x=10;

3. x = y = z = 20;

4.
Operador Ação
− Subtração
+ Adição
* Multiplicação
/ Divisão
% Resto da divisão
−− Decremento
++ Incremento

5. Deslocar os bits que representam o conteúdo de uma variável para a esquerda (<<) ou para a
direita (>>).
6. y=15 e x=16.
7.
Mais alta ++ --
* / %
Mais baixa + -
8.
Operador Ação
> Maior que
>= Maior ou igual a
< Menor que
<= Menor ou igual a
== Igual a
!= Diferente de

9. O operador = é de atribuição e o operador == é usado para a comparação entre dois valores.


10. ≠ 0 para verdadeiro e = 0 para falso.
11.
Mais alta > >= < <=
Mais baixa == !=

\ 10 \ Microcontroladores PIC18 com Linguagem C


12.
Operador Ação
&& AND
|| OU
! NOT

13. 1 se a expressão for verdadeira e 0 se ela for falsa.


14.
Mais alta !
> >= < <=
== !=
&&
Mais baixa ||
15.
Operador Ação
& AND
| OR
^ XOR
~ Complemento de 1
>> Deslocamento à direita
<< Deslocamento à esquerda

16. z = 000100002
17. O operador xor.
Exemplo:
x = 20;
y = x;
z = x^y;

18. Basta testar o bit mais significativo do valor. Se ele for '1', significa que o valor é negativo. Isso
pode ser feito com o operador lógico bit a bit &.
19.
char introd_nibble(char x) //função introd_nibble
{
char y; /*declaração de variável local não inicializada*/
y = (x & 0x0f) | 0b10100000; /*máscara nibble superior que introduz o nibble 1010 na parte alta de x */
return y; //retorna y
}
20. O bit mais significativo do valor.
21. Efetuar o deslocamento dos bits do conteúdo armazenado em uma variável para a esquerda (<<)
ou para a direita (>>).
22. x = 4;
y = x;
x <<= 2;
x += y;

Respostas dos Exercícios \ 11 \


23. variável = Exp1 ? Exp2 : Exp3;
Quando o comando é executado, a Exp1 é avaliada. Se ela for avaliada como verdadeira, a Exp2
assume o valor da expressão que será atribuída à variável. Caso Exp1 seja avaliada como falsa,
Exp3 assume o valor da expressão que será atribuída à variável.
24. É o operador * antes do nome da variável. Sua função é informar ao compilador que aquela é
uma variável de ponteiro.
25. O operador &.
26. O operador cast ou especificador de tipo é utilizado quando é necessário forçar uma expressão
a ser tornar um tipo específico de dado. A forma geral do uso do cast é:
(tipo) expressão
tipo: é um tipo de dado padrão em C.
expressão: pode ser uma variável ou uma expressão válida em C.
27. O operador sizeof retorna, em bytes, o tamanho da variável ou do especificador de tipo que ele
precede. O tipo_de_dado pode ser qualquer tipo de dado reconhecido pelo compilador.
sizeof variavel
sizeof (tipo_de_dado)

28. y = (x=1, x+=2, x= x *5);


29. Exemplo: x = x + 10;
O comando anterior pode ser abreviado da seguinte forma:
x+= 10;

30.
Mais alta () [] ->
! ~ ++ -- (tipo) * & sizeof
* / %
+ -
<< >>
<<= >>=
== !=
&
^
|
&&
||
?
= += -= *= /=
Menor ,

\ 12 \ Microcontroladores PIC18 com Linguagem C


Capítulo 8

1. Seleção, iteração e desvio.


2. If(expressão) comando1;

else comando2;

O comando if testa a expressão. Sendo ela verdadeira, o comando1 é executado. Caso a


expressão seja falsa, o comando2 é executado. Não se pode esquecer de que em C, verdadeiro
é qualquer valor diferente de zero e falso representa o valor zero. Podemos dizer que o comando
if funciona da seguinte forma: se (if) a expressão for verdadeira, é executado o comando1 e, se
não (else), é executado o comando2.
3. O comando switch é utilizado quando desejamos tomar uma determinada ação se uma
expressão assumir o valor de uma constante inteira ou caractere. O comando switch permite a
comparação da expressão com uma lista de constantes que, como definido pelo padrão C ANSI,
pode ter pelo menos 257 valores diferentes.
4. O comando switch compara o valor da expressão com as constantes associadas às diversas
cláusulas case, na ordem, de cima para baixo. Se ocorrer uma coincidência, a sequência de
comandos associada àquela cláusula case será executada.
5. Não havendo nenhuma coincidência com as constantes associadas às cláusulas case, a sequên-
cia de comandos associada à cláusula default será executada. A cláusula default não é obriga-
tória, não sendo tomada nenhuma ação caso não tenha ocorrido nenhuma coincidência se ela for
omitida.
6. Em determinadas situações o comando switch pode substituir o comando if, porém é importante
ressaltar que o comando switch só pode testar igualdade, não sendo possível efetuar avaliação
de expressões lógicas ou relacionais com esse comando.
7. Os comandos de iteração são os laços for, while e do-while.
8. for(inicialização; condição; incremento) comando;

A seção inicialização é utilizada para atribuir um valor inicial à variável de controle do laço. A
seção condição é uma expressão relacional que será testada após a execução do comando
para determinar quando a repetição na execução do comando termina. A seção incremento
define como o conteúdo da variável de controle irá variar, determinando o número de vezes que a
execução do comando irá acontecer. O comando pode ser um único comando, um bloco de
códigos ou um comando vazio.
9. Se a expressão testada na seção condição for dada como falsa na entrada do laço, o comando
não será executado uma única vez.

Respostas dos Exercícios \ 13 \


10. while(condição) comando;

Quando o laço while é executado, primeiramente é testada a condição que pode ser qualquer
expressão válida em C. Caso a expressão seja verdadeira, o comando é executado e, em
seguida, a expressão é novamente testada. O ciclo se repete até que a expressão se torne falsa,
quando então o laço é finalizado. É importante observar que, como a condição é testada no início
do laço, o comando pode não ser executado caso a expressão seja falsa no primeiro teste. O
comando pode ser um único comando, um bloco de códigos ou um comando vazio.
11. O comando while testa a expressão na entrada do laço enquanto o comando do-while testa a
condição na saída do laço. Ao contrário do comando while, quando o comando do-while dá a
expressão testada como falsa, o comando é executado uma vez.
12. Os comandos de desvio provocam um desvio incondicional no programa que fará com que o
processamento desvie para uma localidade da memória de programa fora da sequência de
execução. Exemplos: return, goto e break.
13. Uma vez que a função foi prototipada, ela pode ser definida no programa-fonte após a função
main() ou até mesmo ser editada em outro arquivo.
14. O comando return é utilizado quando é preciso retornar de uma função. Quando ele é executado,
ocorre um desvio incondicional e o programa retorna para o comando imediatamente após aquele
que fez a chamada à função que está sendo executada. De uma forma geral, a chamada a uma
função também provoca um desvio incondicional, porém o endereço de memória de programa
onde está armazenada a primeira instrução a ser executada após o retorno é guardado em uma
pilha. Quando o comando return é executado dentro da função, o endereço de retorno é retirado
da pilha e utilizado para que o microcontrolador encontre a próxima instrução que será
executada.
15. Com o advento da programação estruturada, o comando goto acabou caindo em desuso porque
ele possuía uma grande tendência de deixar o código ilegível à medida que ia crescendo. Sendo
a linguagem C de natureza estruturada, em qualquer aplicação, por maior e mais complexa que
ela seja, não é necessário o uso do comando goto. A base da programação estruturada é a
chamada à função, que não precisa do comando goto.
16. Ele pode ser utilizado para terminar uma cláusula case em um comando switch ou para finalizar
antecipadamente um laço de repetição. Quando o comando break é encontrado, o laço é
imediatamente finalizado e o programa prossegue para o comando imediatamente após o laço.
O comando break é utilizado, em tese, quando uma condição especial, sendo satisfeita, deva
provocar a saída imediata do laço.
17. O comando continue funciona de forma um pouco parecida com o comando break, com a
diferença de que o comando break força a saída do laço, enquanto o comando continue finaliza
apenas a iteração atual do laço.

\ 14 \ Microcontroladores PIC18 com Linguagem C


Capítulo 9

1. Um vetor, também conhecido como array, é um conjunto de variáveis do mesmo tipo


referenciadas por um mesmo nome. Cada variável que compõe um vetor pode ser acessada
individualmente, sendo a sua posição dentro do vetor denominada índice. Todos os índices de
um vetor ocupam posições contíguas de memória.
2. Null
3. char vect [10]="suave"

4. 12 elementos, sendo 11 elementos utilizados para armazenar a string "Casa Blanca" mais um
elemento para armazernar o caractere terminação de string, o caractere '\0'.
5. Variável de ponteiro.
6. Sim. Para passar um vetor como parâmetro para uma função utiliza-se o nome do vetor. Quando
o nome do vetor é passado como parâmetro, o endereço do primeiro elemento do vetor é
passado como parâmetro. Vejamos a fração de código a seguir.
char *p; //declaração de variável de ponteiro
char vogal[10]; //declaração de vetor
p=vogal; //variável p recebe o endereço do primeiro elemento do vetor vogal

Na fração de código anterior é passado para a variável de ponteiro p o endereço inicial do vetor
vogal. A passagem do endereço inicial do vetor vogal para a variável p poderia também ser feita
pelo comando &vogal[0];. Em aplicações profissionais, no entanto, não é comum a utilização do
operador & para a passagem do endereço inicial de um vetor para uma variável de ponteiro.
Normalmente isso é feito utilizando o próprio nome do vetor.
7. Matriz.
8. Chamamos de adimensional um vetor que, na sua declaração, fica a cargo do compilador
calcular a sua dimensão. Se na declaração de um vetor inicializado o tamanho do vetor não for
especificado, o compilador cria um vetor grande o suficiente para conter todos os elementos
presentes na sua inicialização.
Vejamos o exemplo a seguir. São criados dois vetores, um chamado solar do tipo char
inicializado com a string "Hoje eh domingo" e outro de nome vogais do tipo char inicializado com
os caracteres 'A', 'B', 'C', 'D' e 'E'. Como a quantidade de elementos dos vetores não foi fornecida,
o compilador cria um vetor com capacidade de armazenar os dados de inicialização. No caso do
vetor solar o compilador aloca uma localidade de memória adicional para receber o caractere
terminador de string, o caractere null.
char solar[ ] = "Hoje eh domingo!"; //declaração de vetor inicializado
char vogais[ ] = {'A','B', 'C', 'D', 'E'}; //declaração de vetor inicializado

Respostas dos Exercícios \ 15 \


9.
char alfabeto[6][6]={'\0'}; //declaração de matriz inicializada
char x='A'; //declaração de variável inicializada
char i; //declaração de variável inicializada
char j; //declaração de variável inicializada
for(i=0;i<6;i++) //laço de iteração
{
if(x=='Z') break; //finaliza o laço de iteração caso x='Z'
else for(j=0;j<6;j++) //laço de iteração
{
alfabeto[i][j]=x //atribui ao índice i,j o conteúdo de x
if(x=='Z') break; //finaliza o laço de iteração caso x='Z'
else x++; //incrementa x
}
}

10. char * tabela_Hexa(char *p);

Capítulo 10

1. Do ponto de vista físico, uma string é representada na memória por um conjunto de caracteres
terminado pelo caractere null, representado na forma de caractere por '\0' e no código ASCII pelo
valor 0x00.
2. string.h

3. strcat (destino, origem);

strcat: função que concatena strings armazenadas na memória RAM.


destino: aponta para a string que será concatenada com a string apontada por origem.
origem: aponta para a string que será inserida no final da string apontada por destino.
4. O tipo de dado string não faz parte do grupo básico de dados da linguagem C. Isso significa,
entre outras coisas, que várias operações efetuadas com os tipos básicos não funcionam com o
tipo string. Por exemplo, não podemos atribuir uma string a um vetor utilizando o comando de
atribuição =, como é feito com os tipos de dados básicos, exceto na declaração do vetor.
5. A função strcpy() copia uma string apontada por origem para o endereço apontado por destino.
Ambas as strings, de destino e de origem, estão armazenadas na memória RAM.
6. A função strncmp() compara alfabeticamente as duas strings até o caractere n e retorna um
valor numérico da seguinte forma:
< 0 se a String1 for alfabeticamente menor que a String2
> 0 se a String1 for alfabeticamente maior que a String2
== 0 se a String1 for igual a String2

\ 16 \ Microcontroladores PIC18 com Linguagem C


O que importa não é o valor retornado pela função strncmp(), mas o sinal do valor retornado. A
forma geral de declaração da função strncmp() é:
strlncmp (str1, str2, n);
strncmp: função que compara duas strings até um número n de caracteres.
str1: aponta para uma das strings que será comparada.
str2: aponta para uma das strings que será comparada.
n: número máximo de caracteres que será comparado.
7. O comando peocura o caractere 'a' dentro da string apontada por string. Caso o caractere seja
encontrado, é atribuído à variável x um ponteiro para ele; caso contrário, x recebe um null.
8. strstr()

9. Todas as instruções de manipulação se strings que têm a memória de programa como destino
(*pgm) só funcionam quando o microcontrolador utiliza memória de programa externa. Elas não
funcionam para gravar dados na memória Flash ROM do microcontrolador. O microcontrolador
PIC18F4520 não tem suporte para memória de programa externa. Sendo assim, essas instruções
não surtirão o efeito desejado nesse microcontrolador.
10. strlen()

Capítulo 11

1. Uma estrutura é um conjunto de variáveis, não necessariamente do mesmo tipo, referenciadas


por um mesmo nome, facilitando o acesso a informações relacionadas entre si.
2. As variáveis que compõem uma estrutura são normalmente chamadas de membro ou elementos
da estrutura.
3. Para que uma estrutura possa de fato armazenar dados, é necessário declarar uma variável de
estrutura.
4. Operador ponto.
5. Por valor ou por parâmetro. A linguagem C só aceita passagem de parâmetros por valor.
6. Quando passamos um elemento de uma variável de estrutura como parâmetro para uma função,
será passada uma cópia do valor armazenado naquele elemento.
7. Não. Quando uma estrutura é passada como parâmetro para uma função, é passada uma cópia
da estrutura. Sendo assim, a função que recebeu a estrutura como parâmetro não poderá alterar
os elementos da estrutura que foi passada.
8. O operador seta permite referenciar um elemento de uma variável de estrutura utilizando um
ponteiro para a estrutura.

Respostas dos Exercícios \ 17 \


9. Uma estrutura é aninhada quando um de seus elementos é uma variável de estrutura.
10. É uma estrutura na qual cada elemento é formado por um ou mais bits, daí o nome campos de
bits. O campo de bits é um elemento de estrutura em que é definido o número de bits do campo.
Sendo assim, é possível montar estruturas utilizando campos de bits como elementos. A forma
geral de definição de uma estrutura de campos de bits é mostrada a seguir.
struct identificador
{
tipo elemento1 : comprimento ;
tipo elemento2 : comprimento ;
tipo elemento3 : comprimento ;
.
.
.
} listas_de_variaveis;

identificador: é opcional, podendo ou não ser definido.


elementox: é o nome atribuído ao campo.
comprimento: é o comprimento do campo. Ele não pode ser maior que 8 bits.
tipo: normalmente é definido como unsigned, embora ele possa ser definido como outros
tipos de dados suportados pelo compilador.
lista_de_variáveis: são variáveis de estrutura que opcionalmente podem ser declaradas.
Se a estrutura for anônima, pelo menos uma variável deve ser declarada no momento da
declaração da estrutura.
11. Uma união se assemelha bastante a uma estrutura. Existe, no entanto, uma diferença
fundamental entre elas. Quando uma estrutura é declarada, é alocada memória para cada um
dos elementos que a compõem quando uma variável de estrutura é criada. Em uma união, o
espaço de memória alocado é o comprimento do maior elemento que a compõe.
12. Enumeração.
13. Qualquer tipo de dado válido em C pode ter uma nova identificação atribuída a ele. O comando
typedef é utilizado para esse fim. O typedef não cria outro tipo de dado, apenas redefine um tipo
de dado padrão em C para um identificador indicado pelo usuário.

Capítulo 12

1. A ideia principal do conceito de stream está em transformar os dispositivos reais, funcionalmente


diferentes, em dispositivos lógicos chamados streams. Para o programador, cada dispositivo será
visto como uma stream, permitindo escrever caracteres em dispositivos diferentes utilizando as
mesmas funções.

\ 18 \ Microcontroladores PIC18 com Linguagem C


2. As duas streams definidas pelo MPLAB C18 são _H_USART e _H_USER. A primeira se refere
ao periférico UART como destino para as funções de saída de caracteres. A stream _H_USER
permite ao usuário estabelecer um destino diferente para as funções de saída de caracteres.
3. Para selecionar uma das streams definidas pelo MPLAB C18 utilizamos as variáveis globais
stdout e stderr, definidas na biblioteca do compilador e que possuem o valor default de
_H_USART. A stream _H_USART está associada ao periférico UART, o qual servirá de arquivo
de saída padrão para essa stream.
A variável stdout define a stream para as funções de saída de caracteres. A variável stderr
define a stream para onde devem ser enviadas as mensagens de erro geradas pelo programa.
Ambas as variáveis, stdout e stderr, tendo o valor default _H_USART, definem como arquivo de
saída padrão o periférico UART.
4. Significa que pode ser passado como parâmetro para essas funções o conteúdo de variáveis, o
qual é convertido em strings na forma como os caracteres de formatação definirem.
5. Caractere %.
6. Cinco. São eles: Caractere flag, Comprimento do campo, Precisão do campo, Tamanho do
campo, Operador de conversão.
7. Os caracteres de barra invertida foram incorporados à linguagem C em substituição a alguns
caracteres de controle que são impossíveis de inserir pelo teclado. Dentre eles podemos destacar
o caractere retorno de carro (CR), caractere correspondente a tecla Enter.
\b: retrocesso (BS).
\n: nova linha (LF).
\r: retorno de carro (CR).
8. %d
9. A função printf() envia para a stream atribuída à variável stdout, _H_USART por default, a string
que foi passada como parâmetro.
10. A função vfprintf() é funcionalmente equivalente à função fprintf(), com a diferença de que os
parâmetros passados para a segunda foram substituídos por um ponteiro para esses parâmetros
na primeira. O ponteiro, no entanto, não pode ser qualquer um, mas um ponteiro do tipo va_list,
definido no arquivo cabeçalho stdarg.h.
11. A função sprintf().
12. Significa que a função pode receber parâmetros de comprimento variável.
13. Premitir a funções receber parâmetros com comprimento variável.
14. vfprintf(),vprintf() e vsprintf().
15. A função _user_putc() envia um simples caractere para um arquivo de saída definido pelo
usuário. Ela é invocada quando uma função de saída de caracteres envia dados para a
stream _H_USER.

Respostas dos Exercícios \ 19 \


Capítulo 13

1.
4,5V< VDD < 5,5V
Entrada Mín Máx Nível Lógico
VIL (tensão de entrada baixa) 0V 0,8V 0
VIH (tensão de entrada alta) 2V VDD 1
Saída Mín Máx Nível Lógico
VOL (tensão de saída baixa) 0V 0,6V 0
VOH (tensão de saída alta) VDD - 0,7V - 1

2.

3. 20mA
4. 2V
5. Quando um LED é acionado por lógica positiva, é preciso aplicar nível lógico '1' para ele emitir.
Quando ele é acionado por lógica negativa, é necessário aplicar nível lógico '0' para ele emitir. A
forma como o hardware está implementado vai definir se o LED será acionado por lógica positiva
ou negativa.
6. 5x525 teclas.
7. 4 linhas + 4 colunas = 8 pinos
8.
'0' a 'F': caso uma tecla seja detectada como pressionada. Nesse caso, a função retorna,
no código ASCII, o valor da tecla pressionada.
'\0': caso nenhuma tecla esteja pressionada, a função retorna o caractere null.
'G': caso uma tecla tenha sido detectada como pressionada no último rastreamento, a
função retorna o caractere 'G'.

\ 20 \ Microcontroladores PIC18 com Linguagem C


Capítulo 14

1. Display catodo comum e anodo comum. O nome catodo comum deriva do fato de que todos os
catodos de todos os LEDs estão interligados. Da mesma forma, o display anodo comum deriva
do fato de que todos os terminais anodo de todos os LEDs estão conectados.
2. Segmentos A, B, C, D, F, G.
3. A técnica consiste em conectar os segmentos de um display aos segmentos de mesmo nome dos
outros displays e, no caso do display catodo comum, aterrar apenas o catodo do display que
estará emitindo. Apenas um dos displays pode emitir de cada vez pelo fato de as linhas de dados
estarem multiplexadas. A solução para o problema resume-se no fato de que um LED piscando
em uma frequência acima de 50Hz faz com que a retina não consiga acompanhar a piscagem,
dando a impressão de que o LED esteja emitindo direto. Os displays emitirão, um de cada vez,
em uma frequência acima de 50Hz para termos a impressão de que todos os displays emitem
simultaneamente.
4. Nesse caso, cada display se mantém aceso durante 4ms e apagado durante 12ms. Isso significa
que o ciclo completo de atualização do display é de 16ms. Como o período de cada ciclo é de
16ms, a frequência de piscagem será de 1 / 16m = 62,5Hz, o suficiente para termos a impressão
de que todos os displays emitirão simultaneamente. É importante lembrar que em cada ciclo
(16ms) cada display só se mantém emitindo durante 4ms.

Capítulo 15

1. No início da década de 1970, descobriu-se que as moléculas do cristal líquido poderiam ser
giradas pela aplicação de uma tensão elétrica, tornando-o, desta forma, transparente ou opaco.
Essa descoberta deu origem ao display de cristal líquido.
2. LCD caractere e LCD gráfico.
3. RS (dado/instrução), R/W (escrita/leitura) e E (pulso de clock).
4. Pino E.
5. Instrução 38h.
6. ♦ Oito bits de dados
Uma linha de caracteres
Formato 5 x 7 mais cursor
Display e cursor desativados
Move cursor para a direita com entrada de um novo caractere
Mensagem não será deslocada com a entrada de um novo caractere

Respostas dos Exercícios \ 21 \


7. Detectar se o LCD terminou de executar a última instrução que lhe foi enviada. Se, ao ser lida, a
linha busy flag fornecer nível lógico '1', significa que o LCD está ocupado executando uma
instrução.
8. 80h e C0h.

Capítulo 16

1. Podemos definir interrupção como um evento de hardware que provoca uma interrupção na
execução do programa e um desvio incondicional para que o evento seja tratado. Uma vez que o
evento foi tratado, o programa retorna ao ponto em que foi interrompido e a sua execução
continua. Podemos dizer que a interrupção é um desvio no programa provocado pelo hardware.
Em aplicações em que se deve tratar um determinado evento de hardware no momento da sua
ocorrência, a interrupção pode ser uma excelente saída.
2. É uma região de memória reservada para armazenar dados ou instruções do programa. Uma
seção pode ser criada na memória de dados ou na memória de programa. Além disso, é possível
atribuir um endereço estático para a seção de dados criada.
3. Cria uma seção de dados não inicializada na memória RAM.
4. O MPLAB® C18, por default, cria as variáveis temporárias utilizadas no programa principal na
seção de dados .tmpdata. Para alterar a seção de dados utilizada para as variáveis temporárias,
deve-se utilizar a sintaxe mostrada a seguir:
#pragma tmpdata nome_da_seção
nome_da_seção: é o nome da seção de dados que substitui a seção .tmpdata no arma-
zenamento de dados temporários.
5. A diretiva #pragma varlocate permite ao compilador otimizar código à medida que ela possibilita
a remoção de instruções de chaveamento de banco no acesso a dados armazenados na
memória RAM. A diretiva #pragma varlocate ajuda o MPLAB C18 a remover instruções de
chaveamento de banco de memória informando a ele a eventual localização de variáveis.
Lembre-se, no entanto, de que a diretiva #pragma varlocate somente deve ser utilizada com
variáveis cujos endereços já foram explicitamente especificados no código.
6. Podem ser definidos dois níveis de prioridade no tratamento de uma interrupção. Uma
interrupção pode ser definida como de alta ou de baixa prioridade.
7. Os níveis de prioridade no tratamento da interrupção são definidos pelo bit IPEN (RCON<7>).
Quando esse bit é setado, o PIC18F4520 utiliza os níveis de prioridade no tratamento da
interrupção, podendo cada interrupção ser configurada como de alta prioridade ou de baixa
prioridade. Quando o bit IPEN é apagado, o PIC18F4520 não utiliza as prioridades, desviando o
programa para o endereço 0008h da memória de programa quando ocorrer o evento que pode
dar origem a uma interrupção. No POR o bit IPEN é apagado, devendo ser setado por software
caso o programador queira utilizar os dois níveis de tratamento de interrupção.

\ 22 \ Microcontroladores PIC18 com Linguagem C


8. 18 fontes de interrução. Como exemplo podemos citar: interrupção externa, interrupção de
estouro do TMR0 e interrupção de recepção de dados pela EUSART.
9. A interrupção provoca um desvio ocasionado por um evento de hardware. Uma chamada à
função provoca um desvio provocado pelo software.

Capítulo 17

1. Uma delas é a utilização de funções desenvolvidas para esta finalidade, as funções de delay. A
outra forma de medição de tempo é por meio dos módulos temporizadores.
2. TCI = 1/(Fosc/4) = 1/(8M/4)=500ns
3. A função Delay10TCYx() gera um delay, em segundos, de dez vezes o valor que lhe é passado
como parâmetro multiplicado pelo tempo correspondente ao ciclo de instrução. A forma geral de
declaração da função Delay10TCYx() é:
Delay10TCYx (valor)

valor: valor multiplicado por dez vezes o ciclo de instrução.


4. No modo temporizador o timer conta ciclos de instrução, enquanto no modo contador o timer
conta a quantidade de pulsos aplicados no pino correspondente, que varia de um timer para
outro.
5. O prescaler retarda o incremento do registrador associado ao timer. O retardo depende do fator
de prescaler aplicado.
6. T0CON.
7. Operando em 8 bits, o incremento será no máximo até o valor 255. Operando em 16 bits, o
incremento será no máximo até o valor 65535.
8. Módulo Timer2.
9. Módulo Timer2. (faltou explicar como ele funciona)
10. Se após a configuração do Timer0 o par de registradores TMR0H:TMR0L for inicializado com o
valor F82Fh, com um prescaler de 1:4 e uma frequência de clock de 8MHz, o TMR0 será
incrementado a cada 4x500n = 2µs. O número de incrementos até que o TMR0 estoure será
dado pela fórmula 65535(FFFFh) – F82Fh = 2000. Ele será incrementado 2000 vezes até o
estouro. Como ele está operando com 16 bits, o tempo decorrido até o estouro será de:
Tempo_estouro = 2000 x 2µ = 4ms
A diferença 65535 − 2000 = 63535 (F82Fh) é o valor com o qual deve ser inicializado o TMR0
para que o número de incrementos necessários até o estouro seja 2000.

Respostas dos Exercícios \ 23 \


Capítulo 18

1. Uma tensão é analógica quando para ir de um valor a outro de intensidade, a tensão elétrica
precisa passar por todos os pontos intermediários de intensidade entre os valores inicial e final.
Por outro lado, a tensão é digital quando normalmente é composta por apenas dois níveis,
representados pelos níveis lógicos '0' e '1'.
2. Transdutor.
3. PCM (Pulse Code Modulation).
4. É a quantidade de partes em que a tensão será dividida.
5. NB = Log101024/Log102 = 10 bits
6. A conversão de um sinal analógico em digital consiste em amostrar o sinal um número de vezes
em cada segundo e associar cada amostra ao valor correspondente à amplitude do sinal naquele
ponto. A amostragem é uma leitura no valor instantâneo da tensão de tempos em tempos.
Associar um valor proporcional à amplitude do sinal de tempos em tempos é um processo
conhecido como PAM (Pulse Amplitude Modulation).
7. A partir dos pulsos PAM é possível produzir pulsos PCM por meio de um processo conhecido
como quantização, que substitui cada pulso PAM por um conjunto de bits que represente aquele
valor.
8. Em 1928, H. Nyquist provou que um sinal analógico que tenha passado por um filtro passa-
-baixas (FPB) com frequência de corte Fc pode ser completamente reconstituído a partir de um
número de amostras 2 x Fc. Segundo Nyquist, um número maior de amostras seria inútil porque
as frequências acima que 2 x Fc já foram eliminadas pelo filtro.
9. Para garantir que a tensão de saída do filtro não sofra nenhuma queda significativa em relação à
tensão de entrada para qualquer frequência do sinal de entrada, o projetista deve obedecer à
fórmula a seguir, na qual a frequência máxima do sinal de entrada deve ser pelo menos dez
vezes menor que a frequência do filtro passa-baixas.
Fc
Fmáx ≤
10
10. Como o conversor A/D será de 10 bits, é preciso dividir a faixa de tensão em 1024 partes iguais
de tensão. Sendo assim, cada parte terá um valor de 2,048 / 1024 = 2mV.
A frequência de corte será de:
Fc = 10 x Fmáx
Fc = 10 x 25 = 250Hz

\ 24 \ Microcontroladores PIC18 com Linguagem C


Vamos optar por utilizar um FPB RC de primeira ordem. Para dimensionar o FPB podemos
escolher um valor para o resistor R, por exemplo, de 4,7KΩ, e calcular o valor do capacitor C,
visto que já foi calculada Fc. Nesse caso, deduzindo C na fórmula, teremos:
C = 1 / 2. π.4k7.250
C = 135,45nF
O valor comercial inferior mais próximo é 120nF. Com esse valor de C, Fc passa a ser 282,18Hz,
bem próximo dos 250Hz calculados a partir de Fmáx.

11. S = 1,5 / 2m = 750


12. Definir os níveis máximo e mínimo de tensão a serem aplicados no conversor A/D. A tensão de
referência também define a faixa de tensão analógica que será convertida em tensão digital.
13. O conversor A/D interno do PIC18F4520 possui uma resolução de 10 bits. O resultado da
conversão estará disponível em dois registradores de 8 bits, dando um total de 16 bits. A sobra
de bits nos registradores em que o resultado da conversão será armazenado permitiu aos
projetistas deslocar o resultado para a esquerda ou para a direita, procedimento denominado
justificação do resultado.
14. É o tempo necessário para que o capacitor existente na entrada do conversor A/D (CHOLD) possa
se carregar para então ser dado início à conversão.
15. Gerar a base de tempo utilizada na conversão A/D. O período do sinal de clock do conversor,
chamado de TAD, é o tempo necessário para a conversão de cada bit.
16. Na forma manual, o conversor A/D não aguarda o tempo de aquisição para começar a conversão
após o bit que dá início à conversão ter sido setado, o bit GO/DONE. Na conversão automática, o
tempo de aquisição pode ser configurado de 2TAD até 20TAD pelos bits ACQT2:ACQT0 para
qualquer valor diferente de 0002. Nesse caso, quando a conversão é iniciada, o capacitor CHOLD
continua conectado ao canal até o tempo de aquisição configurado. Logo após, CHOLD é desco-
nectado e a conversão tem início.
17.

18. Treze canais de coversão, e apenas um deles pode ser ativado de cada vez.
19. O bit ADIE(PIE1<6>).
20. O módulo conversor A/D do PIC18F4520 pode funcionar no modo sleep desde que o clock
utilizado na conversão A/D seja gerado pelo circuito RC interno ao módulo conversor. Para
selecionar o clock gerado pelo circuito RC, é necessário fazer os bits ADCS2:ADCS0 = x11.
Quando o clock gerado pelo circuito RC é selecionado, o módulo conversor A/D aguarda um ciclo de

Respostas dos Exercícios \ 25 \


instrução para começar a conversão após o bit GO/ DONE ter sido setado. Isso permite que a
instrução SLEEP seja executada, fazendo com que o microcontrolador entre no modo sleep sem
interromper a conversão A/D. Quando a conversão terminar, o bit GO/ DONE será apagado, o flag
de sinalização de fim de conversão será setado e o resultado da conversão armazenado nos
registradores ADRESH:ADRESL. Se a interrupção do módulo conversor A/D estiver habilitada, o
microcontrolador acorda; caso contrário, o módulo conversor A/D será desligado, embora o bit
ADON se mantenha setado.

Capítulo 19

1. O PWM é um sinal digital com frequência fixa e com ciclo ativo variável.
2. É a parte do ciclo em que o sinal se mantém em nível lógico '1'.
3. Duty cycle é a relação entre o ciclo ativo e o período do sinal PWM e é diretamente proporcional
ao nível DC do sinal. O duty cycle é também adimensional e seu valor pode variar entre 0 e 1.
4. Fazê-lo passar por um filtro passa-baixas com frequência de corte pelo menos dez vezes menor
que a frequência do sinal PWM.
5. PR2 = [F(osc) / (F(PWM) × 4 × Prescaler do TMR2)] – 1

PR2 = [8x106 / (31.250 x 4 x 1)] – 1


PR2 = 63
6. O controle do ciclo ativo do sinal PWM é feito a partir de uma divisão do período do sinal PWM
em partes iguais de tempo que recebem o nome de passos. O número de passos em que o
período do sinal será dividido depende do número de bits de controle utilizado.
Dividindo o período do sinal PWM pelo número de passos, calcula-se o tempo correspondente a
cada passo (Tp). O Tp é o tempo mínimo no qual o ciclo ativo do sinal PWM pode variar.

7.
FOSC b) Np = (PR2 + 1) × 4
a) PR 2 = −1
FPWM × 4 × (Pr escaler do TMR 2) Np = (63 + 1) × 4
8M Np = 256 passos
PR 2 = −1
31.250 × 4 ×1
PR2 = 63

\ 26 \ Microcontroladores PIC18 com Linguagem C


1 1 d) PWM ( ciclo ativo ) = Tp × 50
c) TPWM = =
FPWM 31.250
PWM ( ciclo ativo ) = 125n × 50
TPWM = 32 μS
PWM ( ciclo ativo ) = 6,25μS
T 32 μS
Tp = PWM = Tp = 125ns
Np 512
PWM ( ciclo ativo ) f) Diagrama de tempo
e) Vdc = × V( alto )
TPWM
6,25μ
Vdc = ×5
32 μ
Vdc = 0,97V

Capítulo 20

1. Permitir a comunicação entre dispositivos onboard, ou seja, dispositivos que estão instalados na
mesma placa de circuito impresso.
2. Mestre e escravo. O mestre é o responsável pela geração do sinal do clock.
3. Condição START e condição STOP.
4. O barramento I2C permite que seja alterada a direção do fluxo dos dados durante uma trans-
missão em andamento sem que o dispositivo mestre precise antes finalizar a transmissão
corrente com uma condição STOP. Isso é permitido impondo uma condição Re-START no
barramento após o último byte transmitido. Alterar a direção do fluxo dos dados significa alterar
de um ciclo de leitura para um ciclo de escrita ou vice-versa.
5. O endereçamento pode ser efetuado com 7 bits ou com 10 bits de endereços.
6. O barramento I2C possui um recurso que permite ao dispositivo mestre endereçar todos os dis-
positivos escravos simultaneamente. Isso é feito por meio do endereçamento de chamada geral,
cujo uso pode ser interessante quando o dispositivo mestre desejar enviar dados para todos os
dispositivos escravos simultaneamente, um tipo de comunicação conhecido como broadcast.
7. O barramento I2C permite a conexão de vários dispositivos mestres no mesmo barramento de
forma que todos possam transmitir e receber informações, porém não simultaneamente. Isso
significa que apenas um dos dispositivos mestres pode assumir o controle do barramento de
cada vez. É importante observar também que cada dispositivo mestre gera o seu próprio sinal de
clock.

Respostas dos Exercícios \ 27 \


8. Quando mais de um dispositivo mestre tenta assumir o controle do barramento no mesmo
instante para efetuar uma transmissão, ocorre uma colisão. Um procedimento denominado
arbitration assegura que apenas um dos mestres vai concluir a transmissão. Os demais vão
abortar a transmissão à medida que vão perdendo a arbitration. O dispositivo mestre que dará
continuidade à transmissão será o ganhador da arbitration.
O procedimento de arbitration ocorre na linha SDA enquanto a linha SCL estiver em nível lógico
alto. A figura a seguir mostra como é feita uma arbitration. O gráfico DADO 1 mostra o sinal que o
dispositivo mestre 1 está tentando aplicar na linha SDA, enquanto o gráfico DADO 2 apresenta o
sinal que o dispositivo mestre 2 está tentando aplicar na linha SDA. O terceiro gráfico, o SDA,
exibe o sinal que irá realmente aparecer na linha SDA. Observe que o dispositivo mestre 1
perdeu a arbitration no terceiro pulso de clock, uma vez que ele aplicou nível lógico 1 na linha
SDA, tendo prevalecido o nível lógico '0' aplicado na linha SDA pelo dispositivo mestre 2.
Como o dispositivo mestre 1 perdeu a arbitration, ele aborta a transmissão. O dispositivo mestre
2 prossegue a transmissão, tendo em vista que ele foi o ganhador da arbitration. O dispositivo
mestre que perdeu a arbitration deve tentar uma nova transmissão quando o barramento estiver
novamente ocioso. A arbitration garante que dados não sejam perdidos quando dois ou mais
mestres tentam assumir o controle do barramento no mesmo instante. O procedimento de
arbitration não é permitido durante as condições START, STOP e Re-START.

9. O módulo MSSP possui seis registradores utilizados na configuração e no controle do barramento


I2C. São eles SSPSTAT, SSPCON, SSPCON2, SSPBUF, SSPSR e SSPADD.
10. Um microcontrolador configurado como dispositivo mestre pode dar início a um dos eventos
descritos a seguir:
Gerar a condição START
Gerar a condição Re-START
Iniciar a transmissão de um byte escrevendo no registrador SSPBUF (mestre-transmissor)
Configurar a interface I2C para receber dados (mestre-receptor)
Gerar um pulso ACK (ou um NACK) no final de um byte recebido (mestre-receptor)
Gerar a condição STOP e finalizar a transmissão
11. Gerar a condição START, enviar o byte de endereços junto com a direção do fluxo dos dados

\ 28 \ Microcontroladores PIC18 com Linguagem C


como escrita, enviar o byte de dados e gerar uma condição STOP no barramento.
12. Em um barramento I2C as linhas SDA e SCL precisam estar conectadas à linha de alimentação VDD
por meio de resistores pull-ups. A função desses resistores, entre outras coisas, é impor nível alto à
linha.
13. O 24C08 tem uma capacidade de armazenamento de 8kbits (1k × 8). Em outras palavras, ele
possui 1k (1024) de localidades de memória EEPROM com capacidade de armazenamento de
8 bits em cada localidade.

Capítulo 21

1. O barramento SPI é composto por três linhas: serial data out (SDO), serial data in (SDI) e serial
clock (SCK). Adicionalmente, um quarto sinal pode ser utilizado como chip select e pode
selecionar o dispositivo com o qual o mestre vai se comunicar caso existam vários escravos
conectados no barramento. Esse quarto sinal é o SS .
2. Sim. Um barramento SPI pode ter um mestre e vários escravos. Cada escravo será ativo por uma
linha de controle adicional chamada chip select. Apenas um dispositivo escravo pode estar ativo
de cada vez.
3. Os bits SSPM3:SSPM0(SSPCON1<3:0>) são os responsáveis por a configuração do dispositivo
operar como mestre ou como escravo, como mostrado a seguir.
0011 = SPI modo mestre, clock = saída do TMR2 / 2
1000 = SPI modo mestre, clock = Fosc / 64
0111 = SPI modo mestre, clock = Fosc / 16
0110 = SPI modo mestre, clock = Fosc / 4
Além disso, para ativar a interface SPI é necessário setar o bit SSPEN (SSPCON1<5>). A
polaridade do clock é configurada pelo bit CKP (SSPCON1<4>), ou seja, o bit CKP define se o
estado ocioso do clock será o nível alto ou o nível baixo. O estado ocioso é o nível lógico no qual
a linha de clock deve se manter quando nenhuma transmissão estiver em andamento. O bit CKE
(SSPSTAT<6>) define se a transmissão de cada bit ocorre na transição de ativo para ocioso ou
na transição de ocioso para ativo do sinal de clock. O bit CKE determina o momento em que o bit
deve ser amostrado no dispositivo escravo. O bit SMP (SSPSTAT<7>) define o momento em que
cada bit recebido será amostrado, se na metade ou se no final do time bit. Além disso, é
necessário configurar como entrada a linha SDI e como saída as linhas SDO, SS e SCK. A
fração de código a seguir mostra como configurar a interface SPI para operar como mestre, com
uma taxa de transferência de 125kbps, com o sinal de clock ocioso em nível alto, com a
transmissão do dado ocorrendo na transição de estado ocioso para ativo do sinal de clock e com
o bit de entrada sendo amostrado no fim do time bit.

Respostas dos Exercícios \ 29 \


#define _SS PORTCbits.RC1 //define linha chip select
//****************************************************************************
//Configuração do modulo SPI como mestre com taxa de 125kbps
void Configura_SPI (void)
TRISCbits. TRISC5 = 0; //configura SDO como saída
TRISCbits. TRISC4 = 1; //configura SDI como entrada
TRISCbits. TRISC3 = 0; //configura SCK como saída
TRISCbits. TRISC1 = 0; //configura linha _SS como saída
_SS = 1; //desabilita chip select
SSPCON1 = 0b00110000; /*habilita módulo SPI <5>
bit rate 125kbps (Fosc/64)<3:0>
clock ocioso em nível alto<4>*/
SSPSTAT = 0b00000000; /*dado de entrada é amostrado no fim do time bit do dado de saída<7>
transmissão ocorre do estado ocioso para o estado ativo do clock <6>*/
//****************************************************************************

4. 10Mbps.
5. Independente de o dispositivo mestre precisar enviar e/ou receber dados, é necessário escrever
no registrador SSPBUF para dar início a uma transmissão, aguardar a recepção ser finalizada e,
em seguida, efetuar a leitura do registrador SSPBUF, onde estará armazenado o byte recebido
na transmissão corrente.
6. É setado o bit de sinalização de final de transmissão, o bit SSPIF.
7. O MCP41010 é um potenciômetro digital implementado em circuito integrado com um valor
nominal de 10kΩ, fabricado pela Microchip Technology. O protocolo de comunicação utilizado na
comunicação com o MCP41010 é o SPI.
8. É possível, por meio de software, colocar o potenciômetro em um modo chamado shutdown, no
qual o terminal A do potenciômetro é desconectado do meio exterior, enquanto o cursor é unido
ao terminal B. O modo shutdown é conveniente quando o usuário deseja colocar o circuito em
modo de economia de energia.

Capítulo 22

1. UART (Universal Asynchronous Receiver Transmiter) é um protocolo de comunicação serial


assíncrono desenvolvido na década de 1960 para permitir a comunicação ponto a ponto entre
computadores mainframes e computadores terminais remotos.
2. Meio ocioso.
3. Taxa de transferência, quantidade de bits de dados, inclusão ou não do bit de paridade, tamanho
do stop bit e controle de fluxo.
4. É o tempo no qual cada bit se mantém na linha de transmissão. O período do bit define a taxa de
transferência da transmissão.

\ 30 \ Microcontroladores PIC18 com Linguagem C


5. Par, ímpar, marca ou espaço.
Paridade par: a soma dos bits de dados iguais a 1 mais o bit de paridade tem de ser par.
Paridade ímpar: a soma dos bits de dados iguais a 1 mais o bit de paridade tem de ser ímpar.
Marca: o bit de paridade é sempre 1.
Espaço: o bit de paridade é sempre 0.
6. A principal evolução da EUSART é a capacidade de detectar automaticamente a taxa de
transferência, um recurso chamado de auto-baud rate detect. Essa característica está disponível
somente no modo de transmissão assíncrono.
7. TXSTA, RCSTA e BAUDCON.
8. Para transmissão em alta velocidade e com gerador de baud rate de 16 bits, o valor a ser escrito
no par de registradores SPBRGH:SPBRG é 207.
9. Bit SYNC(TXSTA<4>)
10.
Inicializar o registrador SPBRGH:SPBRG para o baud rate desejado.
Configurar os pinos RC7:RC6 como entrada.
Habilitar a porta de comunicação serial apagando o bit SYNC e setando o bit SPEN.
Habilitar a interrupção se for desejado.
Setar o bit RX9 se a recepção for de 9 bits.
Habilitar o transmissor setando o bit TXEN, o qual setará também o bit TXIF.
Se a transmissão for de 9 bits, escrever o nono bit no bit TXD9.
Carregar o dado a ser transmitido no registrador TXREG (a transmissão terá início).
A transmissão estará finalizada quando o bit TRMT for setado pelo hardware.
11. O padrão RS-232 define uma faixa de tensão que deve ser identificada pelos terminais como
níveis lógicos '0' e '1'. O nível lógico '1' é representado pela faixa de tensão de –3V a –15V. Da
mesma forma, o nível lógico '0' é identificado pela faixa de tensão de 3V a 15V. A faixa de tensão
de –3V a +3V é uma região de transição, sendo, portanto, de nível lógico indefinido.
12. O padrão RS-232 foi inicialmente desenvolvido para permitir a comunicação entre computadores
conectados a um modem. É muito comum, no entanto, a necessidade de comunicação entre
computadores que estejam fisicamente próximos. Nesse caso, não será necessária a utilização
de um modem, mas isso não impede a conexão dos computadores via RS-232. O problema é
que esta é uma comunicação direta entre dois DTEs e fere a norma de utilização do padrão
RS-232, desenvolvida para a comunicação entre um DTE e um DCE. Para resolver o problema
foi criado um tipo de conexão chamado Null modem (sem modem).

Respostas dos Exercícios \ 31 \


13.
Número Nome Descrição
Direção
do pino do sinal do sinal
1 Entrada DCD Data Carrier Detect
2 Entrada RD Receiver Data
3 Saída TD Transmiter Data
4 Saída DTR Data Terminal Ready
5 - Gnd Common
6 Entrada DSR Data Set Ready
7 Saída RTS Request To Send
8 Entrada CTS Clear To Send
9 Entrada RI Ring Indicator

14. Várias empresas fabricam um circuito integrado que permite ao microcontrolador interfacear com
o padrão RS-232. O que esse CI faz é converter os níveis de tensão correspondentes à lógica
TTL no padrão RS-232 e vice-versa.
15.
PIC18F4520
Taxa de transferência 110 a 1.250.000bps
Número de bits 8 ou 9
Bit de paridade Não suporta
Stop bit 1
Controle de fluxo Não suporta

16.
//inicializa USART
void Configura_UART (void)
{
TRISCbits.TRISC7 = 1; //configura pino RX como entrada
TRISCbits.TRISC6 = 1; //configura pino TX como entrada
TXSTA = 0b00100100; //transmissão habilitada<5>
//transmissão assíncrona<4>
//transmissão em alta velocidade<2>
RCSTA = 0b10010000; //porta serial habilitada<7>
//recepção contínua habilitada<4>
BAUDCON = 0b00000000; //TX ocioso em nível alto<4>
//gerador de baud rate de 8 bits<3>
SPBRG = 12; //9600bps

\ 32 \ Microcontroladores PIC18 com Linguagem C


Capítulo 23

1. Podemos dividir o trabalho de compilar uma aplicação em C em três partes. São elas o
pré-processamento, a compilação e a linkedição.
O pré-processamento permite incluir no programa-fonte diversos comandos que não fazem parte
da linguagem C, mas são reconhecidos pelo compilador. Esses comandos são chamados dire-
tivas de compilação.
A compilação (ou pré-compilação) tem o objetivo de interpretar os comandos pertencentes à
linguagem C existentes no programa-fonte e gerar um bloco de códigos intermediário chamado
arquivo objeto.
A última etapa, de linkedição, combina os diversos arquivos objeto e arquivos biblioteca com o
link script para gerar o programa executável. Este último contém toda a aplicação representada
em linguagem de máquina.
2. O MPLAB C18 possui um módulo chamado MPLIB librarian, responsável pela criação de
arquivos biblioteca. O MPLIB combina os arquivos objeto gerados pelo MPASM assembler e pelo
MPLAB C18 em um único arquivo biblioteca. O arquivo gerado pelo MPLIB, cuja extensão é .lib,
pode ser utilizado como entrada para o MPLNK gerar o arquivo executável.
3. #if e #endif
4. A diretiva #error força o compilador a parar a compilação caso seja encontrada pelo pré-
-processador, além de emitir uma mensagem de erro. Sua principal finalidade é na depuração de
uma aplicação, ou seja, um processo que consiste em encontrar e eliminar erros em uma
aplicação.
5. Macro pode ser definida, de uma forma geral, como um padrão de entrada que deve ser
substituído por um padrão de saída, de acordo com um conjunto de regras. Dependendo do
contexto, o termo macro pode ter um significado um pouco diferente. Na linguagem C, pode-se
definir macro como uma porção de código que será substituída por outro identificador na fase de
pré-processamento.
6. O padrão C ANSI define um conjunto de macros que podem ser úteis em determinadas
situações. São elas: __DATE__, __TIME__, __LINE__, __FILE__ e __STDC__ que iniciam com
dois underlines e terminam com dois underlines.
__DATE__: retorna um ponteiro para uma string armazenada na memória de programa com
a data da última compilação.
__TIME__: retorna um ponteiro para uma string armazenada na memória de programa com
a hora da última compilação.
__LINE__: retorna um inteiro com o número da linha do programa-fonte de onde ela foi
chamada.
__FILE__: retorna um ponteiro para uma string armazenada na memória de programa com
o nome do programa-fonte, incluindo o caminho para chegar ao arquivo.
__STDC__: retorna um inteiro informando se o programa-fonte segue o padrão C ANSI.

Respostas dos Exercícios \ 33 \


Caso o programa siga o padrão C ANSI, ela retorna o valor 1; caso contrário, ela retorna
outro valor.
7. _asm e _endasm. A diretiva _asm inicializa o bloco e a _endasm finaliza o bloco.
8. O MPLAB C18 pode ser configurado para funcionar com dois modelos de memória distintos. São
eles o small memory model e o large memory model. A diferença entre os dois modelos é
basicamente o tamanho do ponteiro que indica a memória de programa. No small memory model
o ponteiro utilizado para o acesso às memórias de dados e de programa é de 16 bits. Sendo
assim, o endereçamento da memória está limitado a 64k. No large memory model são utilizados
24 bits no endereçamento da memória. Microcontroladores que possuem mais de 64k de
memória de programa precisam funcionar no large memory model.
9. O MPLAB C18 possui uma pilha de estrutura de dados chamada stack software, na qual são
armazenadas as variáveis locais com classe de armazenamento auto. O tamanho da stack
software pode ser configurado no linker script via diretiva STACK. A diretiva STACK possui dois
argumentos, SIZE e RAM, utilizados para controlar, respectivamente, o tamanho e a localização
da pilha. Por exemplo, para alocar 128 bytes no banco 3 de memória RAM, é necessário atualizar
o linker script com a linha:
STACK SIZE=0x80 RAM=gpr3

10. As instruções estendidas são ADDFSR, ADDULNK, CALLW, MOVSF, PUSHL, SUBFSR e
SUBULNK.
11. O processamento tem início no vetor reset, ou seja, no endereço 0000h da memória de
programa. Antes da execução da função main() é executado um código de inicialização chamado
start-up code que começa com a inicialização dos registradores FSR1 e FSR2 para referenciar a
pilha stack software. Dependendo de como o start-up code é executado, uma função que
inicializa a seção de dados idata na memória de programa é chamada e, posteriormente, é
executado um loop infinito com chamadas à função main().
12. É possível executar um código específico imediatamente após o Reset, antes do start-up code.
Para isso é necessário editar o módulo de inicialização que será linkado com a aplicação e
adicionar o código de inicialização à função _entry(). Seis módulos de inicialização podem ser
utilizados no start-up code. São eles os objetos c018i.o, c018i_e.o, c018.o, c018_e.o, c018iz.o e
c018iz_e.o. Os módulos c018i.o e c018i_e.o inicializam a seção de dados idata, enquanto os
módulos c018.o, c018_e.o não.
13. A otimização tem o objetivo de reduzir o código resultante em uma determinada aplicação.
Podemos citar como exemplo de otimização as opções Duplicate-string merging, Branch
optimizations e Banking optimizer.

\ 34 \ Microcontroladores PIC18 com Linguagem C

Você também pode gostar