Você está na página 1de 25

SISTEMAS MICROCONTROLADOS

PROF. MATHEUS
CAPÍTULO 1

MICROCONTROLADORES

1. PARA QUE SERVEM OS MICROCONTROLADORES

O microcontrolador é um “pequeno componente eletrônico”, dotado da capacidade de controlar


processos lógicos, mediante programação inteligente.

O controle de processos é entendido com o controle de periféricos, tias como leds, botões, displays,
relés, sensores diversos e outros. São chamados de controles lógicos, pois a operação do sistema se
baseia nas ações. Lógicas que devem ser executadas, dependendo do estado dos periféricos de entrada
e/ou saída.

O microcontrolador é programável, pois toda a lógica de operação é estruturada de forma que um


programa é gravado dentro do componente. Depois disto, toda vez que o microcontrolador for alimentado, o
programa interno será executado.

Quanto à “inteligência” do componente, é associada à sua Unidade Lógica e Aritmética (ULA), onde
todas as operações matemáticas e lógicas são desenvolvidas. Quanto mais poderosa for essa ULA, maior a
capacidade do componente em processar as informações.

O microcontrolador também é chamado “pequeno”, porque em uma única pastilha de silício há


todos os componentes necessários ao controle de um processo, ou seja, o microcontrolador está provido de
memórias, portas de entrada/saída, timers, contadores, comunicação e outros dispositivos capazes de lhe
dar funcionamento autônomo. Esta é uma das características fundamentais que o diferencia dos
microprocessadores. Estes últimos, apesar de possuírem uma ULA mais poderosa, não têm todos estes
recursos em uma única pastilha.

Como exemplos de aplicação, muitos equipamentos usam microcontoladores: eletrodomésticos,


alarmes, celulares, brinquedos e outros equipamentos de uso diário.

Esta apostila abordará os microcontroladores PIC (Peripherical Interface Controllers), do fabricante


Microchip.

2. A ARQUITETURA HAVARD E A FILOSOFIA RISC

Os microcontroladoes PIC apresentam uma estrutura de máquina interna do tipo Havard, enquanto
grande parte dos microcontroladores tradicionais têm uma arquitetura Von Neumann . A diferença está na
forma como os dados e o programa são processados pelo microcontrolador. Na arquitetura tradicional, Von
Neumann, há apenas um barramento interno (geralmente de 8 bits), por onde passam as instruções e os
dados. Já na arquitetura Havard, há dois barramentos internos, um de dados e outro de instruções; nos
microcontroladores PIC, o barramento de dados é sempre de 8 bits, enquanto o de instruções pode ser de
12, 14 ou 16 bits, dependendo do microcontrolador. Este tipo de arquitetura permite que, enquanto uma
instrução é executada, outra seja “buscada” da memória, o que torna o processamento mais rápido. Além
disto, como o barramento de instruções é maior que 8 bits, o opcode (código) da instrução já incluir o dado e
o local onde ela vai operar, o que significa que apenas uma posição de memória é armazenada por
instrução, economizando, assim, muita memória de programa.

Desta forma, dentro da palavra do opcode, que pode ser de 12, 14 ou 16 bits, não sobra muito
espaço para o código da instrução propriamente dito. Por esta razão, os PICS utilizam a tecnologia RISC,
(Reduced Instruction Set Computer – computador com conjunto de instruções reduzido). Os PIC possuem
cerca de 35 instruções, muito menos que os microcontroladores convencionais, que podem chegar a mais
de 100 instruções. Isto torna o aprendizado mais fácil e mais dinâmico, porém algumas funções devem ser
“construídas”, requerendo habilidade do programador.

3. A ESTRUTURA INTERNA

O diagrama mostrado na figura 1.1 é do microcontrolador PIC 16F628A.

Figura 1.1- Diagrama do PIC 16F628A

Este diagrama de blocos foi retirado da folha de dados original do fabricante e mostra as diversas
partes que compõem o microcontrolador. Para exemplificar, a ULA está diretamente ligada ao registrador W
(work register – registrador de trabalho). No canto superior esquerdo, há a memória de programa, da qual
sai um barramento de 14 bits. Mais ao centro, está a memória RAM, que possui um barramento de 8 bits.
Na parte inferior, podem ser vistos os periféricos, como a EEPROM, os timers, o módulo CCP (Capture,
Compare e PWM) e a porta serial. Na parte superior, há ainda o program counter (contador de linha de
programa) e a pilha de 8 níveis (stack). À direta se visualizam os dois ports A e B (interface para
entrada/saída).
4 OS CICLOS DE MÁQUINA

Nos microcontroladores PIC, o sinal de clock é internamete dividido por 4. Portanto, se o clock
externo tem 4MHz, o interno terá 1MHz. Conseqüentemente, cada ciclo de máquina dura 1µs.

