Buscar

Apostila.PIC16F877.CCS

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você viu 3, do total de 85 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você viu 6, do total de 85 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você viu 9, do total de 85 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Prévia do material em texto

Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 1
 
 
O Mundo dos 
Microcontroladores 
 
 A situação que nos encontramos hoje no campo de microcontroladores teve seu início 
a partir do desenvolvimento da tecnologia de circuitos integrados. Esse desenvolvimento 
permitiu que pudéssemos instalar centenas de milhares de transistores em um único chip, que 
foi a precondição para a possibilidade de fabricação de microprocessadores. Os primeiros 
computadores foram então desenvolvidos a partir dos microprocessadores, adicionando 
periféricos externos, tais como memórias, linhas de entrada e saída, temporizadores e outros 
circuitos. Aumentando ainda mais a densidade de elementos dentro dos chips resultou no 
desenvolvimento de circuitos que continham ambos, processador e periféricos. Isto mostra 
como o primeiro chip contendo um microcomputador chamado mais tarde de microcontrolador 
foi desenvolvido. 
 
 
1.1 Introdução 
 
 Novatos em eletrônica geralmente pensam que o microcontrolador é o mesmo 
que microprocessador. Isso não é verdade. Eles diferem entre si em muitos aspectos. A 
diferença primeira e mais importante em favor do microcontrolador é a sua 
funcionalidade. Para que o microprocessador possa ser usado, outros componentes, 
como a memória por exemplo, devem ser adicionados a ele. Mesmo sendo considerada 
uma poderosa máquina de computação, não é capaz, por si só, de se comunicar com o 
ambiente externo. A fim de permitir que o microprocessador se comunique com o 
ambiente externo, circuitos especiais devem ser usados. Isto é como era no princípio e 
continua sendo até hoje. 
 Por outro lado, o microcontrolador foi projetado para ser tudo isso em um único 
chip. Não são necessários outros componente externos para a sua aplicação, pois todos 
os circuitos necessários já estão incluídos no mesmo, dentro de um único chip. Isso 
economiza tempo e espaço necessários para projetar um dispositivo. 
 Na figura 1.1 podem ser vistos os componentes periféricos inclusos no chip de 
um microcontrolador de uso geral. Observe que o microcontrolador é formado 
basicamente pelo microprocessador, responsável pelo controle de todo o funcionamento 
do chip, e dos circuitos periféricos como memórias, conversores A/D, circuito oscilador, 
etc. 
 
 
 
Capítulo 1 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 2
 
 
 
 
Figura 1.1 – Elementos construtivos de um microcontrolador de uso geral. 
 
 Dispositivos eletrônicos capazes de controlar um pequeno submarino, um 
guindaste ou um elevador já são construídos em um único chip. Os microcontroladores 
oferecem uma ampla gama de aplicações e, normalmente, apenas algumas delas são 
usadas. É critério do projetista decidir o que ele quer que o microcontrolador faça no seu 
produto. Para isso, o projetista descarrega um programa contendo instruções adequadas 
para que o microcontrolador execute a ação desejada. Antes de conceber o seu produto 
final, seu funcionamento deve ser testado por um simulador. Se tudo funcionar bem, o 
microcontrolador é inserido no dispositivo. Se há necessidade de alterações no 
comportamento do produto, melhorias ou atualizações, basta fazê-lo. Até quando? Até 
que sinta-se satisfeito. 
 Na figura 1.2 pode ser observado, de uma forma cômica, o fluxo de 
desenvolvimento de um projeto que utiliza microcontroladores como principal 
elemento. A rigor, um projeto baseado em microcontroladores consiste no estudo do 
dispositivo a ser controlado pelo microcontrolador. Baseado nas características desse 
dispositivo, o projetista deve identificar as necessidades de hardware tais como número 
de entradas/saídas, temporizadores, conversores A/D, etc, para o seu controle. Com as 
necessidades de hardware identificadas, o projetista deve escolher um microcontrolador 
que possua aqueles requisitos e que satisfaça às suas necessidades. Usando um 
computador pessoal e uma linguagem de programação de alto nível, deve-se escrever 
um programa para rodar no microcontrolador. Enquanto programa, usa-se o computador 
para fazer simulações e testar o seu funcionamento. O programa escrito deve ser 
convertido em código que pode ser interpretado pelo microcontrolador. Com o auxílio 
de um programador, esse código deve ser descarregado dentro da memória do 
microcontrolador. Uma vez que o microcontrolador possua em sua memória as 
instruções a serem executadas, basta instalá-lo no dispositivo a ser controlado. 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 3
 
 
Figura 1.2 – Fluxo de desenvolvimento de um projeto utilizando microcontroladores. 
 
 
 
 
 
 
Diga tchau para a 
sua família por 
alguns dias 
Alimente seus 
animais de 
estimação 
Estude a máquina a ser 
controlada pelo microcontrolador 
Procure pelas 
características 
disponíveis em cada 
microcontrolador 
Escolha as que atendem 
suas necessidades 
Projete e construa um 
hardware para 
conectar o 
microcontrolador ao 
mundo externo 
Use um 
computador 
para escrever o 
programa a ser 
executado Converta o programa em 
código de máquina e 
descarregue esse código na 
memória do microcontrolador 
Insira o microcontrolador já programado 
no dispositivo a ser controlado 
Aproveite o sucesso e comece a 
pensar em novos projetos 
 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 4
1.2 Sistemas numéricos 
 
Sistema de Numeração Decimal 
 
 O sistema decimal é um sistema de numeração posicional que utiliza a base dez. 
 Baseia-se em uma numeração de posição, onde os dez algarismos indo-arábicos: 
0 1 2 3 4 5 6 7 8 9 servem para contar unidades, dezenas, centenas, etc. da direita para a 
esquerda. Contrariamente à numeração romana, o algarismo árabe tem um valor 
diferente segundo sua posição no número: assim, em 111, o primeiro algarismo 
significa 100, o segundo algarismo 10 e o terceiro 1, enquanto que em VIII (oito em 
numeração romana) os três I significam todos 1. 
Assim: 
 
 
 
 Da direita para esquerda, o primeiro dígito representa as unidades, o segundo as 
dezenas, o terceiro as centenas e assim sucessivamente. 
 No sistema decimal o símbolo 0 (zero) posicionado à esquerda do número 
escrito não altera seu valor representativo. Assim: 1; 01; 001 ou 0001 representam a 
mesma grandeza, neste caso a unidade. O símbolo zero posto à direita implica 
multiplicar a grandeza pela base, ou seja, por 10 (dez). 
 
Sistema de Numeração Binário 
 
 O que aconteceria se apenas dois dígitos fossem usados - 0 e 1? Ou se não 
soubéssemos como determinar se algo é 3 ou 5 vezes maior do que qualquer outra 
coisa? Ou se estivéssemos restritos a comparar dois tamanhos, ou seja, se só podemos 
afirmar que algo existe (1) ou não existe (0)? A resposta é "nada de especial". 
Gostaríamos de continuar a usar os números da mesma forma como o fazemos agora, 
mas seria um pouco diferente. Por exemplo: 11011010. Quantas páginas de um livro são 
representadas pelo número 11011010? A fim de aprender isso, você apenas tem que 
seguir a mesma lógica que no exemplo anterior, mas em ordem inversa. Tenha em 
mente que tudo isso é sobre matemática apenas com dois dígitos, 0 e 1, ou seja, a base 
do sistema de número 2 (sistema de números binários). 
 O sistema binário ou base 2, é um sistema de numeração posicional em que 
todas as quantidades se representam com base em dois números, com o que se dispõe 
das cifras: zero e um (0 e 1). 
 Os computadores digitais, e também os microcontroladores trabalham 
internamente com dois níveis de tensão, visto que o seu sistema de numeração natural é 
o sistema binário (ligado, desligado). O sistema binário é a base para a Álgebra 
booleana (de George Boole - matemático inglês), que permite fazer operaçõeslógicas e 
aritméticas usando-se apenas dois dígitos ou dois estados (sim e não, falso e verdadeiro, 
tudo ou nada, 1 e 0, ligado e desligado). Toda a eletrônica digital e computação estão 
baseadas nesse sistema binário e na lógica de Boole, que permite representar por 
circuitos eletrônicos digitais (portas lógicas) os números, caracteres, realizar operações 
lógicas e aritméticas. 
 
 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 5
Sistema de Numeração Hexadecimal 
 
 No início do desenvolvimento dos computadores foi percebido que as pessoas 
tinham muitas dificuldades em lidar com números binários. Por esta razão, um novo 
sistema, com 16 símbolos diferentes foi criado. É chamado sistema de numeração 
hexadecimal, consistindo de dez dígitos que estamos acostumados a usar(0, 1, 2, 3, ... 9) 
e mais seis letras do alfabeto A, B, C, D, E e F. 
 O maior número que pode ser representado por 4 dígitos binários é o número 
1111. Ele corresponde ao número 15 no sistema decimal, enquanto que no sistema 
hexadecimal é representado por um único dígito, ‘F’. É o maior número de 1 dígito no 
sistema hexadecimal. O maior número escrito com oito dígitos binários é, ao mesmo 
tempo o maior número de 2 dígitos hexadecimais. Na figura 1.3 pode ser observado um 
exemplo da correlação existente entre números no sistema binário e no sistema 
hexadecimal. 
 
 
 
Figura 1.3 – Mesmo número sendo representado por 8 dígitos binários e 2 dois dígitos 
hexadecimais. 
 
 
Conversão entre Sistemas de Numeração 
 
 O sistema numérico binário é mais comumente usado, o sistema decimal é mais 
compreensível, enquanto o sistema hexadecimal é algo entre eles. Portanto, é muito 
importante aprender como converter números de um sistema numérico para outro, ou 
seja, como transformar uma sequência de zeros e uns em valores compreensíveis. 
 
