Anda di halaman 1dari 60

Laboratório de MCU 16F873A

Professor: Flavio Bispo

30 de octubre de 2017
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

Sobre o Material

Este material contém um roteiro de práticas de laboratório virtual usando os softwares ISIS
Proteus para simulação eletrônica e o MPLAB X junto com o compilador XC8 para codificação
e compilação de programa em linguagem C. Além disso, os procedimentos para prototipagem
estão declarados a cada prática e se estendem desde a instalação dos programas essenciais
até o desenvolvimento de cinco práticas avançadas, as quais envolvem uso dos periféricos de
conversor AC/DC, PWM, Timer, transmissão de dados sob o protocolo USART e rotina de
interrupção.

O S.O. Windows de 64 bits é necessário para um melhor desempenho usando o


MPLAB X. O MPLAB X pode ser executado em uma instalação do Windows 32
bits, mas provavelmente apresentará desempenho mais lento. É recomendado atua-
lizar o sistema operacional para o Windows de 64 bits antes da instalação do MPLAB X.

“Gente que gosta de você discorda de você quando é necessário, gente que te respeita discorda de
você quando necessário, um concorrente fraco te enfraquece, uma oposição frágil te fragiliza e te
deixa envelhecer. Preste atenção em quem discorda de você pois vai te ajuda a superar, transformar,
inovar e com isso não vamos sossegar em excesso, créditos ao professor por nem sempre concorda,
pois, o mar calmo nunca fez bom marinheiro. (Algumas ideias extraídas a partir de pensamentos
do filosofo Mario Sergio Cortella) ”.

Material didático em construção. Aponte qualquer erro ortográfico encontrado para elevar qua-
lidade deste conteúdo enviando mensagem para flavio.santiago.bispo@hotmail.com

2 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

Prática 1) Instalação do MPLAB X


1. Passo: Baixe o instalador do MPLAB X através do site:
http://microchipdeveloper.com/mplabx:installation

2. Passo: Execute o instalador

3. Passo: Escolha o diretório

4. Passo: Marque as opções:

MPLAB X IDE (Integrated Development Environment)


MPLAB IPE (Integrated Programming Environment)

5. Passo: Complete a instalação e finalize-a

3 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

Prática 2) Primeiro projeto usando o MPLAB X e


o Compilador XC8
1. Após instalado o MPLAB x, instale o Compilador XC8 no site da Microchip.

2. Abra o MPLB X

3. Clique em File >> New Project

4. Selecione Microchip Embedded >> Standalone Project

5. Clique Next

4 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

6. Selecione a Família e Dispositivo

7. Clique Next

8. Selecione o compilador (Instalar antes o XC8 C compiler)

9. Edite o nome do projeto

5 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

10. A janela de trabalho aparecerá indicando o nome do projeto em negrito

11. Selecione Source file >> New >> C main file

12. Edite o nome do arquivo C

6 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

13. Comece a programar

Botões importantes

build project: Executa qualquer projeto modificado anteriormente

clean and build project: Executa todos os projetos do arquivo

build and run project: Grava e executa qualquer arquivo modificado anteriormente

7 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

textbfbuild and debug project: Executa todos os projetos do arquivo e realiza um


passo-a-passo do arquivo principal

8 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

Atividade 1) Construção de Programa Brinquedo


Ao se construir um código em C para PIC, se faz necessário prestar bastante atenção no que
compete às estruturas de periféricas que condicionam a aplicação. De forma resumida, são re-
presentadas abaixo:

Wachtdog Timer

Code Protection

Oscillator Selection

Analise o Código a seguir, escreva o significado de cada configuração e discuta em sala qual é
sua efetiva aplicação em uma codificação:

#pragma config FOSC = HS


#pragma config WDTE = ON
#pragma config PWRTE = OFF
#pragma config BOREN = ON
#pragma config LVP = OFF
#pragma config CPD = OFF
#pragma config WRT = OFF
#pragma config CP = OFF

Programa Esqueleto

#include <xc.h>
#include <pic16f873a.h>

#pragma config FOSC = HS


#pragma config WDTE = ON
#pragma config PWRTE = OFF
#pragma config BOREN = ON
#pragma config LVP = OFF
#pragma config CPD = OFF
#pragma config WRT = OFF
#pragma config CP = OFF

int main()
{
return 0;
}
9 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

Aplicação 1) Realize os procedimentos da prática 2 para escrever um código em linguagem C


para PIC. Após abrir a página de edição de códigos, escreva o programa esqueleto acima para
iniciarmos o estudo do çódigo brinquedo".
Estudo de caso: programa em linguagem C para PIC para setar e resetar um um pino digital.

Os pinos Saídas de entrada de um microcontrolador PIC são divididos em PORTS


diferentes que contêm um grupo de pinos GPIO (General Purpose Input Output).

Nos Microcontroladores 16F, cada porta está associada a dois registros: TRIS e PORT.
Por exemplo: TRISB, PORTB, TRISD, PORTD.

TRIS significa Tri-State, determina a direção de cada pino GPIO. A lógica 1 em um bit
particular do registro TRIS faz com que o pino correspondente seja inserido, enquanto
a lógica 0 em um determinado bit faz a saída do pino correspondente.

Todos os pinos de entrada estarão no estado de alta-impedância. PORT Register é


usado para ler dados de ou gravar dados para pinos de saída de entrada.

Para um pino de saída (o bit TRIS é 0), a lógica 1 no registro PORT faz com que o
pino correspondente se torne Logic High (VDD) e Lógica 0 no registro PORT faz o
correspondente se tornar Logic Low (VSS).

O objetivo é fazer com que, uma vez definido o comportamento do pino como entrada e saída,
um bit do PORT adquira um estado lógico variante no tempo. Esse tempo é definido como 1
segundo. Logo, escreva o código abaixo para uma frequência de giro de relógio do dispositivo
em 20 MHz e explique

1. qual o valor do pino físico do MCU?

2. qual o PORT?
10 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

3. qual o bit desse PORT?

4. qual o TRIS?

5. qual a máscara do TRIS? e o que ele representa?

#define _XTAL_FREQ

#include <xc.h>
#include <pic16f873a.h>

#pragma config FOSC = HS