A divisão do clock por 4 forma as fases Q1, Q2, Q3 e Q4 da figura 1.2. O contador de programa é
incrementado automaticamente na fase Q1 do ciclo de máquina e a instrução seguinte é buscada da
memória de programa e armazenada no registrador de instruções no ciclo Q4. Ela é decodificada e
executada no próximo ciclo, no intervalo de Q1 a Q4. Esta característica de buscar a informação num ciclo e
executá-la no próximo é conhecida como pipeline. Ela permite que quase todas as instruções sejam
executadas em apenas um ciclo, gastando assim menos tempo e tornando o sistema muito mais rápido. As
únicas instruções se referem às instruções que geram “saltos” no programa, chamadas de rotinas e
retornos. Ao executar essas instruções, o pipeline deve ser primeiramente limpo e depois carregado
novamente com o endereço correto, consumindo para isso dois ciclos de máquinas. Esse pipeline é
facilmente implementado, devido à arquitetura Havard.

Figura 1.2 – Esquema dos ciclos de máquina.

5 EXERCÍCIOS PROPOSTOS

1. O que se entende por “programação inteligente”?


2. Qual a diferença entre microcontrolador e microprocessador?
3. Qual a diferença entre as arquiteturas Havard e Von Neumann e qual delas o PIC utiliza?
4. Explicar a filosofia RISC
5. O que é pipeline?
6. Se o PIC utilizar um cristal de 10MHz, qual será o clock interno?
CAPÍTULO 2

INTRODUÇÃO ÀS MEMÓRIAS

Devido à arquitetura Havard, o PIC possui barramentos diferenciados para as memórias de


programa e de dados. Essas memórias são totalmente separadas, havendo ainda uma terceira memória,
não volátil, a EEPROM

1 A MEMÓRIA DE PROGRAMA

A memória de programa pode ser de 12, 14 ou 16 bits. Ela pode ser de três tipos:

− EPROM, que pode ser gravada uma vez;

− EPROM programável, que pode ser gravada várias vezes mediante apagamento por luz ultra-violeta
(PIC janelados);

− modelos que têm memória de programa do tipo flash, que pode ser gravada várias vezes sem a
necessidade de apagar a gravação anterior.

O modelo que pode ser gravado uma única vez é mais barato, enquanto aquele que dispõe de
memória flash é mais caro.

VETOR DE RESET

É o primeiro endereço da memória que será executado quando o PIC começar a rodar, após a
alimentação ou um reset. Na maioria dos modelos, o reset aponta para o endereço 0x00.

VETOR DE INTERRUPÇÃO

As rotinas de interrupção serão armazenadas na área de programação, com todo o resto do


programa. Há um endereço reservado para o início do tratamento das interrupções, que é a posição 0x04.

PILHA (STACK)

É um local totalmente separado da memória de programa, onde são armazenados endereços de


retorno, quando utilizadas instruções como rotinas. Quando o programa é desviado para o começo de uma
rotina, o endereço seguinte ao ponto que estava sendo rodado é armazenado na pilha, para que, ao fim da
rotina, o programa possa retornar. O tamanho da pilha varia de acordo com o PIC, caso se tente chamar um
número de rotinas maior que o tamanho da pilha, endereços de retorno mais antigos serão perdidos.

2 A MEMÓRIA DE DADOS
A memória de dados é do tipo RAM, utilizada para guardar todas as variáveis e registradores
utilizados pelo programa. Armazena dados de 8 bits e é volátil, ou seja, quando o PIC é desligado, é
automaticamente perdida. Pode ser dividida em dois grupos, o que contém os registradores especiais e o
que contém os registradores de uso geral.

Muitas vezes, esta memória é dividida em mais de um banco, para possibilitar o acesso aos
endereços, com o auxílio de chaves que controlam o acesso ao banco que está sendo utilizado no
momento.

REGISTRADORES ESPECIAIS

Nesta seção da memódia de dados encontram-se estes registradores, denominados SFR (Special
Function Registers). São utilizados par a execução do programa e processamentos da ULA. Estes
registradores ocupam espaço na RAM e podem ser acessados da mesma maneira que as variáveis do
sistema, com mudança somente do endereço de acesso. Podem ser lidos ou escritos tanto pelo usuário
quando pelo hardware. A quantidade de SFR depende do modelo do PIC, os quais podem ocupar mais
deum banco.

REGISTRADORES DE USO GERAL

É uma área destinada ao armazenamento de variáveis definidas pelo usuário para serem escritas e
lidas pelo programa. O tamanho dessa memória varia de acordo com o modelo do PIC e pode ocupar mais
de um banco.

3 EEPROM

Esta memória é não volátil, ou seja, consegue manter as informações, mesmo sem alimentação. Há
modelos de PIC que contêm uma EEPROM interna e outros que devem acessar uma EEPROM externa por
meio dos barramentos I/O e mediante programação.

4 EXERCÍCIOS PROPOSTOS

1. Citar e explicar os tipos de memórias de programa existentes para PIC


2. O que são SFR?
3. O que são registradores de uso geral?
4. O que é pilha e para que ela serve?
5. Os dados armazenados na RAM são recuperados após um desligamento? Explicar.
6. Como é feito o acesso do PIC a uma EEPROM externa?
CAPÍTULO 3

INTRODUÇÃO ÀS INTERRUPÇÕES

Uma interrupção interrompe o programa imediatamente. Logo após, uma função específica, definida
pelo programador, é executada. Depois, o programa continua sendo executado do ponto em que estava.

Os modelos mais antigos de PIC, como 12C50X e 16C55 não têm interrupções. O foco deste
capítulo é para os modelos mais modernos, que dispõem deste recurso.