Conversão binário-decimal 
 
 Dígitos em um número binário têm valores diferentes dependendo da posição 
que eles ocupam no número. Além disso, cada posição pode conter 1 ou 0 e seu valor 
pode ser facilmente determinado através da contagem de sua posição da direita para 
esquerda. Para fazer a conversão de um número binário para decimal é necessário 
multiplicar os valores dos dígitos correspondentes (0 ou 1) pelo seu respectivo peso na 
base binária e adicionar todos os resultados. Veja o exemplo abaixo: 
 
 
 Note-se que, para representar números decimais de 0 a 3, você precisará usar 
apenas dois dígitos binários. Para números maiores, dígitos binários extras devem ser 
usados. Assim, a fim de representar números decimais 0-7 você precisa de três dígitos 
Binário de 8 dígitos 
Mesmo número no sistema hexadecimal 
Número binário Mesmo número no sistema decimal 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 6
binários, conforme o exemplo acima. Para os números 0-15 você precisa de quatro 
dígitos, etc. 
 Com n dígitos binários é possível representar 2n valores decimais. Para saber 
qual o maior número decimal que pode ser representado com n dígitos binários, 
simplesmente calcule o valor de 2n-1. Assim, por exemplo, se n= 4: 
 
24-1 = 16-1 = 15 
 
 Assim, usando 4 dígitos binários, é possível representar números decimais de 0 a 
15, o que equivale a 16 diferentes valores no total. 
 
 
Conversão hexadecimal-decimal 
 
 A fim de fazer a conversão de um número hexadecimal em decimal, cada dígito 
hexadecimal deve ser multiplicado pelo número 16 elevado pelo seu valor de posição, 
semelhante ao que foi feito na base binária. Após isto, somam-se os valores obtidos 
individualmente. Por exemplo: 
 
 
Conversão hexadecimal-binário 
 
 Não é necessário realizar nenhum cálculo a fim de converter números de 
hexadecimal para binário. Os dígitos hexadecimais são simplesmente substituídos por 
dígitos binários adequados. Desde que o máximo valor representado por um dígito 
hexadecimal é equivalente ao número decimal 15, nós precisamos usar quatro dígitos 
binários para representar um dígito hexadecimal. Por exemplo: 
 
 Um quadro comparativo a seguir contém os valores dos números de 0-255 em 
três diferentes sistemas numéricos. Esta é provavelmente a maneira mais fácil de 
entender a lógica comum aplicado a todos os sistemas. 
 Observe que para representar os valores 0-255 nesses sistemas são necessários: 
 
* 3 dígitos decimais no sistema decimal; 
* 8 dígitos binários no sistema binário; 
* 2 dígitos hexadecimais no sistema hexadecimal. 
 
Número hexadecimal 
Mesmo número no sistema decimal 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 7
 O sistema numérico decimal, juntamente com os sistemas binário e hexadecimal, 
são considerados os sistemas numéricos mais importantes para nós. É fácil fazer a 
conversão de um número hexadecimal em binário e também é fácil de lembrar. No 
entanto, essas conversões podem causar confusão. Por exemplo, o que significa a frase 
“É preciso contar até 110 produtos na linha de montagem”. Dependendo se tratar de um 
valor binário, decimal ou hexadecimal, o resultado poderia ser 6, 110 ou 272 produtos, 
respectivamente! Assim, a fim de evitar mal-entendidos, diferentes prefixos e sufixos 
são adicionados diretamente aos números. O prefixo $ ou 0x, bem como o sufixo h 
marcam os números no sistema hexadecimal. Por exemplo, o número hexadecimal 
10AF pode ser escrito como $10AF, ou 0x10AF, ou ainda 10AFh. Da mesma forma, os 
números binários geralmente usam os prefixos % ou 0b. Se um número não tem nem o 
prefixo nem sufixo é considerado decimal. Infelizmente, esta maneira de marcar os 
números não é padronizada, assim, isto depende da concreta aplicação 
 
. 
 
Tabela comparativa mostrando os valores 0-255 escritos em três diferentes sistemas numéricos: 
decimal, binário e hexadecimal. 
 
Conceito de BIT 
 
 Um bit nada mais é que um dígito binário. Semelhante ao sistema de 
numeração decimal em que os dígitos de um número não têm o mesmo valor (por 
exemplo, os dígitos do número decimal 444 são os mesmos, mas têm valores 
diferentes), a significância de um bit depende de sua posição no número binário . Como 
não há sentido falar de unidades, dezenas etc, em números binários, seus dígitos são 
referidos como o bit zero (bit mais à direita), primeiro bit (o segundo da direita), 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 8
segundo bit, terceiro bit, etc. Além disso, uma vez que o sistema binário utiliza dois 
dígitos apenas (0 e 1), o valor de um bit pode ser 0 ou 1. 
 
 
Conceito de BYTE 
 
 Um byte é composto por oito bits agrupados. Se um bit é um dígito, é lógico 
dizer que bytes representam números. Todas as operações matemáticas podem ser 
realizadas sobre eles, os bytes, igualmente aos números decimais. Semelhante a dígitos 
de um número qualquer, os dígitos de um bytes não tem o mesmo significado. O bit 
mais à esquerda tem o maior valor, e é chamado o bit mais significativo (MSB – Most 
Significant Bit). O bit mais à direita tem o menor valor e por isso é chamado o bit 
menos significativo (LSB – Least Significant bit). Os 8 bits de um byte podem assumir 
valores 0 ou 1, independentemente. Assim, esses 8 bits podem ser combinados em 256 
formas diferentes, o maior número decimal que pode ser representado por um byte é 
255. 
 Um nibble é referido como metade de um byte. Dependendo de que metade do 
byte estivermos falando (esquerdo ou direito), dizemos que há 'alto' e 'baixo' nibble, 
respectivamente. 
 Os conceitos de bit, byte e nibble podem ser entendidos observando a figura 1.4. 
 
Figura 1.4 – Representação dos conceitos de bit, byte e nibble. 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 9
 
 
Conceitosde 
Eletrônica Digital 
 
 Alguma vez você já se perguntou o que há dentro de circuitos eletrônicos integrados 
digitais como microcontroladores e processadores? O que faz estes circuitos realizarem 
operações matemáticas complexas e tomar decisões? Sabia que essa aparente complexidade 
inclui apenas alguns elementos diferentes chamados circuitos lógicos ou portas lógicas? 
 
 
 
2.1 Álgebra de Boole 
 
 A operação dos circuitos lógicos é baseada em princípios estabelecidos por um 
matemático britânico, George Boole em meados do século XIX, antes mesmo da 
primeira lâmpada ter sido inventada. Originalmente, a idéia principal era expressar 
formas lógicas através de funções algébricas. Tal pensamento foi logo transformado em 
um produto prático, que hoje é conhecido como circuitos lógicos E (AND), OU (OR) e 
NÃO (NOT), ou inversor. O princípio de sua operação é conhecida como álgebra 
booleana. 
 Algumas instruções encontradas nos programas de microcontroladores dão o 
mesmo resultado que portas lógicas. Sua operação será discutida em seguida. 
 
Porta lógica E (AND) 
 
 A porta lógica “E” tem duas ou mais entradas e uma saída. Suponha que a porta 
usada neste exemplo tem apenas duas entradas. A lógica um (1) irá aparecer em sua 
saída apenas se as duas entradas (A e B) são acionadas com nível lógico alto (1). A 
tabela à seguir, chamada de tabela da verdade, mostra a dependência mútua entre as 
entradas e saída. 
 
Capítulo 2 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 10
 Quando usado em um programa, uma operação lógica E é realizada por uma 
instrução do programa, que será discutida posteriormente. Por ora, basta lembrar que a 
lógica E num programa refere-se à operação lógica AND aplicada aos bits 
correspondentes a dois registradores, que são posições de memória onde são 
armazanados valores binários, conforme se pode ver no quadro abaixo. 
 
 
 
 
 
Porta lógica OU (OR) 
 
 Da mesma forma, portas lógicas “OU” também tem duas ou mais entradas e uma 
saída. Se a porta tem apenas duas entradas, uma lógica um (1) irá aparecer em sua saída 
se uma entrada (A ou B) é acionada com nível lógico alto (1). Ou seja, uma lógica um 
(1) aparece em sua saída, se pelo menos uma entrada é mantida alta (1). Se todas as 
entradas estão à lógica zero (0), a saída também apresenta lógica zero (0). Em seguida, 
pode ser visto a tabela da verdade para a porta lógica OU assim como uma operação OU 
realizada com os valores de dois registradores. 
 
 
 
 
 
Porta lógica NÃO (NOT) 
 
 A porta lógica “NÃO” (not) tem apenas uma entrada e uma única saída. Ela 
opera de maneira extremamente simples. Quando a lógica zero (0) aparece em sua 
entrada, uma lógica de um (1) aparece em sua saída e vice-versa. Isso significa que esta 
porta inverte o sinal e é freqüentemente chamada de inversora. 
 No programa, essa operação lógica é feita sobre um byte, ou apenas um bit. O 
resultado é um byte com bits invertidos. Se o byte é considerado como um número, o 
valor invertido na verdade é um complemento do mesmo. O complemento de um 
número é um valor que adicionado ao número faz com que ele alcance o maior número 
de 8 dígitos binários. Em outras palavras, a soma de um número de 8 dígitos e seu 
complemento é sempre 255. 
 Em seguida, pode ser visto a tabela da verdade para a porta lógica NÃO assim 
como uma operação NÃO realizada com o valor de um registrador. 
 
 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 11
 
 
 
 
Porta lógica OU-EXCLUSIVO (XOR) 
 
 A porta “OU EXCLUSIVO” (XOR) é um pouco complicado em comparação 