#pragma config WDTE = ON
#pragma config PWRTE = OFF
#pragma config BOREN = ON
#pragma config LVP = OFF
#pragma config CPD = OFF
#pragma config WRT = OFF
#pragma config CP = OFF

int main()
{
TRISB0 = 0;
while(1)
{
RB0 = 1;
__delay_ms(1000);
RB0 = 0;
__delay_ms(1000);
}
return 0;
}

11 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

Prática 3) K150 PIC Programmer Driver


Via blog.FelipFlop.com
Este gravador possui um soquete tipo ZIF de 40 pinos. ZIF significa Zero Insertion Force, ou, em
português, Zero Força de Inserção, que nada mais é do que um sistema composto pelo soquete
e uma pequena alavanca, que permite que você coloque e retire o chip de uma maneira muito
fácil e sem danos aos pinos do CI, ao contrário dos soquetes tradicionais, onde é muito comum
acontecerem quebras, arranhões, e danos aos pinos.

O gravador conta também com um conector para programação ICSP (In-Circuit Serial Program-
ming), onde o microcontrolador pode ser programado diretamente no circuito onde ele está
montado, sendo que para isso são necessárias algumas adaptações no circuito.
Para reconhecimento do dispositivo, basta conectá-lo ao computador e gravador é reconhecido
pelo Windows automaticamente. Se o gravador não foi reconhecido automaticamente pelo seu
computador, os drivers podem ser baixados.
Quando o Windows detectar o gravador, o Windows automaticamente vai atribuir à ele uma
porta COM (serial) aleatória. Entretanto, o software de gravação não funciona adequadamente
com portas abaixo da COM5, e talvez seja necessário alterar essa porta manualmente. Exemplo:

No windows 7, isso é feito acessando o Gerenciador de Dispositivos dentro do Painel de Controle.


Lá dentro, há a opção Portas (Com and LPT), e dentro dela o dispositivo que foi detectado. No
nosso caso, o Prolific USB-to-Serial Comm Port, na porta COM14 :
12 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

Clique com o botão direito em Prolific USB-To-Serial Comm Port (COM14), e depois em PRO-
PRIEDADES:

Na tela de propriedades, selecione a aba Configurações da Porta (Port Settings), depois em AVA-
NÇADO(Advanced):

13 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

Selecione a porta COM de sua preferência (lembre-se que esta porta deve ser maior do que a
COM4) e anote esta informação, que será usada posteriormente no software de gravação. O
valor da porta COM da imagem é meramente ilustrativa.

Uso do programa Microbrn


De posse do gravador de PIC K150 e do programa Microbrn (download nesse link
http://blog.filipeflop.com/pic/como-utilizar-gravador-de-pic-usb-k150.html) realize o procedi-
mento para gravar o arquivo .hex no dispositivo como segue:

Execute o aplicativo Microbrn. Aparecerá a janela abaixo.

14 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

Configure primeiramente a porta COM. No menu FILE, escolha a opção PORT, digi-
tando o número da porta serial que você configurou no painel de controle.

No canto inferior direito da janela, selecione o modelo de microcontrolador que vai


ser utilizado. No desenho do soquete ZIF será representado a posição exata em que o
MCU deverá ser encaixado no gravador. Na figura abaixo está sendo representada a
inserção de um MCU PIC16F628A.

15 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

Na tela principal do Microbrn, o botão Read tem a função de ler o programa do CI


que está no gravador (se o programa não estiver protegido), o botão Verify verifica
se há algum erro na ROM que será gravada, e o botão Blank abre uma tela com 2
opções:

A opção Erase Check verifica se há algo gravado no microcontrolador, e a opção


Erase Chip apaga qualquer programa previamente gravado no chip. Recomendamos
esse procedimento antes da gravação de novos programas no chip.

A definição sobre os FUSES pode ser feita no


próprio programa do PIC, ou então no Microbrn,
clicando no botão FUSES. Observe que esta
opção só estará disponível após você carregar
um arquivo .HEX na memória do Microbrn:

16 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

Se o configurador Code Protect estiver habilitado, ao final da gravação o Microbrn irá apresentar
um erro de leitura, pois o código está protegido. Efetuadas as configurações necessárias, clique no
botão PROGRAM para gravar o arquivo .HEX no microcontrolador.

17 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

Resets do PIC
http://www.hpspin.com.br/site1/programacao/resets.php

Por algum motivo, deseja-se reinicializar o MCU. Seja para restabelecer alguma condição inicial
ou seja porque a CPU parou de funcionar por um motivo desconhecido. Todo MCU pode ser
reinicializado de duas maneiras: desligando e religando a fonte de alimentação ou então usando
as funções de reset do mesmo.

Os MCU PIC possuem algumas funções de reset prevendo certas situações. São elas:

MLCR

Função de reset externo fornecida pelo pino MCLR. Durante a operação normal, esse pino deve
ser mantido em nível alto (+5V), conectado ao VDD através de um resistor de, por exemplo,
10K. Para efetuar o reset, deve-se aterrar esse pino manualmente, isto é, levá-lo ao nível 0V, por
exemplo, através de uma chave táctil. Esse procedimento fará com que a CPU comece a executar
as instruções a partir do vetor de reset, ou seja, no endereço 0x000 da memória de programa. O
reset no pino MCLR limpa alguns registradores de controle do MCU mas mantem intactos todos
os dados da memória de dados (RAM). Em C, a diretiva é escrita como:

#pragma config MCLRE = ON

A figura abaixo mostra como montar um circuito de reset no pino MCLR:

Power On Reset (POR)

18 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

Esse reset só acontece quando o circuito é ligado. É usado para aguardar a tensão de alimentação
subir a um ponto confiável antes da CPU começar a executar as instruções. Após um Power On
Reset, alguns registradores de controle serão inicializado mas os dados da memória de dados
(RAM) podem conter valores inesperados. O Power On Reset fará com que a CPU comece a
executar as instruções a partir do vetor de reset, ou seja, no endereço 0x000 da memória de
programa. Em C, a diretiva é escrita como:

#pragma config PWRTE = ON

Brown-Out Reset (BOR)

O Brown-Out Reset é usado para reiniciar a CPU automaticamente quando a tensão de alimen-
tação cair abaixo de um nível seguro para a operação do circuito.O Brown-Out Reset deve ser
habilitado nos bits de configurações do MCU. Por exemplo, o Brown-Out é habilitado, via lin-
guagem C, com a diretiva

#pragma config BOREN = ON

Se o Brown-Out estiver habilitado e a tensão cair abaixo do nível adequado haverá um reset
que fará com que a CPU comece a executar as instruções a partir do vetor de reset, ou seja,
no endereço 0x000 da memória de programa. Após o reset, alguns registradores de controle do
MCU serão reinicializados mas o conteúdo da memória de dados (RAM) será imprevisível. Em
alguns MCU os níveis de tensão seguros para a operação são fixos mas, em outros, podem ser
selecionados.

Watchdog Timer Reset (WDT)

O que fazer com aquele programa que trava, não se sabe em que rotina, e torna necessário ligar e
desligar o circuito para que ele volte a funcionar? O WTD serve justamente para reiniciar a CPU
de tempos em tempos para certificar que o programa não parou de funcionar por algum motivo.
Seu funcionamento depende de um timer interno que, ao estourar a contagem, provoca o reset do
MCU. Esse tempo varia de acordo com condições de temperatura e a tensão de alimentação mas
fica, em média, em torno dos 18ms (milisegundos) no PIC16F628A. O WDT deve ser habilitado
ou desabilitado através dos bits de configuração.Em linguagem C, segue a escrita como

#pragma config WDTE = ON

19 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

O reset pelo WDT mantem os dados da memória de dados (RAM) intactos mas alguns regis-
tradores de controle são reinicializados. Após o reset do WDT, a CPU começa a executar as
instruções a partir do vetor de reset, ou seja, no endereço 0x000 da memória de programa.

Significados de cada configurador do PIC para C

FOSC: Definição de tipo de velocidade do oscilador

WDTE: Watchdog Timer

PWRTE: Power-up Timer

BOREN: Brown-out Reset

LVP: Low-Voltage In-Circuit Serial Programming (programação em circuito de aplicação)

MCLRE: Reset do MCU manual

CPD: Proteção do Código de Dados de Memória EEPROM

WRT: Flash Escrita na memória de Programa. É possível escrever dados diretamente na


memória Flash pelo firmware do dispositivo

CP: Flash Program Memory Code Protection bit (Proteção do código)

20 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

Atividade 2) Conversor A/D


