Buscar

Unidade IV - Programação em Linguagem Assembler e C++Arduino

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ê também pode ser Premium ajudando estudantes

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ê também pode ser Premium ajudando estudantes

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ê também pode ser Premium ajudando estudantes
Você viu 3, do total de 40 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

Você também pode ser Premium ajudando estudantes

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ê também pode ser Premium ajudando estudantes

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ê também pode ser Premium ajudando estudantes
Você viu 6, do total de 40 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

Você também pode ser Premium ajudando estudantes

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ê também pode ser Premium ajudando estudantes

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ê também pode ser Premium ajudando estudantes
Você viu 9, do total de 40 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

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

Microprocessadores
Material Teórico
Responsável pelo Conteúdo:
Prof. Me. Massaki de Oliveira Igarashi
Revisão Textual:
Prof.ª Dr.ª Selma Aparecida Cesarin
Programação em Linguagem Assembler e C++Arduino
• Capítulo 1 – Introdução;
• Capítulo 2 – Programação Assembler;
• Capítulo 3 – Programação C/C++ para Arduino.
 · Introduzir os conceitos de programação de microcontroladores e 
microprocessadores. Para isso, são apresentados ao leitor conceitos 
fundamentais e também conceitos de programação Assembler e 
C/C++ para microcontroladores PIC® e Arduino.
OBJETIVO DE APRENDIZADO
Programação em Linguagem 
Assembler e C++Arduino
Orientações de estudo
Para que o conteúdo desta Disciplina seja bem 
aproveitado e haja maior aplicabilidade na sua 
formação acadêmica e atuação profissional, siga 
algumas recomendações básicas: 
Assim:
Organize seus estudos de maneira que passem a fazer parte 
da sua rotina. Por exemplo, você poderá determinar um dia e 
horário fixos como seu “momento do estudo”;
Procure se alimentar e se hidratar quando for estudar; lembre-se de que uma 
alimentação saudável pode proporcionar melhor aproveitamento do estudo;
No material de cada Unidade, há leituras indicadas e, entre elas, artigos científicos, livros, vídeos 
e sites para aprofundar os conhecimentos adquiridos ao longo da Unidade. Além disso, você 
também encontrará sugestões de conteúdo extra no item Material Complementar, que ampliarão 
sua interpretação e auxiliarão no pleno entendimento dos temas abordados;
Após o contato com o conteúdo proposto, participe dos debates mediados em fóruns de discus-
são, pois irão auxiliar a verificar o quanto você absorveu de conhecimento, além de propiciar o 
contato com seus colegas e tutores, o que se apresenta como rico espaço de troca de ideias e 
de aprendizagem.
Organize seus estudos de maneira que passem a fazer parte 
Mantenha o foco! 
Evite se distrair com 
as redes sociais.
Mantenha o foco! 
Evite se distrair com 
as redes sociais.
Determine um 
horário fixo 
para estudar.
Aproveite as 
indicações 
de Material 
Complementar.
Procure se alimentar e se hidratar quando for estudar; lembre-se de que uma 
Não se esqueça 
de se alimentar 
e de se manter 
hidratado.
Aproveite as 
Conserve seu 
material e local de 
estudos sempre 
organizados.
Procure manter 
contato com seus 
colegas e tutores 
para trocar ideias! 
Isso amplia a 
aprendizagem.
Seja original! 
Nunca plagie 
trabalhos.
UNIDADE Programação em Linguagem Assembler e C++Arduino
Capítulo 1 – Introdução
Neste Capítulo, serão apresentados conceitos básicos necessários ao aprendi-
zado das Linguagens de Programação utilizadas para microcontroladores e micro-
processadores.
Nos fóruns de discussões sobre microcontroladores, são muito comuns comen-
tários valorizando esta ou aquela linguagem de programação para microcontrola-
dores e microprocessadores, ou ressaltando um ou outro fabricante.
Mas, para escolher a Linguagem e o Fabricante a se trabalhar, é importante 
ficar atento às características técnicas do projeto e levar em consideração, 
principalmente: a arquitetura, o consumo (caso o Projeto demande baixo consumo, 
ou seja, móvel), os periféricos, a velocidade e a capacidade de processamento, 
o tamanho, o encapsulamento e a escalabilidade (ou possibilidade de expansão). 
Além do tempo de fornecimento do produto, sua disponibilidade, seu suporte e 
a documentação do fabricante, a experiência do time de desenvolvimento e as 
ferramentas para correção de bugs. 
Já quanto às Linguagens de Programação a se utilizar, percebe-se que as princi-
pais linguagens utilizadas são Assembler (ou Assembly) e linguagem C/C++, que 
também serão abordadas nesta Unidade. 
Primeiramente, é preciso entender o porquê de se utilizar Assembler: é uma 
Linguagem eficiente (ou seja, permite ao programador desenvolver um Programa 
que rode mais rápido, que consuma pouco processamento ou que exija o mínimo 
de memória possível); também, permite acesso direto ao hardware. Além disso, 
um bom Programador Assembly pode prover segurança e controle que nenhum 
outro poderia ter; porém, ele também pode abrir brechas que outras Linguagens 
não abririam.
Apesar de muitas vantagens, é importante ressaltar que, geralmente, é muito 
trabalhoso, demorado e entediante programar em Assembler.
Ciclo de Máquina
O ciclo de máquina é o período de tempo no qual um microcontrolador ou 
microprocessador lê e processa uma instrução da sua memória para executar cada 
instrução em Código de Máquina num Programa.
Para calcular o tempo de duração de um Ciclo de Máquina (CM ou TCY), 
basta obter o inverso do valor do clock interno (CKINT) do microprocessador ou 
microcontrolador, conforme ilustra a equação I:
 T
CKCY INT
=
1
 (I)
8
9
Já o valor do clock interno pode variar entre os fabricantes de microcontroladores 
e microprocessadores. No caso da maioria dos microcontroladores PIC®, o clock 
interno é equivalente ao clock externo (CKEXT ou FOSC) dividido por 4 (Equação II):
 CK
CK
INT
EXT=
4
 (II)