com outras portas. Ela representa uma combinação de todos eles. A lógica um (1) 
aparece em sua saída somente quando suas entradas têm estados lógicos diferentes. 
 No programa, esta operação é comumente usada para comparar dois bytes. A 
subtração pode ser utilizada para o mesmo fim (se o resultado for 0, os bytes são 
iguais). Ao contrário de subtração, a vantagem desta operação lógica é que não é 
possível a obtenção de resultados negativos. 
 Em seguida, pode ser visto a tabela da verdade para a porta lógica OU 
EXCLUSIVO assim como uma operação realizada com os valores de dois registradores. 
 
 
 
 
 
 
Registradores 
 
 Em suma, um registrador, ou uma célula de memória, é um circuito eletrônico 
que pode memorizar o estado de um byte. Dentro de um microcontrolador há vários 
registradores que são usados para armazenar as informações do programa. Essas 
informações podem ser variáveis de controle do programa, estado das entradas ou 
saídas, resultado de uma operação matemática, etc. 
 Graficamente, podemos ver como funciona um registrador através da figura 2.1. 
Nessa figura, a unidade central de processamento (CPU) pode armazenar um byte numa 
posição de memória, ou registrador. Esse valor armazenado, pode em seguida ser 
utilizado pela própria CPU para um novo cálculo ou processamento. 
 
 
 
Figura 2.1 – CPU comunicando-se com um registrador. 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 12
 Além de registradores de uso geral como o mostrado na figura 2.1, que não tem 
nenhuma função específica e determinada, cada microcontrolador possui um número de 
registradores especiais (Special Function Registers-SFR), cuja função é pré-determinada 
pelo fabricante. Seus bits são conectados (literalmente) com os circuitos internos do 
microcontrolador, tais como temporizadores, conversores A/D, osciladores e outros, o 
que significa que eles são usados diretamente no comando da operação destes circuitos. 
O estado dos bits do registrador é alterado a partir do programa. O estado dos bits 
controla pequenos circuitos dentro do microcontrolador. 
 Imagine oito interruptores que controlam o funcionamento de um pequeno 
circuito dentro do microcontrolador: registradores especiais fazem exatamente isso, 
como pode ser observado na figura 2.2. 
 
 
 
Figura 2.2 – CPU comunicando-se com um registrador de função especial. 
 
 
Portas de Entrada/Saída 
 
 A fim de tornar o microcontrolador útil, este tem que ser ligado a uma eletrônica 
adicional, ou seja, aos periféricos. Cada microcontrolador tem um ou mais registradores 
(chamados portas) conectados aos pinos do microcontrolador. Por que entrada / saída? 
Porque você pode mudar a função do pino que desejar. Por exemplo, suponha que você 
deseja que o seu dispositivo ligue/desligue três LEDs de sinal e, simultaneamente, 
monitore o estado lógico de cinco sensores ou teclas. Algumas das portas precisam ser 
configuradas de modo que hajam três saídas (ligadas à LEDs) e cinco entradas (ligadas 
a sensores). Esta configuração é simplesmente realizada por software, ou seja, através 
do programa que o projetista escreve, o que significa que a função do pino pode ser 
alterada durante a operação. Podemos observar o funcionamento de uma porta de um 
microcontrolador através da figura 2.3. 
 
 
 
Figura 2.3 – CPU comunicando-se com uma porta de entrada/saída. 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 13
 Uma importante especificação dos pinos de entrada/saída (I/O) é a corrente 
máxima que estes podem suportar. Para a maioria dos microcontroladores atuais, a 
corrente obtida a partir de um pino é suficiente para ativar um LED ou algum outro 
dispositivo de baixa corrente (1-20 mA). Quanto mais pinos de I/O, menor corrente 
máxima de um pino. Em outras palavras, a corrente máxima indicada na folha de 
especificações de dados para o microcontrolador é compartilhada entre todas as portas 
de I/O. 
 Outra função importante de um pino de I/O é que estes podem ter resistências de 
pull-up. Essas resistências conectam os pinos à tensão positiva de alimentaçãoque pode 
ser diferente daquela que é usada para alimentar o chip do microcontrolador. Isto é útil 
quando se deseja trabalhar com tensões distintas no mesmo circuito 
 Cada porta de I/O está normalmente sob o controle de um registrador especial, o 
que significa que cada bit do registrador determina o estado do pino correspondente. Por 
exemplo, escrevendo uma lógica (1) para um bit do registrador de controle (SFR), o 
pino apropriado da porta é automaticamente configurado como entrada e a tensão 
presente nele pode ser lida como nível lógico 0 ou 1. Caso contrário, ao escrever zero a 
um bit desse SFR, o pino apropriado da porta é configurado como uma saída. 
 
 
Unidade de Memória 
 
 A memória é a parte do microcontrolador utilizado para armazenamento de 
dados. A maneira mais fácil de explicar é compará-la com um armário de arquivo com 
muitas gavetas. Suponha-se, as gavetas estão claramente identificadas para que seu 
conteúdo possa ser encontrada com facilidade através da leitura da etiqueta na parte 
frontal da gaveta. 
 Da mesma forma, cada endereço de memória corresponde a um local de 
memória. O conteúdo de qualquer lugar pode ser acessado e lido pelo seu 
endereçamento. Memória pode ser escrita ou lida. Na figura 2.4 temos um representação 
de uma memória que pode ser escrita ou lida. Do lado esquerdo, temos o endereço de 
cada posição de memória, do lado direito, temos os dados. Ao endereçar uma posição 
específica, a linha de dados apresenta o conteúdo presente naquela posição endereçada. 
Esse conteúdo pode ser lido para ser usado em algum processamento, ou ainda, esse 
conteúdo pode ser alterado mediante a escrita de um novo dado naquele endereço. 
 
 
 
Figura 2.4 – Memória de escrita/leitura de um microcontrolador. 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 14
 Existem vários tipos de memória dentro do microcontrolador, tais como: 
 
Memória apenas de leitura (Read Only Memory-ROM) - é usado para salvar 
permanentemente o programa sendo executado. O tamanho do programa que pode ser 
escrito depende do tamanho da memória. Microcontroladores atuais costumam usar 16 
bits de endereçamento, o que significa que eles são capazes de endereçar até 64 Kb de 
memória, ou seja, 65.535 localidades. Para iniciantes, o programa irá raramente exceder 
o limite de várias centenas de instruções. Existem vários tipos de ROM. 
 
Memória Flash - Este tipo de memória foi inventado nos anos 80 nos laboratórios da 
Intel e foi apresentada como o sucessor da EPROM UV (tipo de memória ROM que usa 
luz ultravioleta para ser apagada). Como o conteúdo dessa memória pode ser escrito e 
apagado praticamente um número ilimitado de vezes, microcontroladores com memória 
Flash ROM são ideais para a aprendizagem, experimentação e produção em pequena 
escala. Devido à sua grande popularidade, a maioria dos microcontroladores são 
fabricados com tecnologia flash. Então, se você estiver pensando em comprar um 
microcontrolador, o tipo é definitivamente o Flash! 
 
Memória de acesso aleatório (Random Access Memory-RAM) - Uma vez que a 
alimentação é desligada, o conteúdo da RAM é apagado. Ela é usada para armazenar 
dados temporários e resultados intermediários criados e utilizados durante a operação do 
microcontrolador. Por exemplo, se o programa realiza uma adição (de tudo), é 
necessário ter um registro que representa o que na vida cotidiana é a chamada "soma". 
Por esta razão, podemos ter um dos registros de memória RAM chamado de 'soma' e 
usado para armazenar os resultados da adição. 
 
Memória ROM eletricamente apagável e programável (Electrically Erasable 
Programable ROM-EEPROM) – Lê-se E 2 PROM. O conteúdo da EEPROM pode ser 
alterado durante a operação (semelhante à RAM), mas é permanente, mesmo após a 
perda de alimentação (similar a ROM). Assim, EEPROM é freqüentemente usado para 
armazenar valores, criados durante a operação, que deve ser permanentemente 
guardados. Por exemplo, se você criar uma fechadura eletrônica ou um alarme, seria 
ótimo que este permitisse ao usuário criar e digitar uma senha. Mas é inútil se essa 
senha for perdida cada vez que a alimentação se apaga. A solução ideal é um 
microcontrolador com uma EEPROM embutida. 
 
 
Interrupções 
 
 A maioria dos programas usam interrupções em sua execução normal. O 
objetivo do microcontrolador é principalmente responder às mudanças no seu entorno. 
Em outras palavras, quando um evento ocorre, o microcontrolador faz alguma coisa. Por 
exemplo, quando você aperta um botão em um controle remoto, o microcontrolador irá 
registrá-lo e responder pela alteração de um canal, aumentar o volume para cima ou 
para baixo, etc. Se o microcontrolador passasse a maior parte de seu tempo 
infinitamente verificando alguns botões por horas ou dias, isso não seria prático. 
 É por isso que o microcontrolador possui uma técnica de resposta a certos 
estímulos. Em vez de verificar cada pino ou bit constantemente, o microcontrolador 
delega essa função a circuitos específicos que só responderão quando algo específico 
acontece, por exemplo, o pressionamento de um botão. 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 15
 O sinal que informa a unidade de processamento central quando um evento 
como esse ocorre é chamado de uma interrupção. Quando a interrupção ocorre, o 
microcontrolador para de executar o programa e atende aquele evento em especial. 
 As interrupções são recursos extremamente poderosos e práticos para o 
desenvolvimento de sistemas microcontrolados. 
 
 
Unidade Central de Processamento (CPU) 
 
 Como o próprio nome sugere, esta é uma unidade que monitora e controla todos 
os processos dentro do microcontrolador. É constituída por várias subunidades, das 
quais as mais importantes são: 
 