baseado em: microcontrolandos.blogspot.com.br

O conversor analógico-digital (ADC) permite conversão de um sinal de entrada analógico para


um binário de 10 bits. Este dispositivo utiliza entradas analógico, que são multiplexados em uma
única amostragem. A saída da amostra está ligada à entrada do conversor. O conversor gera um
resultado binário de 10 bits por meio de sucessivas aproximações e armazena o resultado da
conversão nos endereços (ADRESL e ADRESH).

A referência de tensão ADC é selecionável por software para ser gerados internamente ou
externamente. São eles Vref + e o Vref −. A função CVref é destinada a comparação de
valor de referência com um outro que está sendo aplicado ao PIC e que pode ser configurado
pelo registrador CVRCON. Nada tem a ver com a estrutura do conversor A/D.

O ADC pode gerar uma interrupção, uma vez concluída uma conversão.

Configuração

CONFIGURAÇÃO DAS PORTAS

O ADC não distingue entre tensões analógicas e digitais. Para evitar erros de medição ou
estragos no chip, os pinos devem ser configurados como entradas analógicas, antes de iniciar
a conversão. Atenção: O valor apresentado pelo ADC leva em conta, sempre, a referência
selecionada. Ou seja, quando a referência Vref + selecionada for VDD , por exemplo, a
conversão máxima 5V será representada pelo valor 1024, já quando a referencia menor de
21 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

tensão é Vref − e corresponde a VSS , a representação binária é 0.

É possível utilizar os pinos RA3 e/ou RA2 como entrada para diferentes tensões de referência,
a máxima conversão retornada como 1024 terá exatamente o valor inserido no pino RA3 ou
ainda a diferença entre RA3 e RA2, caso Vref − tenha sido selecionado também. De qualquer
maneira, é necessário observar os valores máximos e mínimos para trabalhar com tensões de
referência externas no PIC.

CONFIGURAÇÃO DO CANAL

Os bits CHS do registro ADCON0 determina qual canal estará conectado ao conversor.

CONFIGURAÇÃO DA TENSÃO DE REFERÊNCIA

Os bits PCFG do registro ADCON1 fornece controle independente da tensão de referência


positivo e negativo. Tensão de referência positivo pode ser VDD ou uma fonte de tensão
externa. Da mesma forma, a tensão de referência negativa pode ser um VSS ou fonte de tensão
externa.

FONTE DE CLOCK DA CONVERSÃO

A fonte e clock do conversor é selecionável através dos bits ADCS do registo ADCON0. São
quatro opções de clock possíveis: Fosc/2, Fosc/8, Fosc/32 e RC.

ADCON0

ADCS1:ADCS0 - Seleção do clock da conversão (mais configurações vide o datasheet)

00 - Fosc/2, máximo de frequência: 1, 25M Hz (conversão a cada 2 Tosc, ou seja a cada 2


períodos de clock de máquina)
01 - Fosc/8, máximo de frequência: 5M Hz (conversão a cada 8 Tosc, ou seja a cada 8 períodos
de clock de máquina)
10 - Fosc/32, máximo de frequência: 20M Hz (conversão a cada 32 Tosc, ou seja a cada 2
períodos de clock de máquina)
11 - RC (oscilador do módulo interno 2 − 6us)

Atenção:
22 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

o clock de conversão deve atender no mínimo o tempo de 1, 6us

O tempo de clock típico do RC é de 4us

Quando usar o frequências acima de 1M Hz, o RC do A/D somente é indicado quan-


do for utilizado a função de sleep.

Para corretas conversões, o tempo de período de conversão (TAD ) deve ser garanti-
do, no mínimo, a 1, 6us.

CHS2:CHS0 - Seleção do canal

000 = AN0

001 = AN1

010 = AN2

011 = AN3

100 = AN4

GO/DONE - Status da conversão


0 - Conversão completa ou não iniciada;
1 - Conversão iniciada. O bit é limpo automaticamente quando completar a conversão.