Observa-se que o clock externo é obtido a partir de um cristal oscilador adqui-
rido comercialmente em lojas ou sites de componentes eletrônicos; esses cristais 
têm frequência de oscilação que podem variar de alguns quilohertz (kHz), no caso 
dos cristais de baixa potência, até algumas dezenas de mega-hertz, no caso dos 
cristais de alta velocidade. Portanto, no caso de se utilizar um cristal comercial cuja 
Fosc = 4 MHz, o ciclo de máquina será de 1 microssegundo.
A característica de buscar a informação num Ciclo de Máquina e executá-la no 
próximo Ciclo é denominada pipeline. Ela permite que as instruções sejam execu-
tadas dentro de um ciclo, gastando, no caso do cristal de 4MHz, 1 microssegundo.
São exceções os casos de instruções que geram saltos no Contador de Programa 
(PC), como chamadas de rotinas e retornos; ao executar as instruções, o pipeline 
deve ser previamente limpo para depois poder ser carregado, novamente, com o 
endereço correto, consumindo para isso dois Ciclos de Máquina.
Glossário de Termos Utilizados
Para facilitar o aprendizado sobre a construção dos nomes e das instruções, 
foi escolhido como exemplo o set de instruções dos microcontroladores PIC®. 
A seguir, são elencados os principais termos e explicações a seu respeito:
• Work: registrador ou acumulador temporário para as operações da ULA. Na 
Linguagem Assembler dos microontroladores, PIC é conhecido como W;
• File: referência a um registrador (posição de memória). Utiliza-se a letra F para 
a sua representação nos nomes de instruções e f nos argumentos delas;
• Access: referência ao acesso da memória RAM via Access Bank ou via Banco 
por meio do registrador BSR. Utiliza-se a letra a nos argumentos das instruções;
• Literal: um número qualquer, que pode ser escrito na forma decimal, hexa-
decimal ou binária. Utiliza-se a letra L para sua representação nos nomes de 
instruções e k nos argumentos delas;
• Destino: local onde deve ser armazenado o resultado da operação. Existem 
somente dois destinos possíveis: f, que guarda o resultado no próprio registra-
dor passado como argumento ou w, que coloca o resultado em Work. Mais 
especificamente, na sintaxe das instruções, o destino deve ser expresso pelos 
números 0 (w) e 1 (f). Mas, observa-se que as letras f e w são definidas no in-
clude para facilitar a programação;
• Não (Not): operação ou estado oposto. Utiliza-se a letra N para a sua repre-
sentação nos nomes das instruções;
9
UNIDADE Programação em Linguagem Assembler e C++Arduino
• Borrow: refere-se ao STATUS do bit Borrow (ou “vem 1” de uma operação 
de subtração) do registrador. Utiliza-se a letra B para sua representação;
• Overflow: refere-se ao STATUS do bit overflow do registrador. Utilizam-se as 
letras OV para sua representação nos nomes das instruções;
• Bit: refere-se a um bit específico dentro de um byte. Utiliza-se a letra B para 
sua representação nos nomes das instruções e b nos argumentos delas;• Teste: quando se deseja testar o estado de um bit, serve para descobrir se ele 
é zero ou um. Utiliza-se a letra T para representá-lo nos nomes das instruções;
• Skip: significa “pulo”; é utilizado para criar desvios, pulando para a próxima 
linha. Utiliza-se a letra S para representá-lo nos nomes das instruções;
• Set: refere-se ao ato de setar um bit; ou seja, torná-lo com o valor 1. Utiliza-se 
a letra S para representá-lo nos nomes das instruções;
• Clear: refere-se ao clear de um bit, ou seja, torná-lo com valor 0. Utiliza-se a 
letra C para representá-lo nos nomes das instruções;
• Toggle: refere-se ao ato de inverter o estado de um bit. Utiliza-se a letra T 
para representá-lo nos nomes das instruções;
• Zero: algumas instruções podem gerar desvios se o resultado da operação 
efetuada for zero. Neste caso utiliza-se a letra Z para indicar tal condição;
• ADD: somatória;
• AND: lógica “E”;
• CLR: limpar, zerar (Clear);
• COM: complemento;
• CPF: comparar registrador;
• DEC: decremento de uma unidade;
• EQ: igual;
• GT: maior que (>);
• INC: incremento de uma unidade;
• IOR: lógica “OU”;
• LT: menor que (<);
• MOV: mover, transferir para algum lugar;
• MUL: multiplicar;
• RD: leitura;
• RL: rotacionar um bit para a esquerda (rotation left);
• RR: rotacionar um bit para a direita (rotation right);
• SET: setar todos os bits de um registrador, ou seja, tornar todos com o valor 1;
10
11
• SUB: subtração;
• SWAP: inversão entre as partes alta e baixa de um registrador;
• TST: teste;
• TBL: tabela;
• XOR: lógica “OU Exclusivo”;
• WT: escrita.
Conversor Analógico-Digital
A natureza e a maioria das coisas ao nosso redor são analógicas, por isso, é 
importante destacar aqui os conceitos necessários para uma conversão de um Sinal 
Analógico para Digital. Tais conceitos podem ser úteis na conversão de sinal de 
sensores de temperatura, pressão, tensão e posicionamento, entre outros.
Um microcontrolador e também os microprocessadores podem monitorar um 
ou mais sinais por meios de sua(s) entrada(s) Analógico-Digitais (AD ou A/D), 
cuja resolução em bits varia de 4 a 12 bits, mas a resolução de 10 bits é uma 
das mais utilizadas.
O primeiro conceito a se entender numa conversão analógico-digital é o valor 
correspondente à variação de cada unidade de tensão (Equação III):
 V
V V
unidade
ref ref
n=
−
−
+ −
2 1
 (III)
No caso de um microcontrolador alimentado a 5 Volts, ou seja, VREF+ = +5V e 
Vref– = 0 V (Comum da fonte) e , e considerando, ainda, uma resolução de 10 bits 
para esse microcontrolador, o valor , aproximadamente, ou seja, 5 milivolts. Para 
ser mais específico, 4,887585 mV.
Uma vez convertido, o valor do Sinal Analógico pode ser representado por uma 
variável interna pela equação IV:
 Valor
V
V
V
conversor
sinal analogico
n
referencia
sinal a=
−( )
=_ _
* 2 1
nnalogico
bitV1
 (IV)
Para testar a equação IV, no nosso exemplo hipotético, consideremos que o 
Valor Analógico a ser convertido, instantaneamente, seja 2,0 Volts e, considerando, 
ainda, que no microcontrolador de uma tensão de referência de 5,0 Volts, o valor 
a ser devolvido pelo conversor será aproximadamente 410 (você entenderá, por 
meio do exemplo 2 de programação Assembler, que basta uma Regra de Três para 
converter novamente, via programa, esse valor convertido digitalmente para seu 
real valor introduzido na entrada analógica).
11
UNIDADE Programação em Linguagem Assembler e C++Arduino
Tempo de aquisição e conversão do sinal
Para se evitar problemas de ruído e variações da entrada analógica durante o 
processo de conversão, já que nada é absolutamente instantâneo, alguns micro-
controladores e também microprocessadores utilizam, internamente, um processo 
denominado Sample and Hold (S/H), termo que se traduzido para o português 
significaria amostra e congela; observa-se que, no caso da ausência do S/H interno, 
pode-se acrescentar um circuito integrado S/H para atuar nesse caso.
No caso dos microcontroladores PIC®, eles costumam apresentar um S/H inter-
no com capacitor de valor 25 pF (vide datasheet do microcontrolador para expli-
cação mais detalhada do circuito com o ), que é ligado ao Canal Analógico em uso.
Esse capacitor carrega-se com a tensão existente no canal (tensão da amostra); 
quando o processo de conversão é iniciado, esse capacitor é desligado automa-
ticamente do Canal Analógico, mantendo a tensão sobre o capacitor constante. 
Por isso, durante todo o processo de conversão, a tensão utilizada é a existente no 
capacitor e não mais a do Canal Analógico. Logo, mesmo que a tensão externa no 
canal varie, a conversão não é afetada.
Internamente, o capacitor nunca fica desligado, exceto durante a conversão; ele 
sempre se encontra ligado ao Sistema de Entradas Analógicas.
Mas caso o canal ativo esteja ligado ao GND, o capacitor ficará totalmente des-
carregado. Mas se, num momento seguinte, desejar-se medir outra Entrada Analó-
gica (outro Canal) e por isso o Sistema é chaveado internamente (será visto mais à 
frente como isso é possível).
Caso o outro Canal esteja com uma tensão de 5,0 V, o capacitor interno terá 
de ser completamente carregado antes que seja possível começar a efetuar a nova 
conversão. Obviamente, essa carga não é instantânea.
Para evitar problemas, sugere-se que o tempo padrão deixado para garantir a 
carga do capacitor seja de pelo menos 40 us. Obviamente, esse é um tempo que 
garante a pior condição. Na verdade, o tempo de adequação pode ser bem menor 
que isso, chegando ao mínimo a 1 μs.
Essa variação depende basicamente da diferença de tensão entre a entrada e o 
capacitor, da temperatura e da impedância de entrada. Essa impedância deve ser 
de no mínimo 50 Ω e no máximo 2,5 Ω. Quanto menor a impedância, menor 
também o tempo de adequação. Para o cálculo exato desse tempo, consulte o 
datasheet do microcontrolador.
Para que o Sistema de Conversão funcione corretamente, um clock deve ser 
aplicado a ele; nesse caso, cada período desse clock é chamado TAD e é equivalente 
ao tempo de conversão de 1 bit. No caso de um conversor de 10 bits, o tempo 
total de conversão é de 10TAD + 2TDA, ou seja, 12TAD.
Os dois períodos adicionais são para a adequação e o início da conversão. Além 
disso, o valor de TAD depende da frequência empregada e, para isso, o Sistema 
possui um RC interno ou divisores para o oscilador da própria máquina.
12
13
Com o término da conversão, o valor dos registradores de resultado é atuali-
zado, o flag da interrupção é marcado e o capacitor religado. O tempo mínimo 
recomendado para que tudo isso aconteça é de 2TDA.
Observa-se que durante o tempo da conversão, o valor da tensão no capacitor 
interno não foi alterado; porém, ao término da conversão, ele será religado à 
entrada analógica, que pode ter sofrido uma variação brusca (como no exemplo 
anterior), seja por imposição do próprio Sistema, seja por uma troca de Canal. Por 
isso, entre uma conversão e outra é necessário que haja uma adequação da carga 
do capacitor. Nesse caso, recomenda-se, novamente, um tempo mínimo de 40 µs.
O Módulo PWM
O módulo PWM (sigla que advém do termo em inglês Pulse Width Modulation), 
que significa Modulação por Largura de Pulso, é, provavelmente, um dos recursos 
mais poderosos de um microcontrolador ou microprocessador, pois com ele pode-
se obter um Sinal Digital com Largura de Pulsos controlada por meio de software.
As aplicações do módulo PWM são diversas: controle de abertura e fechamento 
de válvulas, controle de motores, controle de luminosidade para LEDs, gerador de 
tensão analógica (observação: para esse tipo de aplicação, faz-se necessário adicio-
nar um hardware complementar de conversor Digital-Analógico (DA) ou filtro RC 
com frequência de corte igual à frequência do PWM para que o Sinal Analógico 
seja gerado a partir de um pulso digital como é o caso do sinal PWM), entre outras.
A Figura 1 mostra uma função digital da tensão V(t) no tempo, cujo período é T 
e a tensão de pulso Vpulso:
GNDpulsoV
tp
T
Figura 1 – Forma de onda de um sinal PWM
Num sinal PWM, a razão entre a Largura de Pulso e o período da forma de onda 
recebe o nome, oriundo da língua inglesa, de duty cycle, cuja tradução seria ciclo 
ativo ou ciclo de trabalho.
Esse pulso apresenta uma tensão fixa; porém, o valor médio da sua tensão varia 
em função do duty cycle. Portanto, a tensão média (Vdc) é diretamente proporcional 
ao duty cycle e como esse varia entre 0 (quando tp = 0) e 1 (quando tp = T), a 
Tensão Média de Onda pode variar entre 0 e ou, mais especificamente, entre 0 e 
5 Volts quando VSS = 0 e VDD = 5V, conforme a Equação V.
 V