1 AS INTERRUPÇÕES EXISTENTES NO PIC

As interrupções são definidas em quatro grandes grupos:

INTERRUPÇÕES DE TIMERS

Estas interrupções acontecem sempre que os contadores de tempo interno TMR0 (timer 0), TMR1
(timer 1) e TMR2 (timer 2) estouram.

O TMR0 é de 8 bits; tem capacidade de contagem até 255 ou 0xFF. Então, estoura quando passar
de 0xFF para 0x00. O TMR1 é de 16 bits e estoura quando passa de 0xFFFF para 0x0000. O TMR2
também é de 8 bits, uma interrupção não acontece quando ele alcança o limite 0xFF, mas quanto atinge um
valor especificado no registrador especial PR2.

Este tipo de interrupção é utilizada normalmente para a contagem de tempo. Como pode acontecer
a qualquer momento, o programa deve garantir que o tempo seja contado. TMR0 e TMR1 podem ser
incrementados internamente pelo clock da máquina ou por um sinal externo. Neste caso, eles passam a ser
contadores de pulsos, podendo ser utilizados para outras finalidades.

INTERRUPÇÃO EXTERNA

É gerada por um sinal externo ligado a uma porta específica do PIC, que no caso é o pino RB0 (pino
0 do port B), uma vez configurado como entrada. Desta maneira, pode-se identificar e processar
imediatamente um sinal externo. Como aplicação, o reconhecimento do estado de um botão ou outro sinal
do sistema, que necessite de uma ação imediata.

INTERRUPÇÃO POR MUDANÇA DE ESTADO.

A interrupção externa vista acima funciona somente na borda de subida ou na descida, dependendo
de como foi configurada. A interrupção por mudança de estado acontece em ambos os casos e está ligadas
aos pinos RB4, RB5, RB6 e RB7 simultaneamente. Por isto, se estas portas forem configuradas como
entradas, a mudança de estado em qualquer uma delas irá gerar a interrupção. Exemplo de aplicação:
sincronismo com a rede de 60Hz, para controle de um tiristor ou sistema semelhante.

INTERRUPÇÃO DE FIM DE ESCRITA NA EEPROM

Para os PIC que possuem EEPROM, esta interrupção serve para detectar o final da rotina de escrita
nessa memória. Não é obrigatória para que a escrita funcione, mas como a escrita na EEPROM é mais
lenta, em alguns sistemas sua utilização pode ser necessária para evitar uma parada durante a escrita.
INTERRUPÇÃO DE COMPARADOR

O PIC 16F628A possui dois comparadores internos, que podem ser utilizados de forma totalmente
independente do programa, com acesso aos pinos como se fossem comparadores externos, ou de forma
mista. Neste último caso, o resultado da comparação poderá ser analisado pelo programa para tomar
decisões. Como exemplo, a interrupção do comparador pode ser utilizada para avisar o sistema quando
houve uma mudança de estado na resposta esperada proveniente da comparação.

INTERRUPÇÕES DE USART

O PIC 16F638A tem um sistema completo para comunicação serial tipo USART (Universal Serial
Assynchronus Receiver Transmitter). Este sistema possui duas interrupções para informar o programa
quando um dado foi recebido e quando a transmissão de outro dado foi concluída.

INTERRUPÇÃO DE CCP

O módulo CCP (Capture, compare e PWM) possui uma interrupção para informar ao programa uma
das duas opções possíveis: fim da captura ou fim da comparação . O módulo de captura pode ser usado
para contar o tempo no TMR1, entre duas mudanças de estado de uma estrada específica (T1CK1); isto
permite implementar a contagem de um tempo específico. O módulo de comparação pode ser utilizado para
comparar o valor de TMR1 com o do registrador especial CCPR1. Desta forma, pode-se criar timers
específicos ou monitorar a quantidade de pulsos na entrada relacionada ao timer 1 (T1CK1).

2 COMO TRATAR UMA INTERRUPÇÃO


Sempre que uma interrupção acontece, o programa guarda o endereço da próxima linha a ser
executada na pilha e descia a execução do programa para um endereço fixo na memória de programa.
Basta, então, escrever, a partir deste endereço (0x04) a rotina que irá reconhecer e tratar a interrupção
acontecida. Quando a rotina da interrupção terminar, o programa automaticamente volta ao ponto em que
estava antes da interrupção acontecer.

3 EXERCÍCIOS PROPOSTOS

1. O que é uma interrupção e como ela atua no programa?


2. O que determina a interrupção em cada um dos timers do PIC 16F628A?
3. O que é uma interrupção externa?
4. Quais são as interrupções existentes para comunicação serial?
5. Explicar as interrupções por captura e comparação, do módulo CCP.
6. Qual o endereço para o qual desvia o programa quando ocorre uma interrupção e como o programa
deve se comportar para tratar uma interrupção?
CAPÍTULO 4

OS PIC 16F628A E 16F877A

1 INTRODUÇÃO AOS COMPONENTES

O PIC 16F628A tem as seguintes características:

− 18 pinos, facilitando a montagem de hardwares experimentais;