ADON - Habilita o módulo ADC


0 - Desabilitado
1 - Habilitado

ADCON1

ADFM - Formato do resultado da conversão


0 - Justificado para Esquerda
1 - Justificado para Direita
23 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

PCFG - Configuração dos pinos como entrada analógica/Digital ou Vref

Pseudo-código para implementação do conversor A/D


———————————————————————————

1. Configurar o pino como entrada;

24 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

TRISA = 0b00000001;// configura o bit 0 (pino 2) como entrada e

2. Configurar o pino como analógico;

ADCON1bits.PCFG = 0b1110;//Vref+ = VDD; Vref- = VSS

3. Selecione o clock da conversão ADC

ADCON0bits.ADCS1 = 1;

ADCON0bits.ADCS0 = 0;// Fosc/32

4. Selecione o canal de entrada ADC

DCON0bits.CHS2 = 0;

ADCON0bits.CHS1 = 0;

ADCON0bits.CHS0 = 0;// escolha de canal

5. Selecionar o formato do resultado

ADCON1bits.ADFM = 1;//justificado à direita

6. Ligue o módulo ADC

ADCON0bits.ADON = 1;// ligar o conversor

7. Esperar o tempo de aquisição pretendido. (20 us)

25 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

__delay_us(20);//aguarda um tempo até a unidade de conversão

//estabilizar a tensão

8. Iniciar a conversão, definindo o bit GO/DONE.

ADCON0bits.GO_nDONE = 1; converta o dado

9. Aguarde ADC conversão, até que:

GO/DONE for resetado ou


Aguardando a interrupção ADC (caso interrupção esteja ativada)

while(GO_nDONE);//CPU aguarda enquanto a conversão

//está em andamento

__delay_ms(20);//20 ms para nova conversão

10. Leia o resultado ADC

adc_rd = ((ADRESH << 8) + ADRESL);//resultado da conversão

Atenção: A diretiva de MCLRE não funciona no XC8 C Compiler.

Questões a serem respondidas

1. Após estudar o pseudo-código acima, para cada bloco de comando explique o


que está ocorrendo.

2. Complete o código abaixo com as configurações de uso de conversor ao seu


modo.

código usando conversor A/D

26 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

// CONFIGURAÇÕES

#include <xc.h>
#include <pic16f877a.h>

#pragma config FOSC = HS


#pragma config WDTE = ON
#pragma config PWRTE = ON
#pragma config BOREN = ON
#pragma config LVP = ON
#pragma config CP = ON

#define _XTAL_FREQ 20000000

unsigned int ADC_Read(unsigned char canal)


{
ADCON0bits.CHS = canal;
GO_nDONE = 1;
while(GO_nDONE);
return ((ADRESH<<8)+ADRESL);
}
void main()
{
unsigned int a;
TRISA = 0xFF;
TRISB = 0x00;
TRISC = 0x00;
ADC_Init();

do
{
a = ADC_Read(0);
PORTB = a;
PORTC = a>>8;
__delay_ms(1000);
}while(1);
}

Mais informações sobre conversores A/D acesse o site: http://www.newtoncbraga.


com.br/index.php/como-funciona/1508-conversores-ad

27 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

Resolução de questão

#include <xc.h>
#include<pic16f873a.h>

#pragma config FOSC = HS


#pragma config WDTE = ON
#pragma config PWRTE = ON
#pragma config BOREN = ON
#pragma config LVP = ON
#pragma config CP = ON

#define _XTAL_FREQ 20000000

long int AC_read(char canal)


{
ADCON0bits.CHS = canal;
ADCON0bits.ADCS = 0b10;
ADCON1bits.PCFG = 0b1110;
ADCON1bits.ADFM = 1;
ADCON0bits.ADON = 1;
__delay_us(10);
ADCON0bits.GO_nDONE = 1;
while(GO_nDONE);
return ((ADRESH << 8) + ADRESL);
}

void main(void) {
long int a;
TRISA = 255;
TRISB = 0;
TRISC = 0;
do{
a = AC_read(0);
PORTB = a;
PORTC = a>>8;
__delay_ms(1000);
}while(1);
return;
}

28 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

Exercício:

Em um sistema de controle de caldeira, um engenheiro de controle e automação projetou um


sistema embarcado utilizando um MCU (microcontrolador) da família PIC16F87XX capaz de
efetuar leituras de dois sensores: temperatura e pressão. Assuma que o controle aplicado é do
tipo “on/off ” para ambas as variáveis supracitadas. A figura acima representa o circuito do
MCU com suas estruturas de relógio externo, reset e conexões com entrada e saída.

Para preparar o PIC de modo a fazê-lo trabalhar com valores analógicos dos sensores, alguns
passos devem ser realizados. Para realizar a leitura dos dois sensores a cada ciclo de um pro-
grama principal, siga o mesmo raciocínio de escrita da questão 1 para escrita das ações nos
registradores.

Obs.: para ambas as entradas, admita um mesmo clock (Fosc/32), dados justificados à direita,
sem valor de tensão de referência e sem rotina de interrupção.

29 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

Debuging
Passos para Debug e visualização de eventos no simulador da IDE do MPLAB X.

Após compilar o código e obter êxito, é possível depurar o código passo-a-passo seguindo alguns
comandos básicos. Clique no ícone Debug >> Debug Main Project.

Uma janela irá aparecer para alterar a execução do programa MPLAB X para simulador.

30 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

Após alguns minutos, o código irá ser executado novamente em modo de simulação e aparecerá
na parte superior do programa um controlador de ações como mostrado na figura abaixo.
Assim que esta parte estiver habilitada, pressione o ícone pause.

Nesta ocasião é possível passar por todas as etapas do código clicando em step over ou quando
desejar analisar uma função, step into.

A fim de visualizar os eventos que estão ocorrendo a cada passo de simulação, é possível através
de fáceis passos ter disponível no IDE este auxílio. clique no ícone Windows >> PIC Memore
Views >> SFRs.

31 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

Posicione no melhor local e acompanhe conforme a figura abaixo.

32 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

33 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

Interrupções
Via: http://www.arnerobotics.com.br/eletronica/
Microcontrolador_PIC_teoria_3.htm

As interrupções são muito utilizadas no mundo dos microcontroladores e dos microprocessa-