t
T
Vdc
p
pulso= (V)
13
UNIDADE Programação em Linguagem Assembler e C++Arduino
Capítulo 2 – Programação Assembler
Neste Capítulo, você aprenderá um pouco dos conceitos básicos de programação 
Assembler para microcontroladores e microprocessadores.
Para o aprendizado e prática da Linguagem Assembler, recomenda-se instalar 
algum compilador de Assembler disponível na Internet ou utilizar, por exemplo, 
softwares já consolidados e conhecidos como o MPLAB®, do fabricante Microchip 
Technology Inc.
Vale ressaltar, também, que você pode utilizar algum gravador de microcontro-
lador comercial, ou comprar um gravador universal ou, até mesmo, construir seu 
próprio gravador para realizar testes de prototipagem, seguindo dicas facilmente 
encontradas na Internet.
Na linguagem Assembler, a utilização do “;” serve para introduzir comentários 
no programa; esses comentários não terão função alguma dentro do programa, 
servindo apenas para sua organização pessoal e explicação de comandos utilizados. 
Os comentários o ajudarão a entender o seu programa caso você só volte a utilizá-
lo após um longo prazo, mas, também, são úteis para que outros programadores 
possam entender o seu programa.
Exemplo 1: Programa Pisca Leds
Nesse primeiro exemplo, será utilizado o microcontrolador PIC12F675, um 
microcontrolador muito utilizado para aplicações simples e até semiprofissionais; 
por meio do seu datasheet, é possível descobrir quais Registradores de Função 
Especial (SFRs) devem ser configurados e com quais valores, de acordo com as 
especificações do Sistema.
Ao fazer isso, para esse primeiro exemplo, constata-se que é preciso configurar 
os registradores a seguir para que o Programa, que será escrito, funcione adequa-
damente conforme o circuito da Figura 2.
Serão apresentados também alguns registradores e comandos básicos da Lin-
guagem Assembler num programa cuja funcionalidade é fazer piscar três LEDs: 
um verde (ligado no pino 2), um amarelo (ligado no pino 3) e um vermelho (ligado 
no pino 6), em intervalos de 500 ms.
14
15
+
+
+
PIC 12F675
5V
5V
5V
5V
10k
330
1 2 3 4
5678
330
330
Verde Amarelo
VermelhoPotenciômetro
Chave 1
Chave 2
+
Figura 2 – Circuito base do exemplo pisca LED
• a) ANSEL – Seleção da Função Analógica ou Digital para os pinos de entrada e 
saída que podem operar nesses dois modos, conforme descrito a seguir. Ao se 
escrever “1” no bit associado ao pino, indica-se que o seu funcionamento será 
no Modo Analógico; já se for escrito “0”, configura-se o pino para trabalhar 
no Modo Digital:
 » Pino 7 – Modo Digital (GPIO 0) ou Modo Analógico (AN 0);
 » Pino 6 – Modo Digital (GPIO 1) ou Modo Analógico (AN 1);
 » Pino 5 – Modo Digital (GPIO 2) ou Modo Analógico (AN 2);
 » Pino 3 – Modo Digital (GPIO 4) ou Modo Analógico (AN 3).
