Ir ao conteúdo

Leitura errada em termometro


joseca

Posts recomendados

Postado

Simulei o codigo abaixo no ISIS e ocorreu que ele somente esta fazendo a leitura dos graus centigrados pares,os impares não aparecem no lcd.

#include <16f877a.h>
#use delay(clock=16000000)
#fuses xt,put,nowdt,protect,nobrownout,NOLVP,NOCPD
#byte porta = 0x05
#byte portb = 0x06
#byte portc = 0x07
#byte portd = 0x08
#byte porte = 0x09

#include "lcd.c"

char temp;

void main(){

set_tris_a(0x01);
set_tris_b(0x00);
set_tris_c(0x00);
set_tris_d(0x00);
set_tris_e(0x00);
porta = 0x00;
portb = 0x00;
portc = 0x00;
portd = 0x00;
porte = 0x00;

setup_adc_ports(ALL_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);

lcd_init();

for(;{
temp = read_adc();
lcd_putc("\f Pic Termometro ");
printf(lcd_putc,"\n %d%cc",temp,0xdf);
delay_ms(1000);
}
}

#include <16f877a.h>
#use delay(clock=16000000)
#fuses xt,put,nowdt,protect,nobrownout,NOLVP,NOCPD
#byte porta = 0x05
#byte portb = 0x06
#byte portc = 0x07
#byte portd = 0x08
#byte porte = 0x09

#include "lcd.c"

char temp;

void main(){

set_tris_a(0x01);
set_tris_b(0x00);
set_tris_c(0x00);
set_tris_d(0x00);
set_tris_e(0x00);
porta = 0x00;
portb = 0x00;
portc = 0x00;
portd = 0x00;
porte = 0x00;

setup_adc_ports(ALL_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);

lcd_init();

for(;{
temp = read_adc();
lcd_putc("\f Pic Termometro ");
printf(lcd_putc,"\n %d%cc",temp,0xdf);
delay_ms(1000);
}
}

Descupem,saiu duplicado!!!!!!!

Postado

Seu código está incorreto.

Tente com o abaixo e repare nas diferenças. Marquei em vermelho.

pic_termometro_impar.png

Código:

#include <16F877A.h>
[B][COLOR="Red"]#device adc=10[/COLOR][/B]

#FUSES NOWDT
#[B][COLOR="Red"]FUSES HS[/COLOR][/B]
#FUSES PUT
#FUSES NOPROTECT
#FUSES NODEBUG
#FUSES BROWNOUT
#FUSES NOLVP
#FUSES NOCPD

[B][COLOR="Red"]#use delay(clock=16000000)[/COLOR][/B]

#include <lcd.c>

int16 ad;
[B][COLOR="Red"]float temp;[/COLOR][/B]

void main()
{
setup_adc_ports(AN0);
[B][COLOR="Red"]setup_adc(ADC_CLOCK_DIV_32);[/COLOR][/B]
set_adc_channel(0);
[B][COLOR="Red"]delay_us (20);[/COLOR][/B]

lcd_init();

for(;
{
ad = read_adc();

[B][COLOR="Red"]temp = (ad*5*100)/1024.0;[/COLOR][/B]

lcd_putc("\f Pic Termometro ");
printf(lcd_putc,"\n [B][COLOR="Red"]%3.0f[/COLOR][/B]%cc",temp,0xdf);
delay_ms(1000);
}
}

Falou

  • 3 meses depois...
Postado

mateus, poderia tirar uma duvida minha aqui.

nesta parte do codigo aqui.

  for(;
{
ad = read_adc();

temp = (ad*5*100)/1024.0; <= aqui

lcd_putc("\f Pic Termometro ");
printf(lcd_putc,"\n %3.0f%cc",temp,0xdf); <= e aqui
delay_ms(1000);
}

pra que o (vezes 100) ?

e na parte de baixo ai, na parte do printf, ( %3.0f %cc", temp,0xdf )

sei que no C ai o %f é pra exibir variavel float, e que o %c para caractere

mas e esse %cc, e depois o que é o 0xdf

Postado
pra que o (vezes 100) ?

No datasheet do LM 35 diz que sua resposta é de 10mV/°C. Mas o PIC lê em volts. Veja essa regra:

Para cada 1°C --------> 10mV ou 0.01V

X. --------> tensão lida pelo PIC.

Exemplo:

1 °C -----> 0.01V

X. -----> 0.25V

X = 0.25 / 0.01

X = 25°C.

Veja que a leitura da tensão pelo PIC é realizado por 5*AD/1023.

Aí no final ou você divide por 0.01 ou multiplica por 100. Dá no mesmo.

mas e esse %cc, e depois o que é o 0xdf

Simples. %cC está dizendo que no LCD aparecerá um char seguido pela letra C. Esse char que será impresso é representado por 0xdf que nada mais é que o simbolo de graus (°).

Falou

Postado

..... e por falar nisso .....

Uma coisa que nunca percebi bem é a função "setup_adc(modo)" Normalmente uso "setup_adc(ADC_CLOCK_INTERNAL);", tal como o JOSECA postou. Mas tenho visto que o Matheus sempre usa "setup_adc(ADC_CLOCK_DIV_32);". Qual a diferença?? ou de um modo geral, em quê que isso influencia na conversão??

Postado

Só complementando o que o colega vtrx disse:

O conversor AD tem um tempo mínimo para executar a conversão. Está no datasheet como título de A/D Acquisition Requirements

Lá ele explica exatamente como calcular o tempo (normalmente 16uS). Nesse caso, você precisa configurar o AD de acordo com o clock do PIC. Exemplo do datasheet do 16F877X:

tabala_AD_tempo_16F877.png

Aí lá no CCS, temos as seguintes opções de configuração da velocidade de conversao do AD:

////////////////////////////////////////////////////////////////// ADC
// ADC Functions: SETUP_ADC(), SETUP_ADC_PORTS() (aka SETUP_PORT_A),
// SET_ADC_CHANNEL(), READ_ADC()
// Constants used for SETUP_ADC() are:
#define ADC_OFF 0 // ADC Off
#define ADC_CLOCK_DIV_2 0x10000
#define ADC_CLOCK_DIV_4 0x4000
#define ADC_CLOCK_DIV_8 0x0040
#define ADC_CLOCK_DIV_16 0x4040
#define ADC_CLOCK_DIV_32 0x0080
#define ADC_CLOCK_DIV_64 0x4080
#define ADC_CLOCK_INTERNAL 0x00c0 // Internal 2-6us

Aí você escolhe de acordo com o cristal.

No datasheet explica tudo nos detalhes.

Postado

.... vamos lá ver se entendi ....

Estou a me bater no 18F4520. No datasheet diz que o tempo minimo é de 2.4us. Diz também que o TAD deve ser o menor possível mas maior que o mínimo (isso complicou um pouco, mas ok). Daí fui para o CCS, configurei o PIC pra 8MHz (interno) e escolhi clock de 4us que é o menor acima do mínimo. isso resulta em setup_adc(ADC_CLOCK_DIV_8). Será que é essa a linha de raciocinio??

Mas tem outro problema, para o 18f4520 para além da escolha do clock ele permite escolher o tempo de aquisição, onde também escolhi 4us e ficou assim setup_adc(ADC_CLOCK_DIV_8|ADC_TAD_MUL_8);. Mas qual a diferença entre essas duas opções? parece a mesma coisa com nome diferente :confused:

E por outra, usando o clock interno o tempo fica entre 2-6us, isso seria um problema porque o tempo mínimo é menor que o mínimo requerido, certo?

...... Devido a problemas linguísticos não sei se interpretei bem o datasheet .....

Postado
.... configurei o PIC pra 8MHz (interno) e escolhi clock de 4us que é o menor acima do mínimo. isso resulta em setup_adc(ADC_CLOCK_DIV_8). Será que é essa a linha de raciocinio??

Isso mesmo. Mais fácil ainda se você olhar apenas para a tabela. Veja onde circuleei em vermelho:

AcquisitionRequirements_18F4520.png:original

De acordo com a imagem, se o clock for de até 11.43Mhz, você usa o clock dividido por 8.

Mas tem outro problema, para o 18f4520 para além da escolha do clock ele permite escolher o tempo de aquisição, onde também escolhi 4us e ficou assim setup_adc(ADC_CLOCK_DIV_8|ADC_TAD_MUL_8);. Mas qual a diferença entre essas duas opções?

Bom Leo, nessa você me apertou. Desconheço esse comando aí. Mas fiz uma pesquisa e vi que parece ser o comando para configuração automática do tempo, veja:

Delay when using the ADC

Ahhh e também tenho problemas em entender por completo o datasheet dos PICs. Tudo muito confuso pra mim.

Falou

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!