dores. Um exemplo típico são nossos microcomputadores PC. Sempre que pressionamos uma
tecla, uma interrupção é gerada para o microprocessador, solicitando o tratamento desta. Assim,
o PC não é obrigado a varrer constantemente o teclado em busca de uma tecla. Porém é claro
que para que isso seja feito, “alguém ou alguma coisa” deve fazer esta varredura por ele. Isso
é feito por um microcontrolador dedicado, interno em todos os teclados de PC. Assim temos a
geração de uma interrupção no processamento central por parte de um “periférico”.

No caso do PIC16F873A algumas interrupções são mostradas abaixo:

Interrupção por overflow do Timer0;

Interrupção RB (mudança de estado das portas B);

Interrupção externa;

Interrupção de conversão analógico/digital;

Interrupção de transmissão de dados da porta serial (RS232);

34 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

Interrupção de recepção de dados da porta serial (RS232);

Interrupção do módulo CCP1 e CCP2;

Em todas as interrupções é necessário habilitar as interrupção global e interrupção dos perifé-


ricos(exceto algumas), configurando o seguinte registro:

GIE: Habilita a interrupção global:

0 - Desabilitado

1 - Habilitado

PEIE: Habilita a interrupção dos periféricos:

0 - Desabilitado

1 - Habilitado

Atividade 2.1) Interrupção via ADC


Exemplo para interrupção usando o conversor ADC: Esta interrupção ocorre quando a
conversão analógico/digital foi concluída.

O bit que habilita essa interrupção é o PIE1.ADIE - (habilita com 1).

A flag de sinalização dessa interrupção é o PIR1.ADIF - (habilita com 1).

35 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

Exemplo de código:

https://docs.google.com/a/grupotiradentes.com/document/
d/1kjXbJdWfViw7o7KUi2pNif1wQY8s40ZeFepNOk8RF1Q/edit?usp=
sharing

Questão a ser respondida:

Estruture o código escrito ou do exemplo acima em bloco de funções.

#include<xc.h>
#include<pic16f873a.h>
#pragma config FOSC = HS
#define _XTAL_FREQ 20000000
#define saida PORTBbits.RB0
void interrupt ADC_int(){
long int conv = (ADRESH << 8) + ADRESL;
if (conv>500){
saida = 1;}
else {
saida = 0;
}
PIR1bits.ADIF = 0;
__delay_ms(1000);
ADCON0bits.GO_nDONE = 1;
}
void ADC_config(void){
ADCON0 = 10000001;
__delay_us(10);
ADCON1 = 10000000;
ADCON0bits.GO_DONE = 1;
}
void interr_config(){
PIE1bits.ADIE = 1;
PIR1bits.ADIF = 0;
INTCONbits.GIE = 1;
36 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

INTCONbits.PEIE = 1;
}
void main(){
TRISA = 255; TRISB = 0;
interr_config();
ADC_config();
while(1){}
}

Atividade 2.2) Interrupção externa via entrada em RB0


Nesta subsessão, é orientada o uso da interrupção via entrara externa, uso do pino RB0/INT.
Esta interrupção faz com que, ao ser identificado um sinal lógico alto no pino RB0/INT, a
ação da CPU seja direcionada para um local de tratamento de interrupção. O registrador para
configurar tal ação é o INCON (pág. 24 datasheet). Os bits relacionados são INTE (bit 4) e INTF
(bit 1), respectivamente, realizam a habilitação da interrupção externa e o outro é o sinalizador
do evento.

Observção: definir o bit RB0 como entrada através do TRIS

INTE: Habilita a interrupção Externa:

0 - Desabilitado

1 - Habilitado

INTF: Flag de realização da interrupção:

0 - Não ocorreu

1 - Ocorreu

Questão a ser respondida:

Elabore um código que faça uso a interrupção via sinal externo através do pino
RB0/INT.

//Aplicação de saída toogle


//mediante a entrada digital
//via interrupção

37 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

#include <xc.h>
#include<pic16f877a.h>

#pragma config FOSC = HS


#define _XTAL_FREQ 20000000

#define saida PORTBbits.RB1

void interrupt externo()


{
saida =~saida;
INTCONbits.INTF = 0;
__delay_ms(300);
}

void main(void) {
TRISB = 1;
PORTB = 0;

INTCONbits.GIE = 1;
INTCONbits.PEIE = 1;
INTCONbits.INTE = 1;
INTCONbits.INTF = 0;

OPTION_REGbits.INTEDG = 1;

while(1){}
return;
}

Atividade 2.3) Interrupção externa via mudança no


PORTB
Interrupção ocorre quando, no mínimo, um dos estados entre RB4:RB7 são alterados.

RBIE: Habilita a interrupção de mudança do PORTB:

0 - Desabilitado

38 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

1 - Habilitado

RBIF: Flag de realização da interrupção via alteração de estado do PORTB:

0 - Não ocorreu

1 - Ocorreu mudança de estado nos bits entre RB4:RB7

Aplicação

Desenvolva um código capaz de usar o valor de um sensor analógico de temperatu-


ra, bem como o sinal de uma chave para entrada digital, com a finalidade de energi-
zar/desenergizar (on/off) um condicionador de ar.

39 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

Atividade 3) PWM (Pulse Width Modulation)


Via microcontrolandos.blogspot.com.br

Para gerar um sinal PWM com o PIC, nós utilizamos o T IM ER2 que é um temporizador de
8 bits (0 − 255). O T IM ER2 é usado como base de tempo para a modulação PWM com o
módulo CCP (compare/capture/PWM).

Cálculo do período do PWM

O período do PWM é especificado pelo registro P R2. Pode ser calculado pela seguinte fórmula:

40 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

P = (P R2 + 1) ∗ 4 ∗ T osc ∗ P rescaler

1
T osc =
F osc
EM que 4 significa um deslocamento de duas casas de algarismos binário para a esquerda do
resultado (P R2 + 1). Isso quer dizer que, na prática, o período pode ser definido com uma
faixa de 4 − 1024 dados como múltiplos de 4.

O Prescale aplica um efeito sanfona ao tamanho do período, ou seja, 1 : 1 significa um ciclo