• Decodificador de Instruções (Instruction Decoder) é uma parte da eletrônica 
embutida no microcontrolador que decodifica as instruções do programa e ativa 
outros circuitos com base nisso. O "conjunto de instruções" que é diferente para 
cada família de microcontroladores expressa a capacidade do circuito; 
• Unidade Lógica Aritmética (ULA) realiza todas as operações matemáticas e 
lógicas sobre os dados; 
• Acumulador é um registrador de uso especial intimamente relacionada com a 
operação da ULA. É uma espécie de mesa de trabalho usada para armazenar 
todos os dados em que uma operação deve ser realizada (transferência, 
adição/mover etc.) Ele também armazena os resultados prontos para uso no 
tratamento posterior. Um dos SFR, chamado de Registrador de Status (Status 
Register), está intimamente relacionado com o acumulador. Ele mostra, em 
determinado momento o 'status' de um número armazenado no acumulador (se 
número é maior ou menor que zero, etc.). O acumulador é também chamado de 
registrador de trabalho e está marcado como registrador W, ou apenas W. 
 
 Na figura 2.5 podem ser vistas as subunidades da CPU citadas. 
 
 
 
Figura 2.5 – Unidade Central de Processamento e suas subunidades. 
 
 Na figura 2.5, temos setas representando os fios que levam a informação de 
endereçamento de memória (Address), dos dados (Data) e das linhas de controle 
(Control Line). Cada seta, dependendo do tipo de microcontrolador, pode conter 8, 16 
fios ou até mais. Cada conjunto de fios que carregam uma informação do mesmo tipo é 
chamado de Barramento. Assim, temos os barramentos de endereço, de dados e de 
controle. 
 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 16
Oscilador 
 
 Para que o microcontrolador execute as instruções armazenadas em sua 
memória, é necessário a presença de um sinal pulsante, normalmente uma onda 
quadrada, para que as instruções sejam executadas a cada pulso. Esse sinal é chamado 
de sinal de relógio (clock), e é provenientede um circuito oscilador. O circuito oscilador 
é normalmente configurado de modo a utilizar um cristal de quartzo ou ressonador 
cerâmico, conectado a dois pinos do microcontrolador, para a estabilidade de 
freqüência, mas também pode operar como um circuito stand-alone (como um oscilador 
RC interno). É importante dizer que as instruções não são executadas ao ritmo imposto 
pelo oscilador em si, mas várias vezes mais lento. Isso acontece porque cada instrução é 
executada em várias etapas. Em alguns microcontroladores, o mesmo número de ciclos 
é necessário para executar todas as instruções, enquanto em outros, o número de ciclos é 
diferente para diferentes instruções. Assim, se o sistema usa um cristal de quartzo com 
uma frequência de 20 Mhz, o tempo de execução de uma instrução não é 50ns, mas 200, 
400 ou 800 ns, dependendo do tipo de microcontrolador! 
 
 
Circuito de alimentação 
 
 Há duas coisas que merecem atenção sobre o circuito de alimentação do 
microcontrolador: 
 
• Brown out é uma condição potencialmente perigosa que ocorre no momento em 
que o microcontrolador é desligado ou quando a tensão cai para um valor 
mínimo devido a ruído elétrico. Como o microcontrolador é composto por vários 
circuitos, com diferentes níveis de tensão de funcionamento, este estado pode 
provocar um funcionamento fora de controle. Para evitar isso, normalmente o 
microcontrolador possui um circuito de reset que reinicia todos os circuitos 
assim que o microcontrolador incorre em um estado de emergência. 
• Pino de reset é normalmente marcado como MCLR (Master Clear Reset). É 
utilizado para reiniciar o microcontrolador através da aplicação de uma lógica de 
zero (0) ou um (1) nesse pino, o que depende do tipo do microcontrolador. 
 
 
Temporizadores/Contadores 
 
 O oscilador do microcontrolador utiliza cristal de quartzo para o seu 
funcionamento. Mesmo não sendo a solução mais simples para a obtenção de um sinal 
de relógio, existem muitas razões para usá-lo. A freqüência do oscilador é precisamente 
definida e muito estável, de modo que gera pulsos sempre da mesma largura, o que os 
torna ideais para a medição do tempo. Tais osciladores também são usados em relógios 
de quartzo. Se é necessário medir o tempo entre dois eventos, basta contar os pulsos 
gerados por este oscilador. Isto é exatamente o que o temporizador, ou timer, faz. 
 A maioria dos programas usam este cronômetro eletrônico em miniatura. Estes 
são geralmente registradores de funções especiais de 8 ou 16-bits, cujo conteúdo é 
automaticamente incrementado por cada impulso vindo do circuito oscilador. Uma vez 
que um registrador é completamente carregado, uma interrupção pode ser gerada. 
 Se o timer usa um oscilador de quartzo para o seu funcionamento interno, então 
ele pode ser usado para medir o tempo entre dois eventos (se o valor do registrador é T1 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 17
no momento em que se inicia a medição, e T2, no momento em que termina, então o 
tempo decorrido é igual a o resultado da subtração T2-T1). Se os registradores usam 
pulsos provenientes de fontes externas conectados a um pino do microcontrolador, 
então o timer é transformado em um contador. Esta é apenas uma explicação simples da 
operação em si. No entanto, é um pouco mais complicado na prática. 
 
 
Conversor Analógico/Digital (A/D) 
 
 Sinais externos normalmente são fundamentalmente diferentes daqueles que o 
microcontrolador entende (zeros e uns) e têm de ser convertidos em valores 
compreensíveis para o microcontrolador. Um conversor analógico/digital é um circuito 
eletrônico que converte os sinais contínuos para discretos números digitais. Em outras 
palavras, este circuito converte um valor analógico em um número binário e o transfere 
para a CPU para processamento adicional. Este módulo é utilizado para a medição de 
tensão analógica em um pino de entrada (valor analógico). 
 Na figura 2.6, por exemplo, temos uma representação do conversor A/D sendo 
controlado pela CPU. O gráfico ao lado mostra a relação de conversão de sinais 
analógicos de 0V até 5V em números binários que vão de 0x000 a 0x3FF. 
 
 
 
Figura 2.6 – Operação de um conversor analógico/digital. 
 
 
Arquitetura Interna 
 
 Todos os microcontroladores usam um dos dois modelos de projeto básicos 
chamados arquitetura Harvard e arquitetura von-Neumann. 
 Eles representam duas formas diferentes de troca de dados entre a CPU e a 
memória. 
 Os microcontroladores com a arquitetura von-Neumann tem apenas um bloco de 
memória e um barramento de 8 bits de dados. Como todos os dados são trocados através 
dessas 8 linhas, o barramentos fica sobrecarregado e a comunicação é muito lenta e 
ineficiente. A CPU pode apenas executar uma instrução de leitura ou gravação de dados 
para a memória. Ambas não podem ocorrer ao mesmo tempo, uma vez que instruções e 
dados usam o mesmo barramento. 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 18
 
Figura 2.7 – arquitetura Von-Neumann. 
 
 Os microcontroladores com arquitetura Harvard tem dois barramentos 
diferentes. Um deles conecta a CPU com a memória RAM. O outro consiste em linhas 
de 12, 14 ou 16 bits e conecta a CPU com a memória ROM. Assim, a CPU pode ler 
uma instrução e ter acesso a dados da memória, ao mesmo tempo. Como todos os 
registradores da memória RAM são de 8 bits, todos os dados sendo trocados são da 
mesma largura. Durante o processo de escrita, um programa apenas manipula os dados 
de 8 bits. Em outras palavras, tudo o que você pode mudar a partir do programa e tudo o 
que pode influenciar é de 8 bits. Todos os programas escritos para estes 
microcontroladores serão armazenado na ROM do microcontrolador interno depois de 
serem compilados em código de máquina. No entanto, posições de memória ROM não 
tem 8, mas 12, 14 ou 16 bits. O resto dos bits 4, 6 ou 8 representa a instrução 
especificando para a CPU o que fazer com os dados de 8 bits. 
 
 
 
Figura 2.8 – arquitetura Harvard. 
 
 
O Conjunto de Instruções 
 
 Todas as instruções compreensíveis para o microcontrolador são chamadas de o 
conjunto (Set) de instruções. Quando você escreve um programa em linguagem 
assembly, na verdade você especifica instruções na ordem em que devem ser 
executadas. A principal restrição aqui é o número de instruções disponíveis. Os 
fabricantes costumam considerar uma das duas abordagens abaixo: 
 
Conjunto reduzido de instruções (RISC-Reduced Instruction Set Computer) 
Neste caso, o microcontrolador reconhece e executa apenas as operações básicas 
(adição, subtração, cópia, etc.) Outras operações mais complicadas são realizadas 
através da combinação delas. Por exemplo, a multiplicação é feita através da realização 
de sucessivas adições. Os microcontroladores da linha PIC são do tipo RISC. 
 
Conjunto complexo de instruções (CISC-Complex Instruction Set Computer) 
CISC é o oposto ao RISC. Microcontroladores concebidos para reconhecer mais de 200 
instruções diferentes, podendo realizar inúmeras tarefas em alta velocidade. No entanto, 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 19
é preciso entender como aproveitar tudo o que estas instruções oferecem, o que não é 
nada fácil. Processadores, como Pentium, Core 2 Duo são do tipo CISC. 
 
 
Modelo genérico de um microcontrolador 
 
 Todos os elementos de hardware vistos até agora, e tantos outros não 
apresentados aqui, fazem parte da eletrônica embutida em um microcontrolador. Esses 
elementos estão todos interligados para desempenhar diferentes tarefas, dependendo das 
necessidades do projetista. A figura 2.9 mostra como esses elementos estão interligados 
para potencializar o uso de um microcontrolador 
 
 
 
Figura 2.9 – Elementosde um microcontrolador. 
 
 
Como fazer a escolha certa? 
 
 Ok, você é novato e tomou a decisão de se aventurar em trabalhar com os 