− até 16 portas configuráveis como entrada ou saída e dois osciladores internos;
− 10 interrupções disponíveis (timers, externa, mudança de estado, EEPROM, Usart, CCP e comparador);
− memória de programação flash com 2048 palavras, permitindo a gravação do programa diversas vezes
no mesmo componente, sem a necessidade de apaga-lo por luz ultra-violeta;
− memória EEPROM (não volátil) interna de 128 bytes;
− recursos adicionais avançados: CCP, comparador interno e Usart;
− programação com 14 bits e 35 instruções.

Os componentes da família PIC possuem um conjunto de instruções bem parecido e mantêm


muitas semelhanças entre suas características básicas. Desta forma, o estudo para o PIC16F628A
possibilita a migração para outros modelos, quando necessário.

2 A PINAGEM DO PIC 16F628A

A figura 4.1 mostra o PIC16F628A com seus respectivos pinos:

Figura 4.1- Pinagem do PIC 16F628A

O PIC16F628A possui 16 pinos I/O em dois grupos denominados portas: porta A (ou port A) e porta
B (port B).
Os oito pinos do port A são designados como RA0, RA1, RA2, RA3, RA4, RA5, RA6 e RA7.
Quando multifuncionais, não podem ter estas funções usadas ao mesmo tempo; por exemplo, se RA5 é
usado como entrada/saída, a função MCLR (máster clear) externa é perdida.

Os 8 pinos do port B são designados como RB0 a RB7, podendo ser configurados como
entrada/saída ou como função especial.

A tabela a seguir mostra o número do pino com a descrição de suas funções:

n.º pino função tipo entrada tipo saída descrição


17 RA0 schmitt.trigger CMOS I/O digital bidirecional
AN0 Analógica - Entrada analógica para os comparadores
18 RA1 schmitt.trigger CMOS I/O digital bidirecional
AN1 Analógica - Entrada analógica para os comparadores
RA2 schmitt.trigger CMOS I/O digital bidirecional
1 AN2 Analógica - Entrada analógica para os comparadores
VREF - Analógica Saída de tensão de referência programável
RA3 schmitt.trigger CMOS I/O digital bidirecional
2 AN3 Analógica - Entrada analógica para os comparadores
CMP1 - CMOS Saída do comparador 1
RA4 schmitt.trigger CMOS I/O digital bidirecional
3 T0CK1 schmitt trigger - Entrada externa do contador TMR0
CMP2 - dreno aberto Saída do comparador 2
RA5 schmitt trigger - Entrada digital
4 schmitt trigger - Master clear (reset externo) O PIC só funciona com
MCLR este pino em nível 1
VPP - - Entrada para tensão de programação (13V)
RA6 schmitt trigger CMOS I/O digital bidirecional
15 OSC2’ - XTAL Saída para cristal externo
CLOUT - CMOS Saída com onda quadrada em ¼ da freqüência
imposta em OSC1 quando em modo RC. Equivale
aos ciclos de máquina internos
RA7 schmitt trigger CMOS I/O digital bidirecional
16 OSC1 XTAL - Entrada para cristal externo
CKLIN schmitt trigger - Entrada para osciladores externos (híbridos ou RC)
RB0 TTL CMOS I/O bidirecional com pull-up interno
6 INT schmitt trigger - Entrada para interrupção externa
RB1 TTL CMOS I/O bidirecional com pull-up interno
7 RX schmitt trigger - Recepção para comunicação USART assíncrona
DT schmitt trigger CMOS Via de dados para comunicação USART síncrona
RB2 TTL CMOS I/O bidirecional com pull-up interno
8 TX - CMOS Transmissão para comunicação USART assíncrona
CK schmitt trigger CMOS Via de clock para comunicação USART síncrona
9 RB3 TTL CMOS I/O bidirecional com pull-up interno
CCP1 schmitt trigger CMOS I/O para capture, compare e PWM
RB4 TTL CMOS I/O bidirecional com pull-up interno
10 Interrupção por mudança de estado
PGM schmitt trigger Entrada para programação em baixa tensão (5V)
11 RB5 TTL CMOS I/O bidirecional com pull-up interno
Interrupção por mudança de estado
RB6 TTL CMOS I/O bidirecional com pull-up interno
Interrupção por mudança de estado
12 T1OS0 - XTAL Saída para cristal externo para TMR1
T1CK1 schmitt trigger - Entrada externa do contador TMR1
schmitt trigger - Clock da programação serial (ICSP)
RB7 TTL CMOS I/O bidirecional com pull-up interno
Interrupção por mudança de estado
13 T1OS1 - XTAL Saída para cristal externo para TMR1
PGD schmitt trigger CMOS Data da programação serial (ICSP)
5 VSS Alimentação - Terminal negativo da alimentação
14 VDD Alimentação - Terminal positivo da alimentação

O PIC 16F628A é alimentado com tensão entre 3 e 5,5V. A corrente máxima em cada pino de
entrada ou saída é 25mA, sendo de 200mA o máximo para as duas portas.

3 MAPAS DAS MEMÓRIAS DO PIC 16F628A

A memória de programa está organizada como mostra a figuras 4.2:

0000h Vetor de reset

0004h Vetor de inicialização

Tipo: 14 bits
Uso geral Tamanho: 2048 palavras
Vetor de reset: 0000h
Vetor de interrup: 0004h
07FFh

Figura 4.2- Memória de programa

A memória de dados é vista na figura 4.3:


