Logo Passei Direto
Buscar
Material
páginas com resultados encontrados.
páginas com resultados encontrados.
left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

Prévia do material em texto

UNIALFA – Prof. Eduardo J. Nogueira 
1 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
UNIALFA – Prof. Eduardo J. Nogueira 
2 
CONVERSOR AD INTERNO DOS MICROCONTROLADORES 
PIC 
 
Introdução 
 
Os conversores A/D padrão dos microcontroladores PIC têm uma resolu-
ção máxima de 10 bits, sendo que o clock pode ser selecionado pelo usuário e 
utilizam a técnica de aproximação sucessiva para a conversão. 
Nesta apostila vamos utilizar como exemplo o PIC 16F877A, mas as in-
formações fornecidas se aplicam a qualquer microcontrolador das linhas 12 ou 
16 que possuam conversor AD interno. 
O microcontrolador PIC 16F877A tem um total de 8 entradas para conver-
são de um sinal analógico para digital e estas podem ser configurados conforme 
a tabela abaixo através do registrador ADCON1. 
 
 
 
UNIALFA – Prof. Eduardo J. Nogueira 
3 
Verificamos na tabela também as tensões de referência (VREF+ e VREF-). 
Nesta configuração, a tensão nos pinos configurados será comparada com as 
tensões de referência, sendo que se a tensão aplicada for igual à tensão de re-
ferência VREF+, o resultado da conversão será o máximo (1024) e quando a 
tensão de entrada for igual a VREF-, o resultado será 0. 
As referências podem ser internas (VDD e VSS) ou externas que são co-
nectadas aos pinos RA2 (VREF-) e RA3 (VREF+). 
Temos abaixo uma tabela com os limites elétricos das tensões de referên-
cia. Estes valores precisam ser respeitados: 
 
 
 
Processo de conversão 
Os microcontroladores PIC utilizam internamente um processo de conver-
são conhecido com Sample and Hold (S/H) para evitar problemas de ruído e 
variações na entrada analógica. Este processo consiste na amostra do sinal e o 
congelamento do seu valor. 
No PIC, internamente, existe um capacitor (120pF) ligado ao canal analó-
gico que fica carregado com a tensão existente no canal em uso (amostra) e 
quando o processo de conversão é iniciado, este capacitor é desligado automa-
ticamente do canal analógico e o valor carregado é mantido (congelado) e a ten-
são utilizada no processo de conversão é a tensão existente no capacitor e não 
mais a tensão existente no canal analógico. Este processo faz com que a tensão 
seja mantida durante a conversão mesmo que a tensão externa (no canal ana-
lógico) varie. 
 
Configuração 
SETUP_ADC () // configura o conversor AD interno. 
 
UNIALFA – Prof. Eduardo J. Nogueira 
4 
Sintaxe: 
SETUP_ADC(opções); // opções é uma variável ou constante inteira de 8 bits. 
 
Exemplo: 
SETUP_ADC(ADC_OFF); 
 
As opções podem variar de acordo com o microcontrolador utilizado. Para 
sabermos mais detalhes vamos verificar o arquivo header para o microcontrola-
dor PIC16F877A. Podemos encontrá-lo, geralmente, em ‘C:\Arquivos de Progra-
mas\PICC\Devices\16F877A.h’, dependendo da pasta onde foi instalado o PCW. 
Vamos analisar somente a parte que configura o conversor AD....essa 
parte se encontra na linha 232 do arquivo 16F877A.h. 
 
 
Podemos verificar que as opções disponíveis para o PIC 16F877A são: 
 
SETUP_ADC_PORTS() //Configura as entradas analógicas do conversor AD 
//interno. 
 
Sintaxe: 
UNIALFA – Prof. Eduardo J. Nogueira 
5 
SETUP_ADC_PORTS(opções); //opções é uma variável ou constante inteira 
//de 8 bits. 
 
Essas opções também podem ser encontradas no arquivo header de cada 
microcontrolador. Aqui exemplificamos para o PIC 16F877A. 
Temos abaixo uma tabela com as opções válidas: 
 
 
SET_ADC_CHANNEL() //Seleciona um canal de entrada para o módulo AD. 
 