microcontroladores. Parabéns pela sua escolha! No entanto, não é tão fácil escolher o 
correto microcontrolador, como pode parecer. O problema não é um número limitado de 
dispositivos, mas o oposto! 
 Antes de começar a projetar um dispositivo baseado no microcontrolador, pense 
o seguinte: quantas linhas de entrada/saída eu preciso para a operação? Deve realizar 
algumas operações além de simplesmente acionar relés? Será que preciso de algum 
módulo especializado, tal como comunicação serial, etc. Um conversor A/D? Quando 
você cria uma imagem clara do que você precisa, o intervalo de selecção é bastante 
reduzido e é hora de pensar em preços. 
 Se você pensar em todas essas coisas pela primeira vez, então, tudo parece um 
pouco confuso. Primeiro, selecione o fabricante, ou seja, a família do microcontrolador. 
Estude um modelo específico. Saiba quanto você precisa, não entre em detalhes. 
Resolva um problema específico por vez. Em seguida, você vai perceber que 
aprendendo um modelo daquela família, você estará apto a trabalhar com qualquer outro 
modelo. 
 Os microcontroladores PIC, desenvolvidos pela Microchip Technology 
provavelmente são a melhor escolha para iniciantes. 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 20
 
 
O Microcontrolador 
PIC 16F877 
 
 O PIC16F877 é um produto bem conhecido da Microchip. Ele possui todos os 
componentes que os microcontroladores modernos normalmente têm. Por seu baixo preço, 
ampla gama de aplicações de alta qualidade e fácil acesso, é uma solução ideal em aplicações 
como o controle de diferentes processos na indústria, dispositivos de controle de máquinas, a 
medição de valores de tensão, etc. Algumas de suas principais características estão listadas 
abaixo. 
 
 
3.1 Introdução 
 
 O PIC16F877 é um microcontrolador que teve suas origens no ano de 1965, 
quando a companhia GI (General Instruments), formou a Divisão de Microeletrônica. 
Na década de 70, a GI criou um dos primeiros processadores de 16 bits, chamado 
CP16000. Como este microprocessador tinha uma certa deficiência no processamento 
de entradas/saídas, a GI projetou e construiu um Controlador de Interface Periférica (em 
inglês, Peripheral Interface Controller, ou PIC). Este controlador foi projetado tendo 
em vista a rapidez, pois devia processar as operações de E/S de uma máquina de 16 bits, 
e tinha um conjunto de instruções muito pequeno. O CP16000 não teve muito sucesso, 
porém o PIC evoluiu para a arquitetura PIC16C5x. Como era disponível somente nas 
versões em ROM, permaneceu como uma boa solução para grandes usuários, que 
podiam encomendar diretamente da fábrica um grande volume de circuitos já pré-
programados. 
 Na década de 80, a divisão de microeletrônica da GI foi reestruturada e se 
transformou na GI Microeletrônica, uma empresa subsidiária. Esta empresa foi vendida 
para investidores e transformada na Arizona Microchip Technology, dedicada 
especificamente ao desenvolvimento de produtos utilizados em sistemas dedicados. 
 Como parte desta estratégia, grande esforço da companhia foi direcionado ao 
desenvolvimento de várias versões do PIC, sendo que a versão com EEPROM (eprom 
apagável eletricamente) é a mais indicada para o desenvolvimento rápido de aplicações, 
devido ao baixo custo do sistema de desenvolvimento necessário e do hardware de 
processamento. 
 O dispositivo mais flexível disponível hoje da série PIC de 14 bits de palavra de 
controle, e que ao mesmo tempo reúne um conjunto de características adequadas ao uso 
em pequenas séries de produtos e estudo de microcontroladores é o PIC16F877A. Na 
Capítulo 3 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 21
figura 3.1 pode-se ver o encapsulamento DIP de 40 pinos, um dos encapsulamentos 
disponíveis para esse microcontrolador. 
 Como o microcontrolador PIC16F877A se utiliza da arquitetura Harvard, isto 
possibilita que as palavras de instruções tenham um número de bits (14 bits de 
comprimento) diferente do tamanho da palavra de dados (8 bits para este 
microcontrolador). Com este tamanho de palavra de instrução é possível codificar todas 
as instruções, com exceção dos desvios para outras posições de programas, como 
instruções de uma única palavra, resultando em uma grande velocidade de execução, 
como 200ns para a versão de 20Mhz. 
 
Figura 3.1 – Microcontrolador PIC 16F877A com encapsulamento DIP de 40 pinos. 
 
 Estes dispositivos podem endereçar direta e indiretamente seus arquivos de 
registros ou memória de dados. O conjunto de instruções foi projetado de tal forma que 
se pode realizar qualquer operação em qualquer registro utilizando qualquer modo de 
endereçamento. 
 A unidade lógica aritmética do PIC16F877 pode realizar operações de adição, 
subtração, deslocamento e operações lógicas. 
 Os microcontroladores da série PIC16F877 são dispositivos computacionais 
extremamente adequados para experimentação e pequenos projetos. Devido ao seu 
baixo custo e facilidade de programação, podem ser empregados em aplicações onde até 
recentemente se utilizavam componentes discretos, como por exemplo, os 
temporizadores e controladores de temperatura, adicionando novas funções até então 
não implementadas devido a complexidade do circuito necessário. 
 O projeto com microcontroladores traz uma diferença fundamental de paradigma 
para o projetista de circuitos. Ao invés de um bem sortido estoque de componentes 
discretos que realizam várias funções diferentes cada um, e de um conceito de projeto 
que consiste em interligar estas diferentes funções de forma que o sistema como um 
todo tenha o comportamento adequado, utilizamos agora praticamente um mesmo tipo 
de hardware para todas as aplicações. A diferença de funcionalidade fica por conta do 
software. Alterações de funcionalidade podem ser feitas, em grande parte das vezes, 
através da modificação apenas do software, sem ser necessária alteração do hardware. 
 Os microcontroladores da série PIC16F87X são máquinas RISC. Isto significa 
que são máquinas com um reduzido conjunto de instruções. Para ser exato, são apenas 
35 instruções para serem compreendidas, cada uma ocupando uma palavra (14 bits ). 
 O PIC16F877 possui as seguintes características básicas: 
• 5 conjuntos de portas de entrada e saída (total de 33 entradas/saídas); 
• Conversor analógico/digital de 10 bits de resolução e 8 canais de entrada; 
• Periférico de comunicação paralela e serial (USART e MSSP); 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 22
• 2 Módulos CCP (Comparação, Captura e PWM); 
• 3 Timers (1 de 16 bits e 2 de 8 bits); 
• Watchdog timer (temporizador especial). 
 Na figura 3.2 temos uma representação da arquitetura interna do PIC16F877, ou 
seja, uma representação da forma como os recursos estão ligados internamente no chip. 
 
 
 
Figura 3.2 – Arquitetura interna do PIC microcontrolador PIC 16F877. 
 
 Na figura 3.3 temos a descrição dos pinos no encapsulamento. Observe que 
alguns pinos apresentam mais de uma função. Isso significa que o projetista deve 
escolher qual a função que o pino vai assumir quando estiver fazendo a sua 
programação. A descrição de cada pino do microcontrolador é mostrada na tabela que 
segue: 
 
 
Figura 3.3 – Pinagem do microcontrolador PIC 16F877. 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 23
 
 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 24
 A fim de que o microcontrolador funcione adequadamente é necessário fornecer: 
 
• Alimentação elétrica; 
• Sinal de reset, e 
• Sinal de clock. 
 
 Mesmo que o PIC16F877possa operar em tensões de alimentação diferentes, 
uma fonte de alimentação DC de 5V é a mais adequada. O circuito mostrado na figura 
3.4 utiliza um circuito integrado de três terminais LM7805, um regulador positivo que 
oferece alta qualidade de estabilidade de tensão e corrente suficiente para permitir que o 
microcontrolador e periféricos eletrônicos funcionem normalmente (o suficiente, aqui, 
significa 1A). 
 Para que o microcontrolador possa operar corretamente, uma lógica (VCC) deve 
ser aplicado sobre o pino de reset (pino 1). O botão conectando o pino MCLR ao GND 
não é necessário. No entanto, é quase sempre fornecido, pois permite que o 
microcontrolador seja resetado manualmente, fazendo com que este retorne às 
condições normais de funcionamento, caso algo dê errado. Ao pressionar este botão, o 
pino é levado a 0V, o microcontrolador é reiniciado e começa a execução do programa 
desde o início. Um resistor de 10K é usado para permitir que o pino MCLR vá a 0V, 
através do botão, sem curto-circuitar com o nível de 5V DC. Esse resistor é chamado de 
resistor de “pull-up”, pois é conectado entre o VCC e o pino. 
 Mesmo que o microcontrolador possua um oscilador interno, ele não pode 
operar sem componentes externos que estabilizam o seu funcionamento e determinem 
sua freqüência (velocidade de operação do microcontrolador). Dependendo do elemento 
em uso para estabilizar a frequência, bem como suas freqüências, o oscilador pode 
operar em quatro modos diferentes: 
 
LP - Cristal de Baixa Potência; 
XT - Cristal/Ressonador; 
HS - Cristal de Alta Velocidade e 
RC - Resistor/Capacitor. 
 
 Quando o cristal de quartzo é utilizado para a estabilização da freqüência, o 
oscilador funciona com uma frequência precisa, que não é afetado por mudanças na 
temperatura e tensão de alimentação. Esta frequência é geralmente indicada na 
embalagem do crysal. Além do cristal, os capacitores C1 e C2 também devem ser 
conectados conforme esquema abaixo. Os valores previstos para C1 e C2 na tabela a 
seguir devem ser considerados como uma recomendação e não como uma regra rígida. 
 
 
 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 25
 
 