• b) TRISIO – Definição da direção do sinal (entrada ou saída) em um pino. Ao 
escrevermos “0” no bit associado ao pino, configura-se o pino como saída 
(output); já se for escrito “1”, conFigura-se o pino como entrada (input);
• c) CMCON – Controle das funções do comparador de tensão interno do 
microcontrolador;
• d) GPIO – Seleção do nível lógico de um pino quando ele for configurado 
como saída digital, ou leitura do nível presente em um pino quando ele for 
configurado como entrada digital. Para fazer a configuração correta desses 
SFRs, é preciso estar atento ao fato de que os registradores ANSEL e TRISIO 
estão presentes fisicamente no Banco de Memória 1, enquanto os registradores 
CMCON e GPIO estão presentes fisicamente no Banco de Memória 0. Sendo 
assim, antes de utilizá-los, deve-se configurar adequadamente o bit 5 (RP0) do 
registrado STATUS.
15
UNIDADE Programação em Linguagem Assembler e C++Arduino
A Tabela 1 traz, em sua coluna da esquerda, o Código completo de um Programa 
desse primeiro exemplo e, na coluna da direita, as explicações e o detalhamento 
das instruções desse Programa, que está dividido em blocos, para facilitar seu 
entendimento.
Tabela 1 – Exemplo de um programa Assembler pisca LED com suas explicações
;INCLUSAO DE BIBLIOTECAS
#INCLUDE <p12f675.inc> ; definições referentes ao 
PIC12F675
Deve-se incluir as bibliotecas necessárias; elas, geralmente, 
já estão nos compiladores. Mas, caso contrário, os 
fabricantes disponibilizam atualizações nos seus sites.
;CONFIGURAÇÃO DO MODO DE FUNCIONAMENTO
__CONFIG _INTRC_OSC_NOCLKOUT & _WDT_OFF & 
_PWRTE_OFF & _MCLR_
OFF & _CPD_OFF & _CP_OFF &
Alguns comandos habilitam ou desabilitam chaves internas 
que apresentam algumas funcionalidades específicas, 
como a seguir:
_INTRC_OSC_NOCLKOUT ;o PIC utilizará o oscilador 
interno de 4 MHz,
_WDT_OFF ; desliga o Watchdog timer.
_PWRTE_OFF ; desliga o reset de power on.
_MCLRE_OFF ; desliga o masterclear.
Os comandos se unem pelo concatenador &
;DEFINIÇÃO DOS NOMES E ENDEREÇOS DAS
VARIÁVEIS UTILIZADAS NO
PROGRAMA
CBLOCK 0x0C ; endereço inicial da memória de usuário
TEMP1 ; contador para o delay de 1 ms
TEMP500 ; contador para o delay de 500 ms
ENDC ; fim do bloco de memória de variáveis
Precisa-se declarar o endereço inicial para a criação das 
variáveis e também definir cada uma das variáveis.
;DEFINIÇÃO DAS ENTRADAS DIGITAIS
#DEFINE Chave_1 GPIO, 2; Pino 5
#DEFINE Chave_2 GPIO, 3; Pino 4
;DEFINIÇÃO DAS SAÍDAS DIGITAIS
#DEFINE LED_VD GPIO, 5 ; Pino 2
#DEFINE LED_AM GPIO, 4 ; Pino 3
#DEFINE LED_VM GPIO, 1 ; Pino 6
Além disso, é preciso associar nomes significativos aos 
pinos de entrada e saída do microcontrolador que serão 
utilizados.
;DEFINIÇÃO DO SELETOR DO BANCO DE MEMÓRIA
#DEFINE Banco STATUS, RP0 ;bit RP0 do registradorSTATUS 
(SFR)
;CONFIGURAÇÃO DOS SFRs
BSFBanco ; Seleção do Banco 1 da Memória
MOVLW B’00000001’ ; modo analógico/digital dos pinos 
de I/O
MOVWF ANSEL
MOVLW B’00001101’ ; direção dos pinos de I/O digitais
MOVWF TRISIO
BCF Banco ; seleção do Banco 0 da Memória
MOVLW B’00000111’ ; desativação do comparador de 
tensão
MOVWF CMCON
Também é preciso configurar alguns registradores internos 
que serão utilizados
no programa. Costuma-se, inicialmente, colocar o valor 
numérico para o registrador W (comando MOVLW) e, na 
sequência, transferir o valor de W para o registrador alvo 
(comando MOVWF).
;INICIALIZAÇÃO DO PROGRAMA
BCF LED_VD ; apaga o LED verde
BCF LED_AM ; apaga o LED amarelo
BCF LED_VM ; apaga o LED vermelho
Aqui, são inicializados os pinos de saída, apagando 
todos os LEDs pela imposição de valor zero aos pinos 
correspondentes (comando BCF).
16
17
;ROTINA PRINCIPAL, implementa um loop infinito
Principal:
BSF LED_VD ; acende o LED verde
CALL DELAY_500MS ; pausa de 500 ms
BCF LED_VD ; apaga o LED verde
CALL DELAY_500MS ; pausa de 500 ms
GOTO Principal ; salto para o início da rotina principal
; Rotina de delay de 500 ms. Repete 200 x a rotina de 2,5 
ms
Agora, deve-se implementar um loop infinito criando o 
rótulo Principal, executando algumas instruções e, no final, 
efetuando um salto incondicional (GOTO) para o mesmo 
label.
Inicialmente, liga-se o LED verde pela imposição de nível 1 
no pino correspondente
(Comando BSF).
Em seguida, chama-se a sub-rotina que provoca um delay 
de 500 ms.
Depois, novamente coloca-se o nível “0” no LED (chamamos 
novamente a sub-rotina de delay de 500 ms) e se recomeça 
a mesma sequência.
DELAY_500MS:
MOVLW .200
MOVWF TEMP500
DL_50
CALL DELAY_2MS ; pausa de 10 ms
DECFSZ TEMP500,F ; decrementa TEMP500. Zerou?
GOTODL_50 ; não, repete o ciclo.
RETURN ; sim, finaliza a rotina.
; Rotina de delay de 2,5 ms. Repete 250 x a rotina de 10 μs
DELAY_2MS:
MOVLW .250
MOVWF TEMP1
DL_10 ; cada ciclo gasta 10 microsegundos
NOP ; gasta um ciclo de tempo
NOP ; gasta um ciclo de tempo
NOP ; gasta um ciclo de tempo
NOP ; gasta um ciclo de tempo
NOP ; gasta um ciclo de tempo
NOP ; gasta um ciclo de tempo
NOP ; gasta um ciclo de tempo
DECFSZ TEMP1,F ; decrementa TEMP1. Zerou?
GOTO DL_10 ; não, repete o ciclo
RETURN ; sim, finaliza a rotina
O delay de 500 ms é obtido por meio da repetição (200 
vezes) da rotina de atraso de 2,5 ms. Inicia-se colocando 
o valor 200 na variável TEMP500 (por meio do registrador 
W) e se efetuam sucessivas chamadas à rotina de atraso de 
2,5ms. Depois disso, deve-se ir decrementando a variável 
TEMP500 até que ela chegue a zero, momento em que 
haverá o retorno (RETURN) da sub-rotina.
Analogamente, há a rotina de atraso de 2,5 ms, obtida 
pela repetição (250 vezes) de um bloco que consome 
10 microsegundos. Esse tempo é alcançado por meio de 
sete instruções NOP (que não possuem função alguma e 
consomem 1 ciclo de máquina), uma instrução DECFSZ (que 
consome mais 1 ciclo de máquina) e a instrução GOTO (que 
consome 2 ciclos de máquina).
END
;FIM DO PROGRAMA Finalmente, o programa se encerra com a instrução END.
Exemplo 2: Programa Conversão AD
Este segundo exemplo, diferente do primeiro, foi escrito com base no datasheet 
do microcontrolador PIC18F4520, outro microcontrolador muito utilizado por 
amantes de eletrônica e até mesmo para aplicações profissionais.
Ele é muito parecido com o PIC12F675, mas, ao invés de 4 conversores AD, 
como é o caso do primeiro, o PIC18F4520 possui 10 conversores no caso dos 
encapsulamentos de 28 pinos (por exemplo, encapsulamento DIP) e 13 conversores 
AD no caso dos encapsulamentos de 44 pinos (por exemplo, encapsulamento 
TQFP e QFN); esse maior número de entradas analógico-digitais possibilitam-no se 
conectar a um maior número de sensores e, portanto, aplicações mais complexas.
Claro que ainda são possíveis outros tipos de expansão ou conexão do mi-
crocontrolador ou microprocessador digitalmente a circuitos integrados dedicados, 
especificamente para a conversão AD, ou também multiplexação de sinais, mas 
17
UNIDADE Programação em Linguagem Assembler e C++Arduino
essas abordagens mais complexas não serão vistas neste Curso Introdutório de 
microprocessadores e microcontroladores.
Esse exemplo consiste num programa Assembler para leitura da tensão ajustada 
pelo potenciômetro ou trimpot P2 (Figura 3). A conversão será realizada direta-
mente no loop principal do Programa, sem a utilização de interrupção específica 
(nem para verificar o término da conversão, nem para definir a frequência de 
amostragem); portanto, a conversão será realizada uma após a outra, na frequência 
definida pelo período do loop principal.
+
4,7K
LM358
P2
10K
+5V
+5V
+5V
4MHz
RS
EN
10K
Reset
MC1
+5V
1uF
330R
RA1
+5V
10K
RS
EN
LCD
4
1
3
27
8
9
10
11
12
13
14
6
5
RS
EN
R/W
VDB0
DB1
DB2
DB3
DB4
DB5
DB6
DB7
DD
VSS
VO
MCLR
RAD
RA1 RB7
RB6
RB5
RB4
RB3
RB2
RB1
RB0
RD7
RD6
RD5
RD4
RD3
RD2
RD1
RD0
RC7
RC6
PIC18F4520
RA2
RA3
RA4
RA5
RE0
RE1
RE2
RC0
RC1
RC2
RC3
RC4
RC524
23
18
17
16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1 32
31
40
39
38
37
36
35
34
33
30
29
28
27
22
21
20
19
26
25
OSC1
OSC2
VDD
VSS
VDD
VSS
Figura 3 – Esquema elétrico do circuito de conversão AD interno utilizando um microcontrolador PIC18F4520
Nesse caso, terminada a conversão, descartam-se os dois bits menos significativos 
e se considera somente o resultado armazenado em ADRESH; isso fará com que já 
ocorra uma espécie de filtragem e se evita uma oscilação do valor final convertido.
O valor a ser exibido por meio do display LCD nada mais é que o valor 
calculado por uma Regra de Três (Equação V). Isso ocorre porque o AD interno do 
microcontrolador retorna o valor de conversão 0 para valor de entrada Ventrada = 0,0 
Volt e 255 para valor de entrada Ventrada = 5,0 Volts, no caso de microcontroladores 
alimentados a 5,0 Volts. Portanto, para se descobrir Ventrada basta-se dividir o valor 
convertido (Vconv) por 255 e multiplicar o resultado por 5,0.
 V
Vconv
Voltsentrada =





255
5 0* , [ ] (VI)
A seguir, o exemplo de um Programa de Conversão AD utilizando um dos 
conversores AD internos ao microcontrolador PIC deste exemplo:
18
19
;**********************************************************************
; EXEMPLO ELABORADO PARA EXPLICAR O MÓDULO DE CONVERSAO AD INTERNO DO 
; PIC,
; Será convertido o valor analógico presente no pino RA2 do microcontrolador
; O valor na entrada a ser convertido varia entre 0,0 Volt a 5,0 Volts e é mostrado 
no LCD 16x16
; Rotinas do LCD são baseadas no APLICATION NOTES da MICROCHIP.
;
; CONFIGURACÕESS PARA GRAVACAO
;
CONFIG OSC= XT, FCMEN = OFF, IESO = OFF, PWRT= ON, BOREN = ON, BORV= 0
CONFIG WDT = ON, WDTPS = 128, MCLRE = ON, LPT10SC= OFF, PBADEN= OFF
CONFIG CCP2MX = PORTC, STVREN= ON, LVP = OFF, DEBUG = OFF, XITNST=OFF
CONFIG CP0= OFF, CP1 = OFF, CP2 = OFF, CP3= OFF, CPB=OFF, CPD = OFF
CONFIG WRT0 = OFF, WRT1= OFF, WRT2 = OFF, WRT3 = OFF, WRTB= OFF
CONFIG WRTC = OFF, WRTD = OFF, EBTR0 = OFF, EBTR1 = OFF, EBTR2= OFF
CONFIG EBTR3= OFF, EBTRB = OFF
;*********************************************************************
; DEFINICAO DAS VARIAVEIS
;*********************************************************************
 CBLOCK 0X00 ; BANK 0 --- > 0X00 .. 0X5F --- > ACCESS BANK
ACCaHI ; ACUMULADOR a DE 16 BITS A SER UTILIZADO
ACCaLO ; NA ROTINA DE DIVISÃO
ACCbHI ; ACUMULADOR b DE 16 BITS A SER UTILIZADO
ACCbLO ; NA ROTINA DE DIVISÃO
ACCcHI ; ACUMULADOR c DE 16 BITS A SER UTILIZADO
ACCcLO ; NA ROTINA DE DIVISÃO
ACCdHI ; ACUMULADOR d DE 16 BITS A SER UTILIZADO
ACCdLO ; NA ROTINA DE DIVISÃO
Temp ; CONTADOR TEMPORÁRIO UTILIZADO
 ; NA ROTINA DE DIVISÃO