Figura 4.3- Memória de dados

4 O PIC 16F877

Quando se deseja um aplicação onde é necessária a utilização de mais pinos de entrada/saída e/ou o
programa requer mais que 2048 words, pode ser utilizado o PIC 16F877A.

Este PIC possui 4 ports, designados por port 0, port 1, port 2 e port3. Sua pinagem é mostrada na figura 4.4

Figura 4.4- Pinagem do PIC 16F877A

Para comparar com o PIF16F628A, segue uma tabela com as características principais do PIC 16F877A:

Características PIC 16F628A PIC16F877A


Frequência de Operação DC a 20MHz DC a 20MHz
Memória de Programa 2048 bytes 8192 bytes
Memória de dados RAM bytes 368 bytes
Memória de dados EEPROM 128 bytes 256 bytes
Terminais de I/O 16 33
Timers 2 de 8 bits;1 de 16 bits 2 de 8 bits;1 de 16 bits
CCP 2 2
ECCP 0 0
Comunicação USART SPI, USART, I2C
Comparador 2 2
Conversor AD 8 canais de 10 bits cada 8 canais de 10 bits cada

5 EXERCÍCIOS PROPOSTOS
1. Explicar o que acontece se o pino Master Clear for utilizado com nível lógico 0.
2. Se o programa conterá interrupções tratadas, pode ser escrito logo em seguida à posição de
memória 0000h? Explicar.
3. Explicar o que são os bancos da memória de dados.

CAPÍTULO 5

OS REGISTRADORES ESPECIAIS DO PIC 16F628A

1 REGISTRADORES GERAIS

STATUS E PCON

Servem para mostrar o estado da ULA, a forma do último reset, configurar o oscilador interno e a
página de programação atual, quando necessário.

O registrador STATUS está relacionado com operações matemáticas e lógicas e contém


informações sobre o estouro dos registradores C – carry e Z – resultados iguais a zero. Na subtração, o
carry trabalha com lógica invertida.

A função mais utilizada do registrador PCON diz respeito à escolha da freqüência do oscilador
interno, se 37kHz ou 4 MHz.

OPTION

Configura uma série de opções para operação do microntrolador, como a habilitação dos pull-ups do
port B, configurações do prescaler, do TMR0 e seleção da borda para interrupção externa. Nos programas,
ele é desginado com o OPPTION_REG.

INTCON, PIR1 e PIE1

Configuram e identificam todas as interrupções.

INTCON opera com as interrupções principais, que são o TMR0, interrupção externa e interrupção
por mudança de estado. Tem a chave geral (GIE) para configurar todas as interrupções.

PIR1 e PIE1 são responsáveis pelo gerenciamento das interrupções dos periféricos EEPROM,
comparadores, USART, CCP, TMR1 e TMR2

PCL e PCLATH

O PCL armazena os 8 bits menos significativos do program counter. Indicando a próxima linha do
programa que será executada no momento.

2 PORTAS

TRIS
São registradores para configurar as portas como entrada ou saída. Quando é colocado “1” em um
bit do TRIS, o pino a ele relacionado é configurado como entrada. Se o bit do TRIS é “0”, o pino respectivo é
configurado como saída. Para configurar o port A, deve ser utilizado o TRISA, assim como o TRISB para o
port B.

PORTS A e B

Cada bit dos ports pode ser referenciado como designado: RB0, RB1, etc. O estado das portas
(todos os bits) pode ser obtido em duas posições distintas da memória.

3 CONTADORES

TIMER0 (TMR0)

Contador de 8 bits que pode ser acessado diretamente na memória, tanto para leitura quando para
escrita. Seu incremento é automático e pode ser feito tanto pelo clock da máquina quanto por um sinal
externo.

TIMER1 (TMR1)

Contador de 16 bits, que pode ser acessado diretamente na memória, tanto para leitura como para
escrita. Pelo seu tamanho, é armazenado em dois endereços, TMR1H (parte alta) e TMR1L (parte baixa).
As configurações do timer1 são feitas através do registrados T1CON.

TIMER2 (TMR2)

Outro contador de 8 bits que pode ser acessado diretamente na memória, tanto para leitura quando
para escrita. É configurado através do registrador T2CON. O valor deste registrador é comparado com o de
PR2, para verificar se foi atingido o valor configurado neste último.

4 EEPROM
EEADR é o registrador que especifica o endereço especificado para leitura ou escrita. EEDATA
contém o dado que será lido ou escrito.

EECON1 e EECON2 são dois registradores responsáveis pela operação da EEPROM.

5 MÓDULO CCP
CCP1CON é o registrador responsável pela configuração do módulo CCP (captura, comparação e
PWM).

6 MÓDULO COMPARADOR
CMCON é o registrador utilizado para configurar os dois comparadores existentes.

7 MÓDULO TENSÃO DE REFERÊNCIA


A configuração deste módulo é obtida através do registrador VRCON, que é uma saída analógica
com 16 valores configuráveis por software.

8 MÓDULO USART

Sendo responsável pela recepção e transmissão de dados, TXSTA configura a transmissão, RCSTA
configura a recepção e SPBRG indica a configuração do baud rate. TXREG e RCREG são os buffers que
contém os dados para transmissão e recepção, respectivamente.