Sintaxe: 
SET_ADC_CHANNEL(canal); //Onde: canal é uma variável inteira de 8 bits. 
 
Exemplo: 
SET_ADC_CHANNEL(0); //Configura o canal 0 como analógico. 
 
 
READ_ADC() //Inicia a conversão AD e somente retorna o valor após o ciclo 
//de conversão. 
 
Sintaxe: 
ad = READ_ADC(); //Guarda o valor lido na variável ad. 
 
Onde: ad é uma variável inteira de 8 ou 16 bits. 
 
UNIALFA – Prof. Eduardo J. Nogueira 
6 
Podemos utilizar também a diretiva #device ADC = x para especificar o 
número (x) de bits que a função READ_ADC() retornará. 
 
Vamos fazer um exemplo onde o valor de uma conversão será mostrado 
no display LCD. Para isso nosso programa fará a leitura do canal analógico 0 
onde está conectado um trimpot (para variação da tensão a ser convertida, assim 
a tensão na entrada do canal 0 poderá variar de o a +5V. 
 
 
Circuito utilizado para o programa de conversão A/D 
 
 
 
Definições do Projeto: 
 
Nome do Projeto: ADC 
 
Arquivo principal: ADC.c 
 
 
 
RA0/AN0
2
RA1/AN1
3
RA2/AN2/VREF-/CVREF
4
RA4/T0CKI/C1OUT
6
RA5/AN4/SS/C2OUT
7
RE0/AN5/RD
8
RE1/AN6/WR
9
RE2/AN7/CS
10
OSC1/CLKIN
13
OSC2/CLKOUT
14
RC1/T1OSI/CCP2
16
RC2/CCP1
17
RC3/SCK/SCL
18
RD0/PSP0
19
RD1/PSP1
20
RB7/PGD
40
RB6/PGC
39
RB5
38
RB4
37
RB3/PGM
36
RB2
35
RB1
34
RB0/INT
33
RD7/PSP7
30
RD6/PSP6
29
RD5/PSP5
28
RD4/PSP4
27
RD3/PSP3
22
RD2/PSP2
21
RC7/RX/DT
26
RC6/TX/CK
25
RC5/SDO
24
RC4/SDI/SDA
23
RA3/AN3/VREF+
5
RC0/T1OSO/T1CKI
15
MCLR/Vpp/THV
1
U1
PIC16F877A
D
7
1
4
D
6
1
3
D
5
1
2
D
4
1
1
D
3
1
0
D
2
9
D
1
8
D
0
7
E
6
R
W
5
R
S
4
V
S
S
1
V
D
D
2
V
E
E
3
LCD1
LM016L
R1
4k7
5
2
%
1
2
3
RV1
10k
5
0
%
1
2
3
RV2
10k
Volts
+2.50
UNIALFA – Prof. Eduardo J. Nogueira 
7 
 
Código fonte do programa ADC.c escrito no PCW. 
 
 
Neste programa também utilizamos a biblioteca criada pela ACEPIC para 
acesso ao LCD, note a inclusão na linha 9. 
 
#include "LCD8B.c" //Diretiva de inclusão do arquivo LCD8B.c ao projeto 
 
Veja o código escrito no PCW na próxima página. 
 
Bem, como fizemos a inclusão, então é interessante que este arquivo 
(LCD8B.c) esteja também na mesma pasta em que criamos nosso projeto. Caso 
contrário, precisaríamos dar o caminho completo na diretiva #include. 
 
Ex: 
 #include "C:\PROJETOS\LCD_PRO\LCD8B.c" //Diretiva de inclusão do 
//arquivo LCD8B.c ao projeto 
 
 
 8 
UNIALFA – Prof. Eduardo J. Nogueira 
8 
UNIALFA – Prof. Eduardo J. Nogueira 
9 
 
Código do LCD8B.c na janela de edição do PCW. 
 
 
 
Função printf 
 
Neste exemplo a função printf foi utilizada com uma formatação diferente 
da que utilizamos na comunicação serial, neste caso especificamos que o con-
teúdo da variável ad deve ser impresso no formato inteiro longo (long int). 
 
Ex: Linha 26 do código ADC1.c. 
printf(lcd_escreve,"\fADC = %lu",ad); //Mostra a mensagem 'ADC =' + o valor //da 
conversão. 
 
Temos a seguir uma tabela com algumas apresentações de valores e 
seus tipos para a formatação da saída. Esta formatação serve para toda vez que 
a função printf for utilizada, para escrever no LCD ou para comunicação serial 
ou em outra circunstância qualquer. 
 
 
 
UNIALFA – Prof. Eduardo J. Nogueira 
10 
Utilização de mais de um conversor AD 
 
Neste próximo exemplo, faremos a leitura dos canais analógicos 0, 1 e 3, 
sendo que o canal 3 está conectado ao sensor de temperatura LM35. A ventoi-
nha deverá ser ligada logo no início do programa e ao verificar o valor da con-
versão AD no canal 3 menor ou igual a 55, deveremos acionar o aquecimento e 
desligar a ventoinha e quando o valor da conversão AD no canal 3 for maior ou 
igual a 80, desligaremos o aquecimento e ligaremos a ventoinha. 
 
A ventoinha é acionada através do pino RC2 e o aquecedor através do 
pino RC1, conforme esquema abaixo: 
 
 
 
 
Definições do projeto 
 
Nome do Projeto: ADC_Aq 
 
Arquivo : ADC_Aq.c 
 
 
RA0/AN0
2
RA1/AN1
3
RA2/AN2/VREF-/CVREF
4
RA4/T0CKI/C1OUT
6
RA5/AN4/SS/C2OUT
7
RE0/AN5/RD
8
RE1/AN6/WR
9
RE2/AN7/CS
10
OSC1/CLKIN
13
OSC2/CLKOUT
14
RC1/T1OSI/CCP2
16
RC2/CCP1
17
RC3/SCK/SCL
18
RD0/PSP0
19
RD1/PSP1
20
RB7/PGD
40
RB6/PGC
39
RB5
38
RB4
37
RB3/PGM
36
RB2
35
RB1
34
RB0/INT
33
RD7/PSP7
30
RD6/PSP6
29
RD5/PSP5
28
RD4/PSP4
27
RD3/PSP3
22
RD2/PSP2
21
RC7/RX/DT
26
RC6/TX/CK
25
RC5/SDO
24
RC4/SDI/SDA23
RA3/AN3/VREF+
5
RC0/T1OSO/T1CKI
15
MCLR/Vpp/THV
1
U1
PIC16F877A
D
7
1
4
D
6
1
3
D
5
1
2
D
4
1
1
D
3
1
0
D
2
9
D
1
8
D
0
7
E
6
R
W
5
R
S
4
V
S
S
1
V
D
D
2
V
E
E
3
LCD1
LM016L
R1
4k7
5
0
%
1
2
3
RV2
10k
23.0
3
1
VOUT
2
U2
LM35
+
1
2
V
R2
2k2
+
1
2
V
R3
56R
R4
2k2
5
2
%
1
2
3
RV1
10k
Q2
NPN
Q1
NPN
D1
UNIALFA – Prof. Eduardo J. Nogueira 
11 
 
 
Código escrito na janela de edição do PCW. 
 
 
 
Videoaula sobre o conteúdo desta apostila: 
 
https://youtu.be/gIr1LTXB39Y 
 
 
 
 
 
https://youtu.be/gIr1LTXB39Y
UNIALFA – Prof. Eduardo J. Nogueira 
12 
Referências: 
 
ACEPIC – Apostila de linguagem C, padrão CCS para PIC 
 
LUZ, Carlos E. S. – Curso Linguagem C para microcontroladores PIC – Edição 
do autor. 
 
PEREIRA, Fábio - Microcontroladores PIC: Programação em C - Érica 
 
 
UNIALFA – Prof. Eduardo J. Nogueira 
13 
Anexo 1 
 
 
ADC_1.c 
#include<16F877A.h> //Aqui é incluso o header (*.h) para o microcontrolador 
//utilizado. 
 
#device ADC = 10 //Define 10 bits para o resultado da conversão AD 
#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 
#include "LCD8B.c" //Diretiva de inclusão do arquivo LCD8B.c ao projeto 
long int ad; //Variável para armazenamento da conversão 
void main() //Função principal 
{ 
 lcd_ini(); /*Chamada à função lcd_ini()... Esta função é para a inicialização 
 do LCD e está no arquivo LCD8B.c*/ 
 SETUP_ADC_PORTS(RA0_ANALOG); //Configurada a entrada analógica, so-
mente a 
 //entrada RA0 
 SETUP_ADC(ADC_CLOCK_INTERNAL); //Configurado o conversor AD in-
terno 
 SET_ADC_CHANNEL(0); //Configurado o canal de leitura 0 
 printf(lcd_escreve,"\f"); //Limpa lcd 
 printf(lcd_escreve,"\Microcontr."); //Escreve na primeira linha 
 printf(lcd_escreve,"\n UNIALFA "); //Escreve na segunda linha 
 delay_ms(1500); //Atraso de 1,5s 
 while(true) //Loop principal 
 { 
 ad = READ_ADC(); //Faz a conversão AD e a salva na variável ad 
 printf(lcd_escreve,"\fADC = %lu",ad); //Mostra a mensagem 'ADC =' + o 
 //valor da conversão 
 delay_ms(1000); //Atraso de 1s para mostrar a leitura 
 } 
} 
 
 
UNIALFA – Prof. Eduardo J. Nogueira 
14 
Anexo 2 
 
 
ADC_2.c 
#include<16F877A.h> //Aqui é incluso o header (*.h) para o microcontrolador 
//utilizado. 
 
#device ADC = 10 //Define 10 bits para o resultado da conversão AD 
#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 
#include "LCD8B.c" //Diretiva de inclusão do arquivo LCD8B.c ao projeto 
long int ad0,ad1,ad3; //Variáves para armazenamento da conversão 
void main() //Função principal 
{ 
 lcd_ini(); //Chama a função para inicialização do LCD 
 SETUP_ADC_PORTS(RA0_RA1_RA3_ANALOG); //Configura as entradas 
analógicas 
 //RA0,RA1,RA3 
 SETUP_ADC(ADC_CLOCK_INTERNAL); //Configura o conversor AD interno 
 Output_High(PIN_C2); //Liga ventoinha 
 while(true) //Loop principal 
 { 
 SET_ADC_CHANNEL(0); //Configura o canal de leitura 0 
 delay_us(100); //Tempo de ajuste do canal (necessário) 
 ad0 = READ_ADC(); //Faz a conversão AD e a salva na variável ad0 
 printf(lcd_escreve,"\fS0=%lu",ad0); //Mostra valor da conversão do canal 0 
 SET_ADC_CHANNEL(1); //Configura o canal de leitura 1 
 delay_us(100); //Tempo de ajuste do canal (necessário) 
 ad1 = READ_ADC(); //Faz a conversão AD e a salva na variável ad1 
 SET_ADC_CHANNEL(3); //Configura o canal de leitura 3 
 delay_us(100); //Tempo de ajuste do canal (necessário) 
 ad3 = READ_ADC(); //Faz a conversão AD e a salva na variável ad3 
 //Mostra valor da conversão dos canais 1 e 3 
 printf(lcd_escreve,"\nS1=%lu - S3=%lu",ad1,ad3); 
 if (ad3>=80) //Sendo ad3 >= 80... 
 { 
 Output_High(PIN_C2); //Liga ventoinha 
 Output_low(PIN_C1); //Desliga aquecimento 
 } 
 if (ad3<=55) //Sendo <= 55... 
 { 
 Output_High(PIN_C1); //liga aquecimento 
 Output_low(PIN_C2); //Desliga ventoinha 
 } 
 delay_ms(1000); //Atraso de 1 segundo 
 } 
} 
 
UNIALFA – Prof. Eduardo J. Nogueira 
15 
Anexo 3 
 
 
LCD8B.c 
//////////////////// LCD8B.c /////////////////////////////////////////////////// 
//Programa para controle do display LCD por 8 vias do Port D // 
//Este programa foi feito pela ACEPIC, fabricante da maior parte dos kits de // 
//microcontroladores usados em nossos laboratórios no UNIALFA e foi adaptado 
// 
//pelo Professor Eduardo J. Nogueira. // 
//////////////////////////////////////////////////////////////////////////////// 
 
#define EN PIN_E1 //Definimos o pino 1 da porta E como EN 
#define RS PIN_E0 //Definimos o pino 0 da porta E como RS 
#define DATA OUTPUT_D //Definimos a saída para a porta D como DATA 
void lcd_cmd(byte cmd) //Função para envio de comandos para o LCD 
{ 
 DATA(cmd); //Coloca o conteúdo da variável cmd na porta D 
 OUTPUT_HIGH(EN); //Pulso alto (1) no pino EN (Pino 1 da porta E) 
 OUTPUT_LOW(EN); //Retorna a nível baixo (0) em EN 
} 
void lcd_envia_byte(boolean nivel,byte dado) //Função para envio de dados ou 
//escrita para o LCD 
{ 
 OUTPUT_LOW(RS); //Coloca em nível baixo o pino RS (Pino 0 da porta E) 
 OUTPUT_BIT(RS,nivel); //Coloca o pino RS no nível da variável nivel 
 delay_us(100); //Atraso de 100 us 
 OUTPUT_LOW(EN); //Coloca em nível baixo o pino EN 
 lcd_cmd(dado); //Chama a função lcd_cmd já com os dados a serem 
 //enviados para a porta D 
} 
void lcd_pos_xy(byte x, byte y) //Função de posicionamento do cursor 
{ 
 byte endereco; //Variável de informação para o endereço do cursor 
 if (y!=1) //Se o valor de y for 2 
 endereco = 0xC0; //então endereco vai ser igual a 0xC0 (endereço da 
 //segunda linha) 
 else //Senão 
 endereco = 0x80; //endereço vai ser igual a 0x80 (endereço da primeira 
 // linha) 
 endereco += x-1; //Aqui decrementa o valor da variável x e o resultado é 
 //somado com a variável endereço... 
 lcd_envia_byte(0,endereco); //Chama a função lcd_envia_byte, com o valor 0, 
 //informando para o LCD que será enviado um dado e o 
 //dado está contido na variável endereço... 
} 
void lcd_escreve(char c) //Função para envio dos caracteres e/ou dados para o 
// LCD 
{ 
UNIALFA – Prof. Eduardo J. Nogueira 
16 
switch(c) //comando switch com a variável c 
 { 
 case '\f' : lcd_envia_byte(0,1); //Caso c seja ‘\f’, o dado 1 será enviado 
 //ao LCD para limpar todo o seu conteúdo. 
 delay_ms(2); //Atraso de 2 ms 
 break; //Comando break, terminou o processo acima, já 
 //não testa 
 //nenhum outro caso... 
 case '\n' : //Caso c seja ‘\n’ 
 case '\r' : lcd_pos_xy(1,2); //ou ‘\r’, muda o cursor para a segunda linha 
 //do LCD 
 break; //Comando break 
 case '\b' : lcd_envia_byte(0,0x10); //Caso c seja ‘\b’ então desloca o 
 //cursor para a esquerda 
 break; //Comando break 
 default : lcd_envia_byte(1,c); //caso seja um caractere qualquer, então 
 //este será escrito no LCD pela função lcd_envia_byte… 
 break; //Comando break 
 } 
} 
void lcd_ini() //Função de inicialização do LCD 
{ 
 byte conta; //Variável de contagem 
 DATA(0x00); //Coloca na porta D o valor 0x00 
 OUTPUT_LOW(RS); //Coloca em nível baixo o pino RS 
 OUTPUT_LOW(EN); //Coloca em nível baixo o pino EN 
 delay_ms(15); //Atraso de 15ms 
 for (conta=1;conta<=3;conta++) //Executará 3 vezes os comandos abaixo 
 { 
 lcd_cmd(0x30); //Envia o comando 0x30 para o LCD 
 delay_ms(5); //Atraso de 5ms 
 } 
 lcd_cmd(0x38); //Escreve comando para interface de 8 vias de dados 
 lcd_cmd(0x01); //Escreve comando para limpar todo o display 
 delay_ms(1); //Atraso de 1mslcd_cmd(0x0C); //Escreve comando para ligar o display sem cursor 
 lcd_cmd(0x06); //Escreve comando para incrementar automaticamente à di-
reita 
} 
 
 
OBS: Todos os códigos dos anexos pode ser copiado da apostila e colados na 
janela de edição do PCW.

Mais conteúdos dessa disciplina