TEMPO0 ; TEMPORIZADORES PARA A ROTINA
TEMPO1 
AUX ; REGISTRADOR AUXILIAR DE USO GERAL
UNIDADE ; ARMAZENA VALOR DA UNIDADE DE TENSÃO
DEZENA ; ARMAZENA VALOR DA DEZENA DE TENSÃO
 ENDC
19
UNIDADE Programação em Linguagem Assembler e C++Arduino
#INCLUDE <P18F4520.INC> ; BIBLIOTECA DO MICROCONTROLADORUTILIZADO
; ESTE PROGRAMA UTILIZA APENAS 1 ENTRADA, NO CASO A ENTRADA RA1 DO CONV. AD
; SERA UTILIZADO DEFINE APENAS P/ DEFINIR UM NOME MAIS PRÁTICO P/ ESTA ENTRADA
; OBS: O CANAL AD A SER CONVERTIDO É SELECIONADO NO REGISTRADOR ADCN0 
; DE FORMA BINÁRIA, E NÃO ATRAVÉS DE DEFINES
 #DEFINE CAD_P2 PORTA, 1
; SERA UTILIZADO DEFINE TAMBÉM PARA FACILITAR NOMENCLATURA DAS 
; SAÍDAS DO PROGRAMA
 #DEFINE DISPLAY LATD ; ACESSO AO BARRAMENTO DE DADOS P/ DISPLAY
 # RS LATE, 0; INDICA PARA O DISPLAY DADO ou COMANDO
 ; 1 -> DADO
 ; 0 -> COMANDO
 #DEFINE ENABLE LATE, 1; SINAL DE ANABLE P/ O DISPLAY
 . ATIVO NA BORDA DE DESCIDAS
; VETOR DE RESET DO MICROCONTROLADOR
; POSICAO INCIAL PARA EXECUÇÃO DO PROGRAMA
 ORG 0X0000 ; ENDEREÇO DO VETOR DE RESET
 BRA CONFIGURACAO ;PULA P/ CONFIGURACAO 
 ;DEVIDO REGIAO DAS RITINAS SEGUINTES