de clock dá um ciclo de PWM, 1 : 4 quatro ciclos de clock dá um PWM e 1 : 16 significa de
dezesseis ciclos de clock dá um ciclo de PWM.

Cálculo do Duty Cycle do PWM

O duty cycle é configurado usando 10 bits: 8 MSB do registro CCP RXL e 2 adicionais
LSB localizados no registrador CCP 1CON : bits 5 e 4, em que esse X significa ou utilizar o
primeiro PWM (1) ou o segundo (2). O resultado é um número de 10 bits, presente na fórmula:

DutyCycle = CCP R1L ∗ T osc ∗ P rescaler

Exemplo: Calcular a frequência e duty cycle, sendo que o cristal é de 20M Hz, Prescaler
1 : 16, P R2 = 255, CCP R1L = 100.

P = (255 + 1) ∗ 4 ∗ 0, 05us ∗ 16

P = 819, 2us

F req = 1/P = 1/819, 2 = 0, 0012207M Hz = 1, 22KHz

DutyCycle = (CCP R1L << 2) ∗ T osc ∗ P rescaler

DutyCycle = (100 ∗ 4) ∗ 0, 05us ∗ 16

DutyCycle = 400 ∗ 0, 05 ∗ 16 = 320us

DutyCycle( %) = 320us/819, 2us ∗ 100 = 39, 06 %

Observação:

41 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

Veja que foi necessário deslocar CCP R1L (8 bits) para podermos ter 10 bits for-
matados. Deslocar dois bits para esquerda é a mesma coisa que multiplicar por 4.

O Duty Cycle pode atingir um resultado que compreende 0 % a 99, 6 %. Isso por
conta da relação abaixo:

(CCP R1L) ∗ 4 ∗ T osc ∗ P rescaler


DutyCycle( %) =
(P R2 + 1) ∗ 4 ∗ T osc ∗ P rescaler

quando os bits 5 e 4 do registro CCPXCON são 0. Isso significa que o valor do Duty
é sempre um múltiplo de 4.

O valor de P R2 deve ser maior que o valor de CCP R1L.

Observe que no caso do P IC16F 873A existem 2 canais PWM.

Analise o Pseudo-código abaixo

1. Define o período escrevendo o valor de PR2

2. Define o duty cycle escrevendo o valor de CCPRxL

3. Define pino RC2(canal 1) ou RC1(canal 2) como saída


42 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

4. Define o valor do Prescaler, bits 1 e 0 do registro T 2CON

00 = prescaler1 : 1
01 = prescaler1 : 4
1x = prescaler1 : 16

5. Habilitar o T imer2, setando o bit T M R20N do registro T 2CON

6. Configure o modulo CCP 1 (ou CCP 2) no modo PWM, setando o bit 3 e 2 do


registro CCPxCON

Usando os valores acima e utilizando um cristal de 20M Hz, a frequência e o duty cycle será:
1
T osc = = 0, 05us
20
P R2 = 200

P rescale = 1 : 1

P = (200 + 1) ∗ 4 ∗ 0, 05us ∗ 1

P = 40, 2us

1 1
F req = = = 0, 02487M Hz = 24, 87KHz
P 40, 2

CCP R1L = 50

DutyCycle = (50 ∗ 4) ∗ 0, 05us ∗ 1

DutyCycle = 200 ∗ 0, 05 ∗ 1 = 10us

10us
DutyCycle( %) = ∗ 100 = 24, 90 %
40, 2us

Questão a responder

Comente o código abaixo descrevendo a atividade em cada instrução

43 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

void main()
{
PR2 = 200; //
CCPR1L = 50; //
TRISCbits.TRISC2 = 0; //

T2CONbits.T2CKPS1 = 0;//
T2CONbits.T2CKPS0 = 0;//

T2CONbits.TMR2ON = 1;//

CCP1CONbits.CCP1M3 = 1;//
CCP1CONbits.CCP1M2 = 1;//

while(1){} //
}

Exemplo: Construa um PWM capaz de fornecer uma saída de, aproximadamente, 1, 3kHz e
com sinal a 75 % de sua faixa, sabendo que o cistal aplicado a este circuito é de 20M Hz.

Sejam P R2 = 240 e Prescaler de 1 : 16,


temos que:
1
P = (240 + 1) ∗ 4 ∗ ∗ 16
20M Hz
P = 768us
1
F =
P
F = 1,302, 08Hz

Agora, para o cálculo do Duty, temos que o registrador a ser utilizado enxerga a saída RC2,
conforme a figura abaixo, e que assume, como registrador de base de cálculo, o CCP R1L.

44 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

Logo, o CCP R1L = 180

DutyCycle = (180 ∗ 4) ∗ 0, 05us ∗ 16


DutyCycle = 720 ∗ 0, 05 ∗ 16 = 576us
576us
DutyCycle( %) = ∗ 100 = 75, 00 %
768us
Questões a serem respondidas

1. Após estudar o pré-código acima, complete-o fazendo o PWM ser definido no


pino 13.

2. Planeje e edite um código para leitura de dado analógico e aplique essa mesma
informação na saída por meio do recurso de PWM.

Pra saber mais acesse: https://www.arduino.cc/en/Tutorial/PWM

Exemplo de código usando o conversor A/D −− > PWM com interrupção.

https://1drv.ms/t/s!AsLeyQ9bNrmoga5F0Q9eM6dysO_PAg

Exemplo de código usando entrada externa para incrementar ou decrementar o PWM.

https://1drv.ms/t/s!AsLeyQ9bNrmoga5EjK48zj_3eQLtEQ

45 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

Atividade 4) Timer
Via microcontrolandos.blogspot.com.br

O módulo Timer1 é um temporizador/contador de 16 bits consistindo de dois registos de 8 bits


(TMR1H e TMR1L). O par de registros TMR1 (TMR1H: TMR1L) incrementa de 0000h a FFFFh e
volta para 0000h.

A interrupção TMR1, se habilitado, é gerada por overflow, no qual o bit de flag é: TMR1IF
(P IR1 < 0 >). Esta interrupção pode ser ativado/desativado através do bit TMR1IE
(P IE1 < 0 >).

Timer1 pode operar em um dos dois modos:

1. Como um temporizador (Síncrono e Assíncrono).

2. Como um contador.