9 ENDEREÇAMENTO INDIRETO
FSR é um registrador onde pode ser escrito outro endereço de memória que será acessado
indiretamente. INDF é um espelho do endereço que será apontado pelo SFR.

10 EXERCÍCIOS PROPOSTOS

1. Qual o registrador que, relacionado com operações matemáticas, sinaliza o estouro de registradores?
2. Como devem ser configurados os bits do registrador TRISB se é desejado que os pinos 0, 1, 2 e 3 do
port B atuem como saída e os demais como entrada?
3. Deseja-se fazer uma contagem até 215 (decimal). Indicar o timer mais apropriado para esta contagem e
o registrador que indicará que a contagem chegou no valor desejado.
CAPÍTULO 6

INTRODUÇÃO À LINGUAGEM “C”

1. PALAVRAS RESERVADAS

Toda linguagem de programação possui um conjunto de palavras definidas para interpretação do


próprio compilador, sendo assim, essas palavras não deverão ser utilizas pelo usuário para outras
finalidades além das definidas pelo compilador.

Essas palavras são chamadas de reservadas e em linguagem C, temos as seguintes:

auto do goto signed unsigned


break double if sizeof void
case else int static volatile
char enum long struct while
const extern register switch
continue float return typedef
default for short union

2. IDENTIFICADORES

Os identificadores são nomes dados às funções, variáveis, constantes, etc e não devem conter
caracteres acentuados, espaços, ‘ç’ e devem sempre começar com uma letra ou o símbolo ’_’ que é tratado
como letra.

3 TIPOS DE DADOS

Os tipos de dados suportados pela linguagem C são identificados pela palavras reservadas: char,
int, float e void.

Tipo de dado Tamanho Intervalo


char 8 bits 0 a 255
Int 8 bits 0 a 255
float 32 bits 3.4 x 10-38 a 3.4 x 1038
void 0 0
O tipo char representa caracteres ASCII de 8 bits, sendo que cada variável do tipo char pode representar
somente um caracter ASCII.

O tipo int representa números inteiro de 16 bits.

O tipo float representa números fracionários de 32 bits, sendo que este tipo de dado deve ser evitado tendo
em vista o seu tamanho.

O tipo void é normalmente utilizado em funções para declarar que ela não deve retornar nenhum valor.

4 MODIFICADORES DE TIPO

Além dos tipos de dados acima, podemos utilizar comandos especiais para modificá-los e são
chamados de modificadores de tipo, sendo eles: signed, unsigned, short e long.

O modificador de tipo signed pode ser utilizado para representar um número positivo ou negativo,
assim um tipo de dado signed int pode representar valores de -127 a 128.

O modificador unsigned define um tipo de dado sem sinal, ou seja, somente a parte positiva de
uma variável, então o tipo de dados unsigned int representa valores de 0 a 255.

O modificador short é utilizada para definir um valor menor do que o tipo modificado, ou seja, ao
declaramos uma variável com o tipo short int, a variável tem seu tamanho reduzido para 1 bit.

O modificador long é o contrário, ou seja, amplia o tamanho de uma variável, então uma variável
declarada com o tipo de dado long int passa a ter o tamanho de 16 bits.

A tabela abaixo mostra todos os tipos de dados e seus modificadores:

Tipo Tamanho Valores


short int, int1, boolean 1 bit 0 ou 1
char 8 bits 0 a 255
signed char 8 bits -128 a 127
unsigned char 8 bits 0 a 255
int, int8, byte 8 bits 0 a 255
signed int, signed byte 8 bits -128 a 127
unsigned int, unsigned 8 bits 0 a 255
long int, int16 16 bits 0 a 65535
signed long int 16 bits -32768 a 32767
int32 32 bits 0 a 4294967295
signed int32 32 bits -2147483648 a 2147483647
unsigned int32 32 bits 0 a 4294967295
float 32 bits 3,4-38 a 3,438

5 VARIÁVEIS
As variáveis são uma representação simbólica onde são armazenados dados do programa ou
dados externos como uma tecla pressionada, um dado lido, etc. As variáveis podem conter letras e
números, sempre começando com letras e não devem ter nome de palavras reservadas pelo compilador.

Declarar uma variável é simplesmente informar ao compilador que uma variável chamada “X” é do
tipo “Y”, da seguinte forma:

<tipo> + <nome da variável>;

Exemplo: unsigned int x;

Pode-se também declarar e inicializar uma variável da seguinte forma:

<tipo> + <nome da variável> = <valor da variável;

Exemplo: int contador = 50;

Variáveis Globais são declaradas no início do programa e que podem ser acessadas em qualquer
ponto:

Exemplos: int conta;


unsigned int c;

void main()
{
conta = 10;
c = 2;
while(true);
}

Variáveis Locais são declaradas dentro de uma função e somente existe durante a execução
dessa função. Elas são descartadas depois de executada a função:

void main()
{
int conta;
conta = conta++;
while(true);
}

6 OPERADORES

Operadores de Atribuição

São utilizados para atribuir valores às variáveis:

Operador Descrição Exemplo


= associa um valor à variável a=2

Aritméticos:

Operador Descrição Exemplo