;*********************************************************************
; ROTINA DE DELAY (de 1 ms até 256ms
;*********************************************************************
; OBS: Esta é uma rotina de delay variável, com duração de 1 ms x Valor passado em 
Work (W).
DELAY_MS
 MOVWF TEMPO1 ;CARREGA TEMPO 1 (UNIDADE DE MS)
 MOVLW .250
 MOVWF TEMPO0 ; CARREGA TMEPO PARA CONTAR 1 MS
 CLRWDT ; LIMPA WDT (GASTA TEMPO)
 DECFSZ TEMPO0, F ; FIM DE TEMPO0?
 BRA $-.4 ; NÃO = VOLTA 2 INSTRUÇÕES
 ; SIM = PASSOU-SE 1 MS 
 DECFSZ TEMPO1, F ; FIM DE TEMPO 1?
 BRA $-.12 ; NÃO = VOLTA 6 INSTRUÇÕES
 ; SIM = RETORNA
 RETURN
;*********************************************************************
20
21
; ROTINA PARA ESCRITA DE CARACTERES NO DISPLAY LCD
;*********************************************************************
; OBS: O caractera ser escrito deve ser colocado em work (W) antes de se chamar a 
rotina
ESCREVE
 MOVWF DISPLAY ; ATUALIZA DISPLAY (PORTD)
 NOP
 BSF ENABLE ; ENVIA UM PULSO DE ENABLE AO DISPLAY
 BRA $+.2
 BCF ENABLE 
 MOVLW .1
 RCALL DELAY_MS ; CHAMA ROTINA DELAY_MS para delay de 1ms
 RETURN ; RETORNA
;*********************************************************************
; ROTINA DE AJUSTE DECIMAL
; W [HEX] = DEZENA [DEC] ; UNIDADE [DEC]
;*********************************************************************
; OBS: esta rotina recebe um argumento passado pelo Work e retorna nas variáveis
; Dezena e Unidade o número BCD correspondente ao parâmetro passado
AJUSTE_DECIMAL
 CLRF UNIDADE ; RESETA REGISTRADOR UNIDADE
 CLRF DEZENA ; RESETA REGISTRADOR DEZENA
MOVWF AUX ; SALVA VALOR A CONVERTER EM AUX
MOVF AUX, F ; VALOR A CONVERTER = 0?
BZ $+.18 ; SIM = RETORNA
INCF UNIDADE, F ; NÃO = INCREMENTA UNIDADE
MOVF UNIDADE, W 
XORLW 0X0A ; UNIDADE = 10d?
BNZ $+.6 ; NÃO
CLRF UNIDADE ; SIM = RESETA UNIDADE
INCF DEZENA, F ; INCREMENTA DEZENA
DECFSZ AUX, F ; FIM DA CONVERSÃO?
BRA $-.14 ; NÃO = VOLTA P/ CONTINUAR CONVERSÃO
RETURN ; SIM
;*********************************************************************
; ROTINA DE DIVISÃO Double Precision Division 
; ACCb (16 bits), ACCa (16 bits)
; ACCb with Reminder in ACCc (16 bits)
21
UNIDADE Programação em Linguagem Assembler e C++Arduino
;*********************************************************************
D_divF
 MOVLW .16
 MOVWF temp ; CARREGA CONTADOR PARA DIVISÃO
 
 MOVFF ACCbHI, ACCdHI
 MOVFF ACCbLO, ACCdLO ; SALVA ACCb M ACCd
 CLRF ACCbHI
 CLRF ACCbLO ; LIMPA ACCb
 
 CLRF ACCcHI
 CLRF ACCcLO ; LIMPA ACCc
DIV
 BCF STATUS, C
 RLCF ACCdLO, F
RLCF ACCdHI, F
 RLCF ACCcLO, F
RLCF ACCcHI, F
 MOVF ACCaHI, W
 SUBWF ACCcHI, W ; CHECAR SE a > c
 BTFSS STATUS, Z
 BRA NOCHK
 MOVF ACCaLO, W
 SUBWF ACCcLO, W ;SE MSB IGUAL ENTÃO CHECAR LSB
NOCHK 
 BTFSS STATUS, C ; SETA O CARRY SE c>a
 BRA NOGO
 MOVF ACCaLO, W ; c-a em c
 SUBWF ACCcLO, F
 BTFSS STATUS, C
 DECF ACCcHI, F
 MOVF ACCaHI, W
 SUBWF ACCcHI, F
 BSF STATUS, C ; Muda um 1 dentro de b (resultado)
NOGO
 RLCF ACCbLO, F
 RLCF ACCbHI, F
 DECFSZ temp, F ; FIM DA DIVISÃO?
 BRA DIV ; NÃO = VOLTA PARA DIV
 RETURN ; SIM = RETORNA
;*********************************************************************
; CONFIGURAÇÕES INICIAIS DE HARDWARE E SOFTWARE
; INCIALIZAÇÃO DAS PORTAS DE ENTRADA/SAÍDA DO MICROCONTROLADOR 
22
23
;ATRAVÉS DOS REGISTRADORES ESPECIAIS (SFR)
;*********************************************************************
; OBS: Coloca todas as saídas em nível Zero através do comando CLRF
CONFIGURACAO
 CLRF PORTA
 CLRF PORTB
 CLRF PORTC
 CLRF PORTD
 CLRF PORTE
 CLRF LATA
 CLRF LATB
 CLRF LATC
 CLRF LATD
 CLRF LATE
 
 MOVLW B’11111111’
 MOVWF TRISA ; CONFIGURA I/O DO PORTA
 MOVLW B’11111111’
 MOVWF TRISB ; CONFIGURA I/O DO PORT B
 MOVLW B’11111111’
 MOVWF TRISC ; CONFIGURA I/O DO PORT C
 MOVLW B’00000000’
 MOVWF TRISD ; CONFIGURA I/O DO PORT D
 MOVLW B’00000100’
 MOVWF TRISE ; CONFIGURA I/O DO PORT E
 MOVLW B’11011000’
 MOVWF T0CON ; CONFIGURA TIMER 0
 ; TIMER 0 INCREM. PELO CICLO DE MAQ. TIMER0 – 1:1
MOVLW B’00000000’
 MOVWF INTCON ;DESABILITA TODAS AS INTERRUPÇÕES
MOVLW B’00000000’ ;CONFIGURA CONVERSOR AD 
 MOVWF ADCON2 ; VELOCIDADE ->Fosc/8
 ; JUSTIFICADO À ESQUERDA
 ; 8 BITS EM ADRESH E 2 BITS EM ADRESL
 ; TEMPO AQUISICAO CAPACITOR POR SOFTWARE 
 
23
UNIDADE Programação em Linguagem Assembler e C++Arduino
MOVLW B’00001101’ ;CONFIGURA CONVERSOR AD 
 MOVWF ADCON1 ; RA0 e RA1 ENTRADAS ANALÓGICAS
 ; RA2, RA3, RA4 E RA5 I/O DIGITAIS
 ; PORTB E PORTE COMO I/O DIGITAL
 ; Vref+ = +Vdd(+5V)
 ; Vref- = GND (0V)
MOVLW B’00000101’ ;CONFIGURA CONVERSOR AD 
 MOVWF ADCON0 ; CANAL 1
 ; MODULO LIGADO
; As instruções a seguir fazem com que o microcontrolador trava quando houver um
; RESET ou POWER-UP, mas passe direto se o RESET for por Watchdog timer (WDT). 
;Desta forma,sempre que o PIC for ligado, o microcontrolador trava, 
;aguarda um estouro de WDT e começa novamente. Isto evita problemas no start-up.
 BTFSC RCON, NOT_TO ; RESET POR ESTOURO DE WDT
 BRA $ ; NÃO = AGUARDA ESTOURO WDT
 ; SIM
;*********************************************************************
; INICIALIZAÇÃO DA RAM
;*********************************************************************
; OBS: Esta rotina limpará toda a RAM. Do Banco 0 até o Banco 15
 LFSR FSR, 0X00 ; APONTA FSR0 PARA O ENDEREÇO 0
LIMPA_RAM
 CLRF POSTINC0 ; LIMPA A POSIÇÃO E INCREMENTA FSR0
 CLRWDT ; LIMPA O WATCHDOG TIMER
 MOVLW 0X0F ; TESTA SE JÁ CHEGOU AO BANCO 15
 SUBWF FSR0H, W ;
 BNZ LIMPA_RAM ; SE NÃO, CONTINUA LIMPANDO
 
;*********************************************************************
; CONFIGURAÇÕES INICIAIS DO DISPLAY LCD
;*********************************************************************
; OBS: Esta rotina inicializa o LCD p/ comunicação 8 vias. configurando 2 Linhas, 
cursor apagado e
; deslocamento do cursos para a direita
INICIALIZACAO_DISPLAY
 BCF RS ; SELECIONA DISPLAY PARA COMANDOS
 
 MOVLW 0X30 ; ESCREVE COMANDO 0X30 PAR
 RCALL ESCREVE ; INICIALIZAÇÃO
 
24
25
 MOVLW .3
 RCALL DELAY_MS ; DELAY DE 3MS (EXIGIDO PELO DISPLAY)
 
 MOVLW 0X30 ; ESCREVE COMANDO 0X30 PARA
 RCALL ESCREVE ; INICIALIZAÇÃO
 
 MOVLW 0X30 ; ESCREVE NOVAMENTE COMANDO 0X30 PARA
 RCALL ESCREVE ; INICIALIZAÇÃO
 MOVLW B’00111000’ ; ESCREVE COMANDO PARA INTERFACE DE
 RCALL ESCREVE ; 8 VIAS DE DADOS
 MOVLW B’00000001’ ; ESCREVE COMANDO PARA LIMPAR
 RCALL ESCREVE ; TODO O DISPLAY
 MOVLW .1
 RCALL DELAY_MS ; DELAY DE 1MS (EXIGIDO PELO DISPLAY)
 MOVLW B’00001100’ ; ESCREVE COMANDO PARA 
 RCALL ESCREVE ; LIGAR O DISPLAY SEM O CURSOR
 MOVLW B’00000110’ ; ESCREVE COMANDO PARA INCREMENTAR
 RCALL ESCREVE ; AUTOMATICO À DIREITA
 BSF RS ; SELECIONA O DISPLAY PARA DADOS
;*********************************************************************
; ROTINA PARA A ESCRITA DA TELA INICIAL
;*********************************************************************
; OBS: Esta rotina escreve nas duas respectivas linhas do display as seguintes 
palavras:
; LINHA 1: “AD Int (P2) “
; LINHA 2: Volts “
 MOVLW 0X81 ; COMANDO PARA POSICIONAR O CURSOR
 RCALL ESCREVE ; NA LINHA 0 / COLUNA 1
 BSF RS ; SELECIONA O DISPLAY PARA DADOS
 MOVLW ‘A’ 
 RCALL ESCREVE
MOVLW ‘/’ 
 RCALL ESCREVE
MOVLW ‘D’ 
 RCALL ESCREVE
25
UNIDADE Programação em Linguagem Assembler e C++Arduino
 
 MOVLW ‘ ’ 
 RCALL ESCREVE
MOVLW ‘I’ 
 RCALL ESCREVE
MOVLW ‘n’ 
 RCALL ESCREVE
MOVLW ‘t’ 
 RCALL ESCREVE
MOVLW ‘.’ 
 RCALL ESCREVE
MOVLW ‘ ’ 
 RCALL ESCREVE
MOVLW ‘ ’ 
 RCALL ESCREVE
MOVLW ‘ ( ’ 
 RCALL ESCREVE
MOVLW ‘P’ 
 RCALL ESCREVE
MOVLW ‘2’ 
 RCALL ESCREVE
MOVLW ‘)’ 
 RCALL ESCREVE
BCF RS ; SELECIONA O DISPLAY PARA COMANDOS
 MOVLW 0XC7 ; COMANDO PARA POSICIONAR O CURSOR
 RCALL ESCREVE ; NA LINHA 1 COLUNA 7
 BSF RS ; RETORNA CONFIG. DISPLAY PARA DADOS
MOVLW ‘V’ 
 RCALL ESCREVE
MOVLW ‘o’ 
 RCALL ESCREVE
MOVLW ‘l’ 
 RCALL ESCREVE
MOVLW ‘t’ 
 RCALL ESCREVE
MOVLW ‘s’ 
 RCALL ESCREVE
;*********************************************************************
; LOOP PRINCIPAL DO PROGRAMA
;*********************************************************************
26
27
LOOP
 CLRWDT ; LIMPA O WDT
 BSF ADCON0, GO ; INICIA A CONVERSAO AD
 BTFSC ADCON0, GO ; FIM DA CONVERSAO?
 BRA $-.2 ; NÃO = VOLTA 1 INSTRUÇÃO
 ; SIM
 MOVF ADRESH, W ; SALVA VALOR DA CONVERSÃO NO WORK
 MULLW .50 ; MULTIPLICA VALOR DO AD POR 50
 MOVFF PRODH, ACCbHI ; CARREGA ACCb C/ RESULTADO DA MULT
 MOVFF PRODL, ACCbLO ; (NUMERADOR)
 CLRF ACCaHI ; CARREGA ACCa COM 255d (Fundo de escala do
 MOVLW .255 ; CONVERSOR AD 8 BITS, JUSTIFICADO A ESQUERDA
 MOVWF ACCaLO ; (DENOMINADOR)RCALL D_divF ; CHAMA ROTINA DE DIVISÃO
 
 MOVF ACCbLO, W ; FAZ AJUSTE DECIMAL DO RESULT. DIVISÃO
 RCALL AJUSTE_DECIMAL ; PARA MOSTRAR NO DISPLAY LCD
 
BCF RS ; SELECIONA O DISPLAY PARA COMANDOS
 MOVLW 0XC3 ; COMANDO PARA POSICIONAR O CURSOR
 RCALL ESCREVE ; NA LINHA 1 COLUNA 3
 BSF RS ; RETORNA CONFIG. DISPLAY PARA DADOS
 MOVF DEZENA, W
 ADDLW 0X30 ; CONVERTE BCD DA DEZENA EM ASCII
 RCALL ESCREVE ; ENVIA AO LCD
 MOVLW ‘,’ ; ESCREVE UMA VÍRGULA
 RCALL ESCREVE ; NO LCD
 MOVF UNIDADE, W
 ADDLW 0X30 ; CONVERTE BCD DA UNIDADE EM ASCII
 RCALL ESCREVE ; ENVIA AO LCD
 BRA LOOP ; VOLTA PARA O LOOP
;*********************************************************************
; FIM DO PROGRAMA
;*********************************************************************
 END ; FIM
27
UNIDADE Programação em Linguagem Assembler e C++Arduino
Capítulo 3 – Programação 
C/C++ para Arduino
Neste Capítulo você aprenderá um pouco de Programação C/C++ utilizada nas 
Plataformas Arduino.
Primeiramente, é importante justificar ao leitor o porquê da escolha de um novo 
microcontrolador para a explicação da programação C/C++, quando seria possível 
ter escolhido, novamente, a plataforma PIC® para microcontroladores. 
Como este Curso é introdutório e com ele se pretende apresentar um pouco 
dos principais recursos disponíveis para iniciar trabalhos com microcontroladores 
e microprocessadores. Portanto, basta o domínio dos conceitos iniciais de uma 
Linguagem e um fabricante que, com um pouco de estudo sobre os tutoriais e dicas 
disponíveis nos sites dos demais fabricantes e na Internet, o leitor pode, facilmen-
te, adaptar-se às modificações necessárias e evoluir numa ou noutra linguagem e 
microcontrolador ou microprocessador escolhido.
O Arduino é, hoje, uma das principais plataformas de Código Aberto utilizada 
em todo o mundo. Surgiu em meados de 2005, desenvolvida por professores e uni-
versitários de uma Universidade italiana para auxiliar no ensino de eletrônica, e se 
difundiu entre os amantes de eletrônica, hobistas e afins. O objetivo principal sem-
pre foi que o Arduino fosse uma plataforma de baixo custo e acessível para todos.
Antes de galgar os primeiros passos na Linguagem C/C++ para Arduino, é 
preciso enfatizar que, assim como no C/C++ os comentários podem ser feitos 
colocando duas barras de divisão (//) na frente da frase comentário ou destacando 
um parágrafo inteiro como comentário ao se introduzir “/*” no início do parágrafo 
e, após a última palavra ou após o ponto final do parágrafo, coloca-se “*/” para 
simbolizar que o parágrafo de comentário foi finalizado.
Introdução ao Arduino
A Plataforma Arduino é formada, principalmente, pelo Hardware e pelo Software.
O hardware é composto por uma Placa Eletrônica que facilita a programação 
e a utilização do microcontrolador; ela pode ser facilmente adquirida em sites de 
e-commerce, a partir da qual são construídos os projetos.
O software para programação do microcontrolador do Arduino (o microcon-
trolador base do ArduinoOne® é um microcontrolador ATMEGA328) é uma IDE, 
que é executado num computador no qual é feita a programação baseada em lin-
guagem C/C++.
Os programas desenvolvidos para Arduino são, costumeiramente, chamados 
pela comunidade de sketch.
28
29
Terminado um Sketch, deve ser feito o upload para a placa do Arduino, por 
meio de uma comunicação serial previamente configurada via software.
O sketch feito pelo projetista dirá à Placa o que deve ser executado durante o seu 
funcionamento, assim como qualquer outro Programa desenvolvido em qualquer 
outra Linguagem para microcontroladores e microprocessadores.
Existem diversas placas oficiais de Arduino e muitas outras cópias não oficiais; 
mas como o Código é Aberto, diga-se de passagem, que são adaptações projetadas 
e atualizadas pela comunidade.
Para efeitos introdutórios deste Curso, serão abordados aqui conceitos de 
programação da placa Arduino Uno REV3:
Figura 4 – Placa Arduino UMO
Fonte: site do fabricante – <https://store.arduino.cc/usa/arduino-uno-rev3>.
Essa placa possui diversos conectores que servem de interface para os demais 
componentes eletrônicos do Circuito Eletrônico do Projeto; possui 14 pinos de 
entrada e/ou saída digital (pinos 0 a 13), cuja finalidade pode ser programada de 
acordo com a necessidade do projeto e conforme definido no sketch criado na IDE 
do Arduino.
Possui, ainda, 6 pinos de entradas analógicas (pinos A0 a A5), que são dedicados 
a receber valores analógicos, por exemplo, a tensão de um sensor de temperatura. 
O valor a ser lido deve estar na faixa de 0 a 5 V, para esse tipo de placa, na qual 
serão convertidos para valores entre 0 e 1023, já que o padrão de conversão é de 
10 bits. Apresenta, também, 6 pinos de saídas analógicas (pinos 3, 5, 6, 9, 10 
e 11), pinos digitais que podem ser programados para ser utilizados como saídas 
analógicas, utilizando modulação PWM.
A alimentação da Placa pode ser feita a partir da porta USB do computador ou 
através de uma fonte DC externa.
No software para programação do Arduino, quando pressionado o botão 
upload da IDE, o Código Escrito é traduzido para a Linguagem C e é transmitido 
para o compilador avr-gcc, que realiza a tradução dos comandos para uma Lingua-
gem que pode ser compreendida pelo microcontrolador ATMEGA328 da Placa.
29
UNIDADE Programação em Linguagem Assembler e C++Arduino
A IDE possui uma Linguagem própria baseada na linguagem C e C++. 
Um ciclo de programação do Arduino pode ser dividido da seguinte maneira:
• Conexão da placa a uma porta USB do computador;
• Desenvolvimento de um sketch com comandos para a placa;
• Upload do sketch para a placa, utilizando a comunicação serial USB;
• Aguardar a reinicialização; em seguida, ocorrerá à execução do sketch criado.
A partir do momento que foi feito o upload do firmware, a Placa não necessita 
mais estar conectada ao computador; o Arduino executará o sketch criado, desde 
que seja ligado a uma fonte de energia externa ou bateria.
A IDE pode ser baixada gratuitamente no site do Arduino, no qual pode ser 
escolhida a melhor opção de download conforme a Plataforma utilizada.
Quando se abre o IDE do Arduino, será exibido algo semelhante à Figura a seguir:
Figura 5 – Tela de um Sketch de Arduino
Fonte: elaborada pelo próprio autor.
O IDE é dividido em três partes: a Toolbar no topo, o Código ou a Sketch 
Window no centro, e a janela de mensagens na base, conforme exibido na Fi-
gura anterior.
Na Toolbar, há uma guia, ou um conjunto de guias, com o nome do sketch. 
Ao lado direito, há um botão que habilita o serial monitor. No topo, há uma barra 
de menus, com os itens File, Edit, Sketch, Tools e Help. Os botões na Toolbar 
fornecem acesso rápido às funções mais utilizadas dentro desses menus.
30
31
Após a conexão do Arduino ao computador, é atribuída à placa uma porta 
COM de comunicação. A primeira vez que o programa Arduino for executa-
do, deve-se selecionar o modelo de Placa utilizado; nesse caso, deve-se escolher 
Arduino Uno, conforme a Figura 6 a seguir:
Figura 6 – Tela de seleção de modelo de placa Arduino
Fonte: elaborada pelo próprio autor.
Após a definição do modelo, deve-se selecionar em qual porta serial a placa se 
comunicará com o computador.
Após estas configurações, o ambiente está preparado para uso e se pode 
testar qualquer um dos exemplos que acompanham a IDE ou, até mesmo, um 
novo sketch.
Uma das principais facilidades da plataforma Arduino são os exemplos pré-
disponíveis que podem ser acessados por meio do Menu File >Examples.
Esses exemplos trazem desde o mais simples programas C/C++ de um pica-
pisca de led (Sketch denominado Blink), até exemplos mais complexos para 
transmissão de dados Wi-Fi e programação para display TFT, entre outros.
31
UNIDADE Programação em Linguagem Assembler e C++Arduino
Programações mais complexas como, por exemplo, programação para controle 
PID de aquecimento, podem ser acessados após a instalação dabiblioteca específica 
no site do próprio fabricante.
Outra facilidade é que, devido ao seu Código Aberto, praticamente, todas as 
placas similares desenvolvidas pela comunidade de Arduino são compatíveis e 
utilizam o mesmo compilador para programar seu microcontrolador.
O exemplo mais simples para iniciar a programação do Arduino consiste em 
acionar um LED por meio de uma saída digital. A placa Arduino Uno já possui 
um Led ligado ao pino digital 13, que pode ser utilizado para o teste, e na IDE é 
possível carregar o exemplo Blink:
Figura 7 – Tela de seleção de exemplos padrão do Arduino
Fonte: elaborada pelo próprio autor.
Exemplo 1: Pisca Led Padrão do Arduino (Blink)
Este exemplo padrão denominado Blink é um Código exemplo de domínio 
público que já acompanha o compilador do Arduino.
Ele serve para ligar um LED durante 1 segundo e o mantém desligado por mais 
1 segundo, repetidamente; ou seja, é como um pisca pisca de frequência de ope-
ração 1 Hz.
Muitos Arduinos já têm na placa um LED padrão que pode ser controlado 
digitalmente.
Nas placas UNO, MEGA e ZERO, o LED padrão está conectado à saída digital 
pino 13; na MKR1000, está conectado ao pino 6.
32
33
As novas versões dos compiladores, para evitar problemas com a diferença de 
pinagem, introduziram um comando padrão denominado LED_BUILTIN, que já 
configura a Placa para o pino correto do seu LED padrão, conforme a respectiva 
Placa utilizada. O exemplo a seguir já utiliza esse novo comando:
*/
// A função setup roda apenas quando é pressionado o botão reset ou a 
placa é ligada
void setup() 
{
 // inicializa o pino digital LED_BUILTIN como saída digital.
pinMode(LED_BUILTIN, OUTPUT);
}
void loop()
{ //A função Loop é executada a cada ciclo de varredura do 
microcontrolador
 digitalWrite(LED_BUILTIN, HIGH); // Ativa a saída LED em 
nível alto (+5V)
 delay(1000); // espera 1000 milissegundo (1s)
 digitalWrite(LED_BUILTIN, LOW); // Desliga Led colocando 
saída em GND
 delay(1000); // Espera 1 segundo
} 
Para verificar se o código está correto, pode-se clicar no ícone verify (cujo 
símbolo é semelhante a um V de check). Em seguida à verificação da compilação, 
exibe-se uma mensagem de status da operação e, caso esteja tudo certo, será 
exibida a quantidade de bytes gerados pelo programa.
Para gravar o código na memória flash do microcontrolador, é necessário clicar 
no ícone Upload; será transferido o Código para a Placa e após alguns segundos o 
LED ligado ao pino 13 começará a piscar em intervalos de 1 segundo.
O código do exemplo Blink é relativamente simples; porém, apresenta a estru-
tura básica de um programa desenvolvido na IDE Arduino. Inicialmente, nota-se 
que existem duas funções obrigatórias em um programa Arduino, setup() e loop().
A função setup () é executada na inicialização do Programa e é responsável 
pelas configurações iniciais do microcontrolador, tal como, definição dos pinos de 
I/O e inicialização da comunicação serial, entre outras.
33
UNIDADE Programação em Linguagem Assembler e C++Arduino
A função loop () será aquela em que ocorrerá o laço infinito da programação, 
ou seja, em que será inserido o Código que será executado continuamente pelo 
microcontrolador, a cada ciclo de varredura.
Dentro do loop principal, está o Código que fará o led ligado pino 13 piscar em 
intervalos de 1 segundo.
A função digital Write (led, HIGH) coloca o pino em nível lógico 1, ligando o led.
A função delay (1000) aguarda o tempo de 1000 ms, ou seja, 1 segundo para 
que possa ser executada a próxima instrução.
A função digital Write (led, LOW) coloca o pino em nível lógico 0, desligando o led.
E novamente é esperado 1 segundo com a função delay ();
O loop é repetido infinitamente, enquanto a Placa estiver ligada.
Testar outros exemplos básicos é um bom começo para aprender mais sobre 
a plataforma.
Exemplo 2: Exemplo PWM com Arduino
Pode-se implementar, manualmente, a geração de um sinal PWM em qualquer 
uma das saídas digitais do Arduino. Para isso, basta alternar os níveis alto e baixo 
intercalando os tempos desejados para a geração do PWM, conforme o exemplo 
a seguir:
void setup() 
{ 
 pinMode(13, OUTPUT); // Utiliza a saída 13 da placa. Como na saída 
13 já 
// existe um LED instalado, isto permite visualizar
// o pulso PWM gerado; mas para outras aplicações
// recomenda-se usar outro pino digital disponível. 
} 
 
void loop() 
{ 
 digitalWrite(13, HIGH); 
 delayMicroseconds(100); // 10% duty cycle , freq 1KHz 
 digitalWrite(13, LOW); 
 delayMicroseconds(1000 - 100); 
}
34
35
Alguns microcontroladores Arduino, como o ATmega328P, já têm três timers, 
conhecidos como Timer 0, Timer 1 e Timer 2. Cada um deles têm saídas com 
comparadores que controlam a largura de pulso do PWM para as outras duas sa-
ídas de timer: quando o temporizador atinge o valor do registro de comparação, 
a saída correspondente é alternada. As duas saídas para cada temporizador, nor-
malmente, terão a mesma frequência, mas podem ter ciclos de trabalho diferentes 
(dependendo do respectivo registro de comparação de saída).
Cada um dos temporizadores gera o relógio do temporizador, dividindo o relógio 
do Sistema por um fator de pré-escala como 1, 8, 64, 256 ou 1024. 
O Arduino possui um relógio do Sistema de 16MHz e a frequência do relógio 
do temporizador será a frequência do relógio do Sistema dividida pelo fator de pré-
escala.
Observe que o Timer 2 possui um conjunto diferente de valores de pré-escala 
dos outros temporizadores.
Os principais modos PWM são “Fast PWM” e “PWM de fase corretiva”. O tem-
porizador pode ser executado de 0 a 255 ou de 0 a um valor fixo. (O temporizador 
1 de 16 bits possui modos adicionais para suportar valores de temporização de até 
16 bits).
Cada saída também pode ser invertida. Os temporizadores também podem gerar 
interrupções em excesso e/ou emparelhar contra qualquer registro de comparação 
de saída, mas isso está além do escopo deste Curso. Registros de temporizador são 
usados para controlar cada temporizador.
Os Registros de Controle Temporizador/Contador TCCRnA e TCCRnB man-
têm os bits de controle principais para o temporizador (Observe que TCCRnA e 
TCCRnB não correspondem às saídas A e B.) Esses registros possuem vários gru-
pos de bits:
• Bit de modo de geração de forma de onda (WGM): controla o modo geral 
do temporizador (esses bits são divididos entre TCCRnA e TCCRnB);
• Seletor de Relógio (CS): controla a pré-escala do relógio; 
• Comparador da saída A (COMnA): ativa/desativa/inverte a saída A;
• Comparador da saída B (COMnB): ativa/desativa/inverte a saída B.
• Os comparadores OCRnA e OCRnB: define os níveis em que as saídas A e B 
serão afetadas. Quando o valor do temporizador corresponde ao valor do regis-
tro, a saída correspondente será modificada conforme especificado pelo modo.
Os bits são ligeiramente diferentes para cada temporizador; então, consulte a 
folha de dados para obter detalhes.
35
UNIDADE Programação em Linguagem Assembler e C++Arduino
Timer 1 é um temporizador de 16 bits e tem modos adicionais. O temporizador 
2 possui diferentes valores de preconceito.
No modo PWM mais simples, o temporizador conta, repetidamente, de 0 a 
255. A saída é ativada quando o temporizador está em 0 e se desliga quando o 
temporizador corresponde ao registro de comparação de saída. Quanto maior o 
valor no registro de comparação de saída, maior o ciclo de trabalho. Esse modo é 
conhecido como modo PWM rápido.
Já no modo PWM Rápido, que exemplifica o seguinte fragmento de código, 
configura-se o PWM rápido nos pinos 3 e 11 (Temporizador 2).
Para resumir as configurações de registro, definir os bits de modo de geração 
de Forma de Onda WGM para saída 11 seleciona PWM rápido. Definir os bits 
COM2A e os bits COM2B para 10 fornece PWM não invertido para as saídas A 
e B. Configurando os bits CS para 100 define o prescaler para dividir o relógio 
em 64 (vez que os bits são diferentes para os diferentes temporizadores, consulteo datasheet para os valores corretos.) 
Os registros de comparação de saída são arbitrariamente configurados para 180 
e 50 para controlar o ciclo de trabalho PWM das saídas A e B, mas, podem-se 
modificar os registros diretamente, em vez de usar pinMode, mas, para isso, é 
preciso configurar os pinos para a saída.
As linhas de código a seguir permitem a programação de uma PWM modo 
rápido, utilizando os timer e comparadores do Arduino:
//Exemplo PWM rápido para Arduino
pinMode(3, OUTPUT);
pinMode(11, OUTPUT);
TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
TCCR2B = _BV(CS22);
OCR2A = 180;
OCR2B = 50;
Para outros exemplos de Programação C/C++ para Arduino ou PIC e até 
mesmo outros microcontroladores e microprocessadores, recomenda-se acessar 
os tutorias indicados em Material Complementar ou sites de Eletrônica, disponíveis 
na Internet.
36
37
Material Complementar
Indicações para saber mais sobre os assuntos abordados nesta Unidade:
 Sites
Arduino
Acesse outros Materiais Complementares e Tutoriais para Arduino.
https://www.arduino.cc
Sparkfun
Site de compras que contém esquemáticos de circuitos e exemplos de programas para 
microcontroladores.
https://www.sparkfun.com/
 Vídeos
Gerando PWM com os Comparadores | Assembly para PIC #062
https://youtu.be/FCzLQ0y1CLc
 Leitura
Secrets of Arduino PWM
Acesse Material Complementar sobre PWM para Arduino.
https://goo.gl/B0LCb4
37
UNIDADE Programação em Linguagem Assembler e C++Arduino
Referências
MCROBERTS, Michael. Arduino básico. São Paulo: Novatec, 2011. v.1.
MIYADARIRA, N. A.; MICROCONTROLADORES, PIC18: Aprenda a Programar 
em Linguagem C. São Paulo: Érica, 2009.
SOUSA, Daniel Rodrigues de; SOUZA, David José de; LAVINIA, Nicolás César. 
Desbravando o Microcontrolador PIC18 – Recursos Avançados. São Paulo: 
Érica, 2010.
38

Continue navegando