O modo de funcionamento é determinado pela fonte de clock, selecionando o bit T M R1CS


(T 1CON < 1 >). No modo Timer, o Timer1 incrementa a cada ciclo de clock.

No modo de Contador, ele incrementa em cada subida da entrada do relógio externo. Timer1
pode ser ativado / desativado através do bit TMR1ON (T 1CON < 0 >). Timer1 também

46 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

tem uma .entrada RESETïnterno TMR1GE, este RESET pode ser gerado por qualquer um dos
dois CCP módulos.

Quando o oscilador Timer1 está habilitado (T1OSCEN é definido), os pinos RC1/T1OSI/CCP2


e RC0/T1OSO/T1CKI se tornam entradas para a inserção de um cristal oscilador.

T1CKPS1/T1CKPS0 - Seleção de prescaler da fonte de clock do Timer1

00 - 1:1
01 - 1:2
10 - 1:4
11 - 1:8

T1OSCEN - Bit de controle de habilitação de Oscilador do Timer1.

1 - Oscilador é habilitado
0 - Oscilador desligado

T1SYNC - Bit de controle de Sincronização com o clock externo.

Caso T1OSCEN = 1:

1 - Não há sincronia com o clock externo


0 - Sincronia com o clock

Caso T1OSCEN = 0:

O bit é ignorado. Uso do clock interno.

TMR1CS - Fonte de clock do Timer1

1 - Clock externo
0 - Clock Interno

47 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

TMR1ON - Habilida/desabilita o Timer1

1 - Habilitado
0 - Desabilitado

MODO TEMPORIZADOR

Modo de temporizador é selecionado por limpar o bit TMR1CS(T 1CON < 1 >). Neste
modo, o relógio de entrada para o temporizador é FOSC / 4. O bit de controle de sincronização,
T1SYNC(T 1CON < 2 >), não tem qualquer efeito, uma vez que o relógio interno está
sempre em sincronia.

Cálculo para interrupção em 1 segundo.

16
BaseT emporal = P eriodoclock ∗P reescaler∗(2 −T M R1H : T M R1L)

BaseT emporal = 0, 2 ∗ 4 ∗ 12500 = 10000us

Estude o código exemplo abaixo sob efeito da interrupção

int contagem;

void interrupt(){
contagem++;
TMR1L=0x2C;
TMR1H=0xCF;
PIR1.TMR1IF=0;
}