Figura 3.4 – Circuito de alimentação, reset e oscilador para o PIC 16F877. 
 
 Como visto na figura acima, trata-se de um circuito simples, mas nem sempre é 
assim. Se o dispositivo de destino é utilizado para controlar grandes máquinas ou 
dispositivos de suporte a vida, tudo fica cada vez mais complicado. No entanto, esta 
solução é suficiente por enquanto. 
 Independentemente do fato de que o microcontrolador é um produto de 
tecnologia moderna, este é inútil se não estiver ligado a alguns componentes adicionais. 
Simplificando, o aparecimento de tensões nos pinos do microcontrolador não significa 
nada se não for utilizado para a realização de determinadas operações, tais como ligar 
ou desligar LEDS, relés, ler botões ou chaves, exibir dados em um display de 7 
segmentos ou display de LCD etc. 
 Nos capítulos que se seguem, serão abordadas as técnicas de programação em 
linguagem C, bem como a utilização do micocontrolador para realizar tarefas que vão 
desde acender/apagar um LED, até tarefas mais complexas como escrita em um LCD ou 
mesmo a comunicação entre dois microcontroladores. 
 No final desta apostila, encontra-se o datasheet resumido do PIC16F877, 
contendo as principais informações necessárias para o desenvolvimento de aplicações 
utilizando esse microcontrolador. 
 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 26
 
 
Introdução à 
Linguagem C 
 
 Assim como o uso de uma linguagem não está limitada apenas a livros e revistas, as 
Linguagens de Programação não estão estritamente relacionadas com algum tipo especial de 
computador, processador ou Sistema Operacional. C é atualmente uma linguagem de 
programação de alto nível e de uso geral. Entretanto, o fato da não associatividade da 
linguagem C a nenhuma máquina pode causar problemas durante a sua utilização, 
dependendo das peculiaridades de cada máquina em que está se programando (isto poderia 
ser comparado ao uso de diferentes dialetos de uma linguagem). 
 
 
4.1 Introdução 
 
 A idéia associada a escrever um programa na linguagem C é quebrar um grande 
problema em vários problemas menores, mais simples de serem resolvidos. Suponha, 
por exemplo, que é necessário escrever um programa para o microcontrolador para 
realizar a medição de temperatura e mostrar o resultado em um display de cristal 
líquido. O processo de medir é feito com o uso de um sensor apropriado, que converte a 
temperatura em uma tensão proporcional. O microcontrolador usa seu conversor A/D 
para converter essa tensão (analógica) em um número (digital) que é então enviado para 
o LCD através de vários fios. Assim, o programa é dividido em quatro partes que 
precisam ser executadas na ordem correta, como seguem: 
 
 
 
 
1. Ativar e ajustar o conversor A/D; 
2. Realizar a medição do valor analógico; 
3. Calcular a temperatura; 
4. Enviar os dados de forma apropriada para o display. 
 
 
 
 
 
 
Capítulo 4 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 27
 Para facilitar a compreensão da linguagem C, vejamos primeiramente um 
exemplo de programa: 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Vejamos o significado de cada linha do programa. 
 A primeira linha do programa: 
 
// Primeiro exemplo 
 
é chamada de comentário. Os comentários não são interpretados pelo compilador, mas 
são apenas descrições inseridas no código-fonte pelo programador com o intuito de 
documentar o programa e para facilitar o seu entendimento por parte de outros 
programadores que eventualmente farão alterações ou atualizações no programa 
original. 
 Os comentários podem ser de linha simples, como foi mostrado no exemplo 
anterior, e são iniciados por uma barra dupla. Os comentários de linha simples podem 
ser iniciados em qualquer ponto de uma linha e são muito utilizados para descrever o 
funcionamento ao final de cada linha de código. 
 Os comentários também podem ser de múltiplas linhas. Nesse caso, são 
compostos por uma ou mais linhas. Iniciam sempre com os caracteres “/*” para iniciar o 
comentário, e a sequência “*/” para terminar o comentário, como mostra o exemplo 
abaixo: 
 
/* 
Este é um exemplo 
de comentário de 
múltiplas linhas 
*/ 
 
Na próxima linha temos: 
 
#include <16F877A.h> 
 
 O comando #include é uma diretiva do compilador. Neste caso, está 
determinando ao compilador que anexe ao programa o arquivo especificado: 
“16F877A.h”, que é um arquivo que contém todas as informações sobre o 
microcontrolador utilizado, no caso, o PIC 16F877A. Arquivos com extensão do tipo 
“.h” são chamados de arquivos de cabeçalho e são utilizados em C para definir 
variáveis, tipos, símbolos e funções úteis ao programa. 
// Primeiro exemplo 
 
#include <16F877A.h> 
#fuses HS 
#use delay(clock=20M) 
 
main() 
{ 
 output_high(pin_b0); //seta o pino rb0 
 delay_ms(500); //aguarda 500ms 
 output_low(pin_b0); //reseta o pino rb0 
 
} 
 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 28
 Na próxima linha encontramos: 
 
#fuses HS 
 
 Esta é uma diretiva que especifica o estado dos “fusíveis” da palavra de 
configuração do dispositivo. No caso, estamos indicando ao processador que opere com 
a opção HS ou High Speed, isto é, com um cristal de alta velocidade. Existem várias 
outras opções para configurar os fuses, como por exemplo, proteger o código gravado 
no microcontrolador contra leitura, modos de programação, proteção para evitar 
travamentos no caso de uma queda de tensão, etc. 
 Em seguida temos: 
 
#usedelay(clock=20M) 
 
 Esta é outra diretiva do compilador. Esta diretiva especifica o clock, ou a 
velocidade do cristal usado para sincronizar as operações dentro do dispositivo. No 
caso, estamos indicando ao compilador que o dispositivo opera com um cristal de 
20MHz. Este valor é utilizado para a geração de códigos de atraso e outras rotinas que 
dependam do tempo. 
 Na próxima linha do programa encontramos: 
 
main() 
 
 A declaração main( ) especifica o nome de uma função. No caso, a função 
main( ) é padronizada na linguagem C e é utilizada para definir a função principal, ou o 
corpo principal do programa. 
 Uma função em C é um conjunto de instruções que pode ser executado a partir 
de qualquer ponto do programa. O sinal de abertura da chave “{“ é utilizado para 
delimitar o início da função e o sinal de fechamento da chave ”}” indica o final da 
função. Na realidade, as chaves delimitam o que chamamos de bloco de programa ou 
bloco de código. 
 O bloco de programa dentro da função main( ) é formado por 3 instruções. Cada 
instrução é terminada por um ponto e vírgula (;). 
 A instrução output_high(pin_b0) é uma chamada a uma função interna do 
compilador. Esta função é utilizada para setar (ou seja, colocar em nível lógico ‘1’) um 
pino do microcontrolador, identificado entre os parênteses. Isto significa que o pino rb0 
(da porta B) será setado. Note que (pin_b0) é um símbolo predefinido para especificar o 
pino rb0. Este símbolo está localizado no arquivo de cabeçalho do processador 
utilizado, e que foi adicionado com a diretiva #include. O conteúdo presente entre os 
parênteses de uma função é chamado de argumento da função. Assim, pin_b0 é o 
argumento da função output_high( ). 
 A próxima função a ser executada é: 
 
delay_ms(500); 
 
 Esta também é uma função interna do compilador e é utilizada para gerar um 
atraso de X milissegundos, indicado entre os parênteses. No caso, o atraso será igual a 
500ms. 
 A instrução output_low(pin_b0) é uma chamada a uma outra função interna 
do compilador. Esta função é utilizada para resetar (ou seja, colocar em nível lógico ‘0’) 
um pino do microcontrolador, identificado entre os parênteses. Isto significa que o pino 
rb0 (da porta B) será resetado. 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 29
 Desta forma, ao programarmos o PIC com o programa anterior e se tivermos 
conectado um LED (com o devido resistor de limitação de corrente) ao pino rb0, nós o 
veremos acender, permanecer aceso por 500ms, apagar e depois permanecer apagado. 
 Obviamente este é um programa bem simples, mas que é útil para o 
entendimento inicial da estrutura de um programa escrito em linguagem C. 
 Podemos dizer que um programa em C é constituído por um ou mais dos 
seguintes elementos: 
 
*Operadores são elementos utilizados para comandar interações entre variáveis e dados 
em C; 
 
*Variáveis que são usadas para armazenamento temporário ou permanente de dados. A 
linguagem C dispõe de uma variedade de tipos de variáveis e dados; 
 
*Comandos de controle são elementos essenciais à escrita de programas em C. São 
utilizados para controlar, testar e manipular dados e informações dentro de programas 
em C; 
 
*Funções são estruturas de programa utilizadas para simplificar, otimizar ou apenas 
tornar mais claro o funcionamento do programa. 
 
 Vejamos outro exemplo de programa em C: 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 As quatro primeiras linhas do programa acima constituem o que podemos 
chamar de cabeçalho do programa, onde temos alguns comentários acerca do programa 
e também as diretivas de controle do compilador. Observe que as diretivas não 
necessitam (e nem permitem) o uso do ponto e vírgula como delimitador. 
 O primeiro comando, int tempo, é chamado de declaração de variável. Este 
comando determina que o compilador crie uma variável do tipo inteira int chamada 
tempo. Esta operação, na realidade irá reservar uma posição de memória no 
microcontrolador para o armazenamento do valor relativo à variável. O tipo inteiro int 
especifica um tipo de dados de 8 bits com valores compreendidos entre 0 e 255 decimal. 
Veremos mais sobre variáveis e tipos de dados em seguida. 
// Segundo exemplo 
 
#include <16F877A.h> 
#fuses HS 
#use delay(clock=20M) 
 