+ soma dos argumentos a+b
- subtração dos argumentos a-b
* multiplicação dos argumentos a*b
/ divisão dos argumentos a/b
% Resto da divisão (só pode ser utilizado com valores a % b
inteiros)
++ Soma 1 ao argumento a++
-- Subtrai 1 ao argumento a--

Relacionais:

São utilizados para comparação entre argumentos e retornam uma resposta verdadeira ou falsa. Como em
linguagem C não existe uma variável booleana para um resultado verdadeiro ou falso, todo valor igual a 0
será considerado falso e todo valor diferente de 0 (qualquer valor) será considerado verdadeiro.

Operador Descrição Exemplo


== Compara se igual a a == 5
!= Compara se diferente de a != 5
> Compara se maior que a>5
< Compara se menor que a<5
>= Compara se maior ou igual a a >= 5
<= Compara se menor ou igual a a <= 5

Operadores lógicos bit-a-bit:

Operador Descrição
& E (AND)
| OU (OR)
^ OU EXCLUSIVO (XOR)
~ Complemento (NOT)
>> Deslocamento à direita
<< Deslocamento à esquerda

Operadores lógicos relacionais:

Operador Descrição
&& Comparação lógica E (AND)
|| Comparação lógica OU (OR)
! Comparação lógica Complemento (NOT)

7 DECLARAÇÕES DE CONTROLE
Comando if (se):

O comando if é uma comando de decisão e é utilizado para avaliar uma determinada condição e
determinar se ela é verdadeira; caso seja, executa o bloco contido dentro desta condição. Sua forma geral
é:

if (exp) comando;

Se o resultado da condição referente à expressão (exp) for verdadeiro, comando será executado, caso
contrário, o programa segue sem executar o comando.

Para o exemplo a seguir, a mesma explicação anterior se encaixa, sendo que agora, se a condição
da expressão for verdadeira, serão executados comando1 e comando2.

if (exp)

{
comando1;
comando2;
}

Outros exemplos:

if (conta>50) conta = 0;

Neste caso, se a variável conta atingir um valor maior que 50, conta = 0 será executado e a variável
conta será zerada.

if (conta>50)
{
conta = 0;
conta1++;
}

Neste caso, se a variável conta atingir um valor maior que 50, os comandos conta = 0 e conta1++
serão executados: a variável conta será zerada e a variável conta1 será incrementada em 1,
respectivamente.

Comando if-else:

Neste caso, a condição if é utilizada da mesma forma anterior, sendo que agora, se a condição da
expressão for falsa a condição else será executada, ou seja, neste caso existe a possibilidade de escolha
de uma entre duas opções. Sua forma é:

if (exp) comando1;
else comando2;

Caso a expressão seja verdadeira, comando1 será executado, caso seja falsa, comando2 será executado.
Outro exemplo:

if (conta>0)
{
conta = 0;
conta1++;
}
else conta++;

Se o valor da variável conta for maior que 0, então os comandos conta = 0 e conta1++ serão executados,
porém se conta for menor ou igual a 0, então o comando conta++ será executado.

Comando SWITCH-CASE:

Quando existem muitos valores para testar de uma só variável, o comando IF pode ficar meio confuso ou
sem muita eficiência, para isso podemos utilizar o SWITCH-CASE. Segue sua forma:

switch(var)
{
case valor1: comando1;
....
break;
case valor2: comando2;
....
break;
....
....
default: comandoN;
....
....
}

Neste caso, a variável var será testada; se o valor dela for igual a valor1, comando1 será executado, se for
igual a valor2, comando2 será executado e assim por diante; se var tem valor diferente de qualquer caso
(case), comandoN será executado.

Exemplo:
switch(conta)
{
case 10 : conta1++;
break;
case 15: conta2++;
break;
case 20: {
conta1++;
conta2++;
}
break;
default: conta3++;
}

Neste caso, se o valor da variável conta for igual a 10, a variável conta1 será incrementada, se o valor de
conta for igual a 15, conta2 será incrementado; se conta for igual a 20, tanto os valores de conta1 quanto
de conta2 serão incrementados; para todos outros valores diferentes de conta, conta3 será incrementado.

Notar que após cada comando, há uma cláusula break, cuja função é encerrar o teste da variável, tendo em
vista já ter sido satisfeita a condição, assim, por exemplo:

switch(conta)
{
case 10 : conta1++;
break;
....

Se a variável conta tem seu valor igual a 10, o comando de incremento da variável conta1 será executado,
ou seja, a condição já foi atendida e não é preciso testar mais vezes a variável conta. Então, a cláusula
break, encerra os teste feitos por case e, assim, o programa continua na próxima instrução após a estrutura
switch.

Laço FOR:

Este é um dos comandos de laço (loop ou repetição) disponíveis na linguagem C, a sua forma é:

for(inicialização;condição(término);incremento) comando:

ou,

for(inicialização;condição(término);incremento)
{
comando1;
comando2;
}

onde:

inicialização: contém o valor inicial da variável;

condição: contém a condição de finalização do laço;

incremento: pode conter um ou mais comandos para incremento da variável.

Exemplo:

int conta;
int a = 0;
for (conta=0;conta<10;conta++) a = conta;

Neste exemplo, a variável conta será iniciada com o valor 0. A expressão a = conta será executada
e após, a variável conta será incrementada novamente. Essa repetição ou laço se encerrará quando a
condição conta < 10 for satisfeita, ou seja, quando a variável conta for igual a 9.

Laço WHILE:

Neste laço, os comandos serão repetidos enquanto a expressão for verdadeira, sua forma é:

while (exp)
{
comando;
}

Exemplo:

int x;
x = 0;
while(x<10) x++;

A programa ficará no laço de repetição while, enquanto a variável x for menor que 10 e o programa
só continuará quando x for maior ou igual a 10.

Laço DO-WHILE:

Este laço é uma variação do comando WHILE, sendo que neste caso o comando será executado antes de
testar se a condição é verdadeira. Sua forma é:

do
{
comando;
}
while(exp);

O comando será executado pelo menos uma vez antes de verificar a condição da expressão.

Exemplo:

int x;
int y;
do
{
x++;
} while(y!=1);
8 NOTAÇÃO NUMÉRICA

Em linguagem C, pode-se utilizar quatro formas de representação numérica: decimal, binária,


hexadecimal e octal, sendo as mais comuns somente as 3 primeiras.

Notação decimal: a representação desta notação é direta, ou seja, como estamos acostumados a
escrever:

Ex.: OUTPUT_B(10);

Notação binária: esta representação vem precedida de “0b” ou “0B”, indicando a notação:

Ex.: OUTPUT_B(0B00000010);

Notação Hexadecimal: esta representação vem precedida de “0x” ou “0X”, ex:

Ex.: OUTPUT_B(0x0A);

9 ESTRUTURA DE UM PROGRAMA EM C

Em linguagem C, os programas podem ter uma ou mais funções. Isto faz com haja uma estrutura
modular, ou seja, que cada parte do programa seja definida por blocos, facilitando sua visualização e
entendimento.

Todo programa em C tem uma função principal (main) a partir de onde o programa inicia.

A estrutura básica de um programa em C é:

#include<16F877A.h> //Aqui é incluído o header (*.h) para o microcontrolador utilizado.

#use delay (clock=8000000) //Aqui é definida a frequência do cristal para cálculo dos delays

#fuses HS, NOWDT, PUT,BROWNOUT, NOLVP //Configuração dos fusíveis

void main()

{ //Inicia a função.

//Este é o bloco principal do programa e é o único que a linguagem C precisa para funcionar.

} //Finaliza a função.

Este, portanto, é o menor programa escrito em linguagem C. Notar a função principal void main(); logo após,
abre-se a inicialização da função com uma chave, logo após vem o corpo do programa (onde ele será
escrito) e em seguida fecha-se o programa com outra chave.

Notar também as duas barras (//) antes das explicações. Essas barras iniciam um comentário e tudo que
vier após estas barras não será compilado.
Pode-se também fazer comentários de outra maneira::

/*Temos aqui uma outra forma de comentar num programa. Esta maneira é indicada quando precisamos
escrever algum comentário grande como este ou maior*/

Neste caso, o comentário tem seu início com ‘/*’ e é finalizado com ‘*/’.

Diretivas são comandos internos e que não são compilados, sendo estes dirigidos ao pré-
processador e executados pelo compilador antes da execução do processo de compilação.

#include<16F877A.h> //Aqui é incluso o header (*.h) para o microcontrolador utilizado.

#use delay (clock=8000000) //Aqui definimos a frequência do cristal para cálculo dos delays

#fuses HS, NOWDT, PUT, BROWNOUT, NOLVP //Configuração dos fusíveis

A primeira diretiva #include insere um programa fonte em outro, no nosso caso, estamos incluindo
o arquivo 16F877A.h que é um arquivo tipo ‘header’ (cabeçalho) e tem a função de definir o endereço na
memória de algumas funções e identificações para o microcontrolador PIC16F877A. Este arquivo,
geralmente, está localizado em C:\Aarquivos de Programas\PICC\Devices.

A diretiva #use delay, informa ao compilador a velocidade de clock do sistema, sendo necessária
para as funções de atraso (delay_us() e delay_ms()). Este valor é especificado em Hertz (por exemplo:
para a placa ACEPIC 40, o valor será 8000000Hz).

A diretiva #fuses, informa a configuração dos bits de controle (fusíveis) e para o PIC16F877A, as
opções disponíveis são:

Fuse Descrição
LP Oscilador LP
RC Oscilador RC
XT Oscilador XT
HS Oscilador HS
NOWDT Watchdog desabilitado
WDT Watchdog habilitado
NOPUT Temporizador Power-up desligado
PUT Temporizador Power-up ligado
NOPROTECT Proteção de código desabilitada
PROTECT Proteção de código habilitada
NOBROWNOUT Reset por queda de tensão desabilitado
BROWNOUT Reset por queda de tensão habilitado
NOLVP Programação em baixa tensão desabilitada
LVP Programação em baixa tensão habilitada.
NOCPD Proteção da EEPROM habilitada
CPD Proteção da EEPROM desabilitada
WRT_5% Proteção dos primeiros 255 bytes da memória de programa habilitada
WRT_25% Proteção de ¼ dos bytes totais da memória de programa habilitada
WRT_50% Proteção de ½ dos bytes totais da memória de programa habilitada
NOWRT Proteção da memória de programa desabilitada

Você também pode gostar