void main(){
INTCON.GIE=1;
INTCON.PEIE=1;
PIE1.TMR1IE=1;

TMR1L=0x2C;
TMR1H=0xCF;
T1CON=0b00100001;

while (1){
if(contagem==100){
48 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

portb.RB0=~portb.RB0;
}

O código acima descreve a utilização do Timer1 e tratamento de interrupção causado pelo


mesmo. O objetivo é alterar o estado lógico do bit RBO a cada segundo sem usar a instrução
delay. Com essa operação, a unidade de processamento poderá realizar atividades em paralelo
e ser mais produtiva.

Questão a responder

1. Comente o código acima instrução por instrução.

2. Use o código acima e escreva um novo código para leitura de dados de dois sensores
analógicos a cada 2 segundos.

Aplicação

Considere uma atividade com robô móvel de duas rodas em eixo diferencial como mostrado
abaixo. Para realizar o movimento do robô do ponto A para B utilize a aplicação de PWM pa-
ra as duas rodas. Use para modular a intensidade de cada PWM o sensor de posição angular
(potenciômetro).

49 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

5) Protocolo USART

O protocolo de comunicação USART (Universal Synchronous Asynchronos Reciever Transmitter)


é uma alternativa de comunicação serial entre periféricos externos, outros microcontroladores
e PCs.

O USART pode ser configurado como um sistema assíncrono de dupla direção (Full-duplex) ou
como um sistema síncrono de uma direção (half-duplex).

O bit SPEN (RCST A < 7 >) e os bits T RISC < 7 : 6 > tem que ser configurados a
fim de realizarem as tarefas RC6/T X/CK and RC7/RX/DT , respectivamente.

Os procedimentos a seguir tratam apenado uso do módulo para aplicações com comu-
nicação assíncrona.

Bit 7: CSRC - bit de seleção de fonte de clock. Não importa o valor binário.

Bit 6: TX9 - bit de habilitação de transmissão do nono dígito.


1 - 9 bits transmitidos
0 - 8 bits transmitidos

Bit 5: TXEN - bit de habilitação de transmissão


1 - habilita a transmissão
50 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

0 - desabilita a transmissão

Bit 4: SYNC - bit de seleção de modo


1 - Síncrono
0 - Assíncrono

Bit 2: BRGH - bit de seleção de velocidade de Baud Rate.


1 - Alta
0 - Baixa

Bit 1: TRMT - bit de estado do deslocador para transmissão de dado


1 - vazio
0 - cheio

Bit 0: TX9D - bit de paridade

Bit 7: SPEN - bit habilita o Port Serial


1 - Configura RC7/RX/DT e RC6/TX/CK como pinos seriais
0 - desabilita porte serial

Bit 6: RX9 - bit de habilitação de recebimento do nono dígito.


1 - 9 bits para recebimento
0 - 8 bits para recebimento

Bit 5: SREN - bit de habilitação recebimento simples


Não importa o valor do bit

Bit 4: CREN - bit habilita recebimento contínuo de bits


1 - habilita recebimento contínuo de bits
0 - desabilita recebimento contínuo de bits

Bit 3: ADDEN - bit de habilitação de endereço detectado. (RX9=1)


1 - permite detecção de endereço
0 - todos os Bytes são recebidos e o nono bit pode ser usado como bit de paridade

51 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

Bits < 2 : 0 > - Flags para frame, overrun error e nono bit recebido.

Estudo de caso: Projeto SKYLINE por Douglas Macedo Cruz.

Este foi um trabalho desenvolvido com os conhecimentos adquiridos durante o curso de


microcontroladores e suas aplicações com o objetivo de realiza controle e monitoramento
de níveis de fluidos através de sensores ativos, microcontroladores e sistemas de saída de
potência. O trabalho foi concluído com êxito mostrando diversas possibilidades de utilização e
programação dos PICs.

Realizar uma estrutura utilizando canos de PVC, galões de água, válvulas, sensores, microcontro-
ladores e outros periféricos para que se faça a geração da energia oriunda do descarte de esgoto
em condomínios. Cálculos de Timer0, baudrate para transmissão USART e PWM foram realiza-
dos com o intuito de que projeto tenha um melhor aproveitamento da energia cinética e elétrica.

Com o intuito de realizar um controle e monitoramento do sistema da figura abaixo, foi


utilizado dois PIC, um da família 16f887a e outro 16f873a e vários outros periféricos.

52 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

Na programação dos PICs foi definido que o "Master" será o PIC16f887A responsável pela
conversão A/D e transmissão assíncrona via RX TX e o PIC16f873A foi definido como "Slave"
e responsável por receber essa transmissão assíncrona via RX TX do "Master" e converter em
PWM, o Slave também tem a função de realizar leitura nos sensores via interrupção por Timer.

Abaixo são mostrados, em ambiente de simulação, os esquemáticos de circuitos para este pro-
cesso.

53 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

Código para transmissão de dados analógicos

54 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

#pragma config FOSC = XT


#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config BOREN = OFF
#pragma config LVP = OFF
#pragma config CPD = OFF
#pragma config WRT = OFF
#pragma config CP = OFF

#include <xc.h>
#include <pic16f877a.h>

#define _XTAL_FREQ 20000000

//Configuração inicial do conversor A/D

void ADC_config()
{
ADCON0bits.ADCS = 0b10;
ADCON0bits.CHS = 0b000;
ADCON1bits.ADFM = 0;
}
void Interrupt_ADC(){
PIR1bits.ADIF = 0;
PIE1bits.ADIE = 1;

INTCONbits.GIE = 1;
INTCONbits.PEIE = 1;

ADCON0bits.ADON = 1;
}
unsigned int Entrada(unsigned char channel)
{
GO_nDONE = 1;
while(GO_nDONE);
return ((ADRESH<<8)+ADRESL);

}
//Variavel inteira sem sinal e caractere em C sem sinal

//calculo da taxa de transferência


//e diz se vai ser low ou high baud

55 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

//rate atribuido ao caractere

char UART_Init(const long int baudrate)


{
unsigned int x;
x = (_XTAL_FREQ - baudrate*64)/(baudrate*64);
if(x>255)
{
x = (_XTAL_FREQ - baudrate*16)/(baudrate*16);
BRGH = 1;
}
if(x<256)
{
SPBRG = x;
SYNC = 0;
SPEN = 1;
TRISC7 = 1;
TRISC6 = 1;
CREN = 1;
TXEN = 1;
return 1;
}
return 0;
}

// enviando dados...
void UART_Write(char dado)
//Escrevendo em estrutura de caractere
{
while(!TRMT);
TXREG = dado;
}

char UART_TX_Empty()
{
return TRMT;
}
void UART_Write_Text(char *text)
//esccreve um texto que for colocado
//na função. É conseguido através do
//uso contínuo da função UART_Write ().
{

56 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

int i;
for(i=0;text[i]!=’\0’;i++)
UART_Write(text[i]);
}

// recebendo dados...
//A função (UART_Data_Ready) ele
//usa o bit de sinalizador RCIF
//que será definido quando a recepção
//de dados for concluída.
char UART_Data_Ready()
{
return RCIF;
}
char UART_Read()
//espera até que os dados
//de 8 bits do registro de
//recebimento tenha terminado
{
while(!RCIF);
return RCREG;
}

void main()
{
TRISA = 0xFF;
TRISB = 0x00;
ADC_config();
Interrupt_ADC ();
UART_Init(19200);
//UART_Write_Text ("E N G E N H A R I A
//M E C A T R O N I C A");
do
{
unsigned int a;
a = Entrada(0);
UART_Write(a>>8);
__delay_ms(100);

}while(1);
}

57 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

Código para recebimento de dados analógicos

#pragma config FOSC = XT


#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config BOREN = OFF
#pragma config LVP = OFF
#pragma config CPD = OFF
#pragma config WRT = OFF
#pragma config CP = OFF

#include <xc.h>
#include <pic16f877a.h>

#define _XTAL_FREQ 20000000

void PWM ()
{
PR2 = 0xFF;
//valor que pode ir de
//0 a 255 para dizer o
//período

TRISCbits.TRISC2=0;
T2CON = 0x4;
CCP1CON = 0xC;

}
//calculo da taxa de transferência e
//diz se vai ser low ou high baud rate
atribuído ao caractere
char UART_Init(const long int baudrate)
//Numero inteiro longo que não
//pode ser mudado por função
{
unsigned int x;
x = (_XTAL_FREQ - baudrate*64)/(baudrate*64);
if(x>255)
{
x = (_XTAL_FREQ - baudrate*16)/(baudrate*16);
BRGH = 1;

58 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

}
if(x<256)
{
SPBRG = x;
SYNC = 0;
SPEN = 1;
TRISC7 = 1;
TRISC6 = 1;
CREN = 1;
TXEN = 1;
return 1;
}
return 0;
}

// enviando dados...
void UART_Write(char dado)
//Escrevendo em estrutura de caractere
{
while(!TRMT);
TXREG = dado;
}

char UART_TX_Empty()
//Verificando o registrador de
//Transmissão se está vazio
{
return TRMT;
}
void UART_Write_Text(char *text)
//esccreve um texto que for colocado
//na função. É conseguido através do
//uso contínuo da função UART_Write().

{
int i;
for(i=0;text[i]!=’\0’;i++)
UART_Write(text[i]);
}

// recebendo dados...
//A função (UART_Data_Ready) ele usa

59 60
Flavio Bispo Laboratório de Microcontroladores e Aplicações 16F873A

//o bit de sinalizador RCIF que será


//definido quando a recepção de dados
//for concluída.

char UART_Data_Ready()
{
return RCIF;
}
char UART_Read()
//espera até que os dados de 8
//bits do registro de recebimento
//tenha terminado
{
while(!RCIF);
return RCREG;
}
void main()
{
TRISB = 0x00;
UART_Init(19200);
PWM();
do
{

if(UART_Data_Ready())
CCPR1L = UART_Read();
__delay_ms(100);

while(1);
}

60 60

Anda mungkin juga menyukai