main() 
{ 
 int tempo; 
 tempo=100; 
 output_high(pin_b0); //seta o pino rb0 
 delay_ms(tempo); //aguarda 100ms 
 output_low(pin_b0); //reseta o pino rb0 
 delay_ms(tempo); 
 
} 
 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 30
 O nome dado à variável é um identificador e pode ser composto de letras, 
números e o caractere sublinhado “_”. Veremos mais sobre identificadores válidos na 
linguagem C. 
 Em seguida, temos a linha tempo=100 que constitui em uma operação de 
atribuição. As atribuições em C são executadas pelo operador de igualdade “=”. Desta 
forma, a linha tempo=100 fará com que o compilador gere uma sequência de instruções 
para fazer com que o valor 100 decimal seja armazenado na variável tempo. 
 As linhas com output_high( ) e output_low( ) são funções internas ao 
compilador e são utilizadas para setar e resetar, respectivamente, algum pino do 
microcontrolador, nesse caso, o pino b0 (da porta B). 
 As outras duas linhas restantes são as linhas com a instrução delay_ms(tempo). 
Esta também é uma função interna do compilador e é utilizada para gerar um atraso de 
X milissegundos. O valor X é o parâmetro dessa função, no caso, X é igual ao conteúdo 
da variável tempo, que foi previamente carregada com o valor 100. Logo, o atraso 
gerado será de 100ms. 
 Maiores detalhes sobre o funcionamento das funções internas do compilador 
podem ser vistas no manual do usuário do compilador PIC C (CCS). 
 
 
4.2 Palavras reservadas na Linguagem C 
 
 Toda linguagem de programação possui um conjunto de palavras ou comandos 
para os quais já existe interpretação interna prévia. Tais palavras não podem ser 
utilizadas para outras finalidades que não as definidas pela linguagem. 
 A linguagem C ANSI estipula as seguintes palavras reservadas: 
 
auto break case char const 
continue default do double else 
enum extern float for goto 
if int long register static 
return short signed sizeof 
struct switch typedef union 
void volatile while unsigned 
 
 
4.3 Identificadores 
 
 Identificadores são nomes dados pelo programador a variáveis, funções e outros 
elementos da linguagem C. Não é permitido utilizar palavras reservadas como 
identificadores. 
 Um identificador pode ser composto de caracteres numéricos e alfanuméricos, 
além do caractere sublinhado “_”. Além disso, um identificador somente pode ser 
iniciado por uma letra ou sublinhado, nunca por um número, como nos exemplos: 
 
variável 
variavel1 
_teste 
_teste1 
_13_abc 
abc_def 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 31
4.4 Variáveis e tipos de dados 
 
 Variáveis e constantes são os elementos básicos que um programa manipula. 
Uma variável é um espaço reservado na memória do microcontrolador para armazenar 
um tipo de dado determinado. Variáveis devem receber nomes para poderem ser 
referenciadas e modificadas quando necessário. Muitas linguagens de programação 
exigem que os programas contenham declarações que especifiquem de que tipo são as 
variáveis que ele utilizará e às vezes um valor inicial. Tipos podem ser, por exemplo: 
inteiros, reais, caracteres, etc. As expressões combinam variáveis e constantes para 
calcular novos valores. 
 Os dados podem assumir cinco tipos básicos em C que são: 
 
Tipo Tamanho em bits Intervalo 
char 8 0 a 255 
int 8 0 a 255 
float 32 3.4*10-38 a 3.4*1038 
void 0 Nenhum valor 
 
char: (Caractere) O valor armazenado é umcaractere (letras dígitos e símbolos 
especiais). Caracteres geralmente são armazenados em códigos (usualmente o 
código ASCII). 
int: Número inteiro é o tipo padrão e o seu tamanho normalmente depende da máquina 
em que o programa está rodando. No caso do PIC16F877, seu tamanho é de 8 bits. 
float: Número em ponto flutuante de precisão simples. São conhecidos normalmente 
como números reais. 
void: Este tipo serve para indicar que um resultado não tem um tipo definido. Uma das 
aplicações deste tipo em C é criar um tipo vazio que pode posteriormente ser 
modificado para um dos tipos anteriores. 
 
 O intervalo especifica qual a faixa de valores que podem ser representados por 
uma variável daquele tipo. 
 Modificadores podem ser aplicados a estes tipos. Estes modificadores são 
palavras que alteram o tamanho do intervalo de valores que o tipo pode representar. Por 
exemplo, um modificador permite que possam ser armazenados números inteiros 
maiores. Outro modificador obriga que só números sem sinal possam ser armazenados 
pela variável. Deste modo não é necessário guardar o bit de sinal do número e somente 
números positivos são armazenados. O resultado prático é que o conjunto praticamente 
dobra de tamanho. A Tabela abaixo mostra todos os tipos básicos definidos no 
compilador CCS 
 
Tipo Tamanho em bits Intervalo 
short int, int1, boolean 1 0 ou 1 
char 8 0 a 255 
signed char 8 -128 a 127 
unsigned char 8 0 a 255 
int, int8, byte 8 0 a 255 
signed int, signed byte 8 -128 a 127 
unsigned int, unsigned 8 0 a 255 
long int, int16 16 0 a 65535 
signed long int 16 -32768 a 32767 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 32
unsigned long int 16 0 a 65535 
int32 32 0 a 4294967295 
signed int32 32 -2147483648 a 
unsigned int32 32 0 a 4294967295 
float 32 3.4*10-38 a 3.4*1038 
 
 
4.4 Declaração de variáveis 
 
 Para serem usadas, as variáveis precisam ser declaradas de modo que o 
compilador possa reservar espaço na memória para o valor a ser armazenado. Declarar 
uma variável nada mais é do que informar ao compilador o nome dessa variável, através 
de um identificador e o seu tipo, conforme a tabela anterior. 
 A forma geral de uma declaração é: 
 
 tipo lista_de_variaveis ; 
 
 Exemplos: 
 
 int i; 
 unsigned int a, b, c; 
 unsigned long int dia, mes, ano; 
 float salario; 
 
 Outro aspecto importante da declaração de variáveis é o local onde elas são 
declaradas. A importância do local onde a variável é declarada relaciona-se à 
acessibilidade ou não dessa variável por outras partes do programa. Basicamente, 
podemos declarar as variáveis em dois pontos distintos do programa, a saber: 
 
• No corpo principal do programa, (fora de qualquer função, inclusive da função 
main() . Variáveis declaradas dessa forma são chamadas de variáveis globais, 
porque podem ser acessadas de qualquer ponto do programa; 
 
• Dentro de uma função. As variáveis declaradas dentro de um função somente 
podem ser acessadas de dentro da função em que foram declaradas. Variáveis 
declaradas dessa forma são chamadas de variáveis locais. Isto significa que uma 
variável local somente existe enquanto a função está sendo executada. 
 
Em seguida, temos um exemplo de um programa com variáveis locais e globais. 
 
 
 
 
 
 
 
 
 
 
 
 
// terceiro exemplo (variáveis locais e globais) 
 
#include <16F877A.h> 
#fuses HS 
#use delay(clock=20M) 
 
int var_global; //declaração de variável global (fora das funções) 
 
main() 
{ 
 int tempo, var_local; 
 var_global=3; 
 var_local=5; 
} 
 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 33
 O programa, apesar de não produzir nenhum efeito sobre os pinos do 
microcontrolador, ilustra a forma de declaração de uma variável global e local. 
 Abaixo da diretiva #use delay temos a declaração de uma variável do tipo 
inteiro cujo nome atribuído foi var_global. Essa é uma variável do tipo global, pois 
está fora de qualquer função. 
 Dentro da função main( ) temos a declaração de duas variáveis do tipo inteiras, 
cujos nomes são tempo e var_local. Essas variáveis são locais, pois foram declaradas 
dentro do corpo da função main( ). As variáveis locais devem sempre ser declaradas 
no início de cada função, antes do chamado a qualquer comando. 
 No final da função main( ) as variáveis local e global são carregadas pela 
atribuição do valor 3 à variável global e do valor 5 à variável local. 
 
 
4.5 Operadores 
 
 Operadores são elementos da linguagem que realizam ações sobre variáveis. 
Podemos classificar os operadores da linguagem C nas categorias principais que seguem 
abaixo: 
 
Operador de atribuição (igualdade): comum à maioria das linguagens, este operador 
(=) faz a variável da esquerda assumir o valor da variável, constante ou expressão da 
direita. Exemplo: 
 
var = var + 2; 
 
Portanto, o conteúdo de var é aumentado de 2. 
 
Operadores aritméticos: realizam operações aritméticas sobre os valores das variáveis, 
constantes ou expressões associadas. 
 
Operador Descrição 
* Multiplicação 
/ Divisão 
% Resto 
+ Adição 
- Subtração 
 
Exemplo: 
 
var = 10 % 3; (o valor de var será 1). 
 
Operadores relacionais 
 
 Eles avaliam o relacionamento entre duas expressões e dão o resultado 1 se 
verdadeiro ou 0 se falso. 
Operador Descrição 
< Menor que 
<= Menor ou igual 
> Maior que 
>= Maior ou igual 
== Igual 
!= Diferente 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 34
 
Exemplo: 
 
var = 2; 
if( var>2 ) 
var = 3; 
 
 Ou seja, o valor de var continua 2. 
 Um lapso comum é confundir o operador de comparação (= =) com o operador 
de igualdade (=). Exemplo: 
 
var = 1; 
if( var=2 ) 
var = 3; 
 
 E o valor de var será 3, o que certamente não era esperado. Isso ocorre 
porque var=2 atribui 2 a var e, desde que foi executado, a expressão retornará um valor 
verdadeiro para a declaração if, permitindo a execução da linha seguinte. Portanto, o 
correto seria 
 
if( var==2 ) 
 
 Deve ser lembrado que, mesmo sem operadores, a linguagem C considera 
verdadeiro qualquer valor não nulo. Por exemplo, após a execução das linhas 
 
var = 2; 
if( -50 ) 
var = 3; 
 
o valor de var será 3. 
 
 
Operadores de incremento e decremento 
 
 São dois operadores bastante úteis para simplificar expressões: 
 
++ (incremento de 1) 
-- (decremento de 1) 
 
 Podem ser colocados antes ou depois da variável a modificar. Se inseridos antes, 
modificam o valor antes de a expressão ser usada e, se inseridos depois, modificam 
depois do uso. Alguns exemplos: 
 
x = 2; 
var = ++x; 
 
 No caso acima, o valor de var será 3 e o de x será 3. 
 
 
 
Operadores de bits 
 
 Manipulam bits em valores inteiros. Nos exemplos a seguir, são considerados 
dados de 8 bits de valores inteiros e sem sinal. 
 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 35
 
~ (complemento): Atuando em apenas um valor, muda os bits de valor 1 para 0 e vice-
versa. Exemplo: se a variável var tem o valor 170 (10101010), após ~var, ela terá 85 
(01010101). 
 
<< (deslocamento à esquerda): Desloca, para a esquerda, os bits do operando esquerdo 
no valor dado pelo operando direito. Equivale à multiplicação pela potência de 2 dada 
por este último. Exemplo: se a variável var tem o valor 3 (00000011), após var << 2, ela 
será 12 (00001100). 
 
>> (deslocamento à direita): Desloca, para a direita, os bits do operando esquerdo no 
valor dado pelo operando direito. Equivale à divisão pela potência de 2 dada por este 
último. Exemplo: se a variável var tem o valor 12 (00001100), após var >> 2, terá 3 
(00000011).& (E): Faz o valor do bit igual a 1 se ambos os bits correspondentes nos operandos são 
1 e 0 nos demais casos. Exemplo: se a variável var tem o valor 12 (00001100) e fazendo 
a operação com 6 (00000110), o resultado, var & 6, será 4 (00000100). 
 
^ (OU exclusivo): Faz o valor do bit igual a 1 se apenas um dos bits correspondentes nos 
operandos é 1 e 0 nos demais casos. Exemplo: se a variável var tem o valor 12 
(00001100) e fazendo a operação com 6 (00000110), o resultado, var ^ 6, será 10 
(00001010). 
 
| (OU inclusivo): Faz o valor do bit igual a 1 se um ou ambos os bits correspondentes 
nos operandos é 1 e 0 nos demais casos. Exemplo: se a variável var tem o valor 12 
(00001100) e fazendo a operação com 6 (00000110), o resultado, var | 6, será 14 
(00001110). 
 
Operadores lógicos 
 
 Usados normalmente com expressões booleanas, isto é, expressões que retornam 
verdadeiro ou falso (1 ou 0), para fins de testes em declarações condicionais. 
 
 
&& (E lógico): Retorna verdadeiro se ambos os operandos são verdadeiros e falso nos 
demais casos. Exemplo: 
 
if( a>3 && b<4). 
 
|| (OU lógico): Retorna verdadeiro se um ou ambos os operandos são verdadeiros e 
falso se ambos são falsos. Exemplo: 
 
if( a>3 || b<4). 
 
 
! (NÃO lógico): Usado com apenas um operando. Retorna verdadeiro se ele é falso e 
vice-versa. Exemplo: 
 
if( !var ). Notar que essa expressão é equivalente a if( var = =0 ). 
 
 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 36
4.6 Declarações de controle 
 
 As declarações ou comandos de controle são uma parte muito importante de uma 
linguagem de programação. Podemos classificar as declarações de controle em duas 
categorias básicas: 
 
1. Declarações de teste condicional: são utilizadas para testar determinadas 
condições/variáveis e executar um código para cada caso. A linguagem C dispõe de dois 
tipos de declarações condicionais: o comando if-else e o comando switch; 
 
2. Declarações de estrutura de repetição: são utilizadas para provocar a execução de um 
bloco de comandos enquanto uma determinada condição for verdadeira. Em C 
dispomos de três declarações de repetição: for, while e do-while. 
 
4.7 O laço While 
 
 O comando while é um comando de repetição. Ele possui a seguinte forma 
geral: 
 
while(condição) 
{ 
 Comando1; 
 Comando2; 
 ... 
} 
 
 A filosofia de funcionamento do comando while é: primeiramente a condição é 
avaliada, caso seja verdadeira, então o comando ou o bloco de comandos associado é 
executado e a condição é novamente avaliada, reiniciando o laço. Caso a condição seja 
falsa, o comando ou o bloco de comandos não é executado e o programa tem sequência 
a partir da declaração seguinte ao bloco while. 
 A condição testada pelo comando while pode ser qualquer expressão da 
linguagem C que possa ser avaliada como verdadeira ou falsa. 
 Podemos alterar o programa visto no início do capítulo a fim de fazer com que o 
LED fique piscando indefinidamente. Para isso, basta introduzir os comandos que estão 
dentro da função main( ) em um laço do tipo while. Para que o laço seja 
indefinidamente repetido, o teste da condição deve resultar sempre num valor 
verdadeiro. Assim, o programa fica como segue abaixo: 
 
 
 
 
 
 
 
 
 
 
 
 
 
// quarto exemplo 
 
#include <16F877A.h> 
#fuses HS 
#use delay(clock=20M) 
 
main() 
{ 
 while(true) //laço de repetição 
 { 
 output_high(pin_b0); //seta o pino rb0 
 delay_ms(500); //aguarda 500ms 
 output_low(pin_b0); //reseta o pino rb0 
 delay_ms(500); //aguarda 500ms 
 } 
} 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 37
 A palavra true usada entre os parênteses do laço while garante que a condição 
sempre é verdadeira, uma vez que a palavra true, em inglês, significa verdadeiro. A 
palavra true é definida como tendo o valor “1” no arquivo de cabeçalho ”.h” do 
dispositivo usado. Assim, os comandos dentro do laço while serão sempre executados 
na ordem em que aparecem. 
 Imaginemos agora que não desejamos mais que o LED fique piscando 
indefinidamente, mas gostaríamos que ele piscasse apenas uma quantidade de vezes 
definida, digamos, dez vezes, e em seguida ele deve permanecer aceso. O programa que 
executa esta função é mostrado abaixo, e uma explicação é dada em seguida. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Na linha: 
 
int contador; 
 
temos uma declaração de variável. Este comando determina que o compilador crie uma 
variável do tipo inteiro int chamada contador. Esta operação irá na realidade reservar 
uma posição na memória RAM do PIC para armazenar valores relativos a essa variável. 
Durante a execução do programa, esse valor pode ser alterado pelo programa, daí essa 
posição ser chamada de variável. O tipo inteiro int especifica um tipo de dado de 8 bits 
com valores compreendidos entre 0 e 255 decimal. 
 Em seguida temos a linha: 
 
contador=0; 
 
que se constitui numa operação de atribuição. As atribuições em C são executadas pelo 
operador de igualdade “=”. Desta forma, essa linha fará com que o compilador gere uma 
sequência de instruções para fazer com que o valor zero decimal seja armazenado na 
posição de memória do PIC nomeada como “contador”. 
 No laço while, a condição agora é que a variável contador seja menor que dez. 
Isso é verdadeiro, já que a variável contador possui o valor zero. Assim, o bloco de 
// Quinto exemplo 
 
#include <16F877A.h> 
#fuses HS 
#use delay(clock=20M) 
 
main() 
{ 
 
 int contador; //definição da variável contador 
 contador=0; //inicialização da variável com zero 
 
 while(contador<10) //laço de repetição 
 { 
 output_high(pin_b0); //seta o pino rb0 
 delay_ms(500); //aguarda 500ms 
 output_low(pin_b0); //reseta o pino rb0 
 delay_ms(500); //aguarda 500ms 
 contador=contador+1; 
 } 
 
 output_high(pin_b0); //seta o pino rb0 
} 
 
Curso – Microcontroladores PIC e Linguagem C 
Prof. Fagner de Araujo Pereira 
 38
comandos dentro das chaves é executado, fazendo com que o LED acenda, espere 
500ms, apague, espere mais 500ms e, depois de feito isso, temos a linha: 
 
contador=contador+1; 
 
que é uma operação de atribuição, fazendo com que a variável contador seja modificada 
para o valor atual do contador mais uma unidade, ou seja, o contador agora passa a ter o 
valor de 1, já que antes possuía o valor zero. 
 Após essa instrução, a condição do laço while é mais uma vez testada. Nesse 
caso, o contador possui o valor 1, e é menor do que 10, fazendo com que o teste da 
condição seja verdadeiro (contador<10). Então, mais uma vez o bloco dentro das chaves 
é executado, fazendo o LED acender e piscar mais uma vez. No final, a variável 
contador é novamente incrementada, passando a ter o valor 2, já que deve assumir o 
valor atual mais uma unidade. O teste da condição do laço while é feito mais uma vez, 
resultado em verdadeiro, já que 2<10, e o processo se repete até que a variável contador 
assuma o valor 9. Quando a variável contador assume o valor 10, o teste da condição 
while não é mais verdadeiro, ou seja, 10 não é menor do que 10. Com isso, o bloco de 
comandos dentro do laço while não é mais executado, e o programa passa direto para o 
comando que vem em seguida, que no caso é o comando output_high(pin_b0), que 
seta o pino rb0, fazendo com que o LED se acenda e fique permanentemente aceso. O 
LED então piscou dez vezes e em seguida ficou permanentemente aceso, como era o 
nosso interesse. 
 
 
4.4 O laço For 
 
 O laço for é uma das mais comuns estruturas de repetição, sendo a versão em C 
considerada uma das mais poderosas e flexíveis dentre todas as linguagens de 
programação.

Outros materiais