Ir ao conteúdo

Problema ADC PIC16F690


edu.

Posts recomendados

Postado

Bom, eu nunca usei ADC. Dei uma lida no datasheet do pic e com PICwizard do CCS tentei fazer um convesor. A ideia era converter o valor e jogar um LCD. Só que ele fica escrevendo diversos numeros meio que aleatorios no LCD sendo que eu liguei o pino do ADC no GND, deveria marcar 0!

Aqui segue o código, e as ligações devem estar corretas, pois o LCD funciona corretamente.


#define LCD_DB7 PIN_A2
#define LCD_DB6 PIN_C0
#define LCD_DB5 PIN_C1
#define LCD_DB4 PIN_C2
#define LCD_E PIN_B4
#define LCD_RS PIN_B5
#include "flex_lcd.c"


unsigned int8 aux;


void main()
{

setup_adc_ports(sAN8|VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
//Setup_Oscillator parameter not selected from Intr Oscillotar Config tab

// TODO: USER CODE!!
lcd_init();
set_adc_channel(8);
printf(lcd_putc,"adc=");
while(1)
{
aux=read_adc();
lcd_gotoxy(5,1);
printf(lcd_putc,"%3u",aux);
delay_ms(500);
}
}
#include "C:\Arquivos de programas\PICC\Projects\main.h"

EDIT:

Olhando bem pro lcd, ele alterna entre 4 valores, aleatoriamente:

0,64,128,192

Postado

Bem edu, para começar, sempre quando postar um código, poste ele completo. No início do seu post tá assim:

C:\Arquivos de programas\PICC\Projects\main.h"

O que seria esse main.h? Sei que são os fuses e as velocidade do PIC, mas não tenho como adivinhar eles. Dessa forma fiz um exemplo do zero aqui:

Circuito:

semttuloiyw.png

Código:

#include <16F690.h>
#device adc=10
#fuses NOWDT,PUT,NOMCLR,NOPROTECT,NOCPD,NOBROWNOUT

#use delay(clock=4000000)

#include <lcd_flex.c>

int16 aux;
float tensão;

void main()
{
lcd_init();

setup_adc_ports(sAN0);
setup_adc(ADC_CLOCK_INTERNAL);

set_adc_channel(0);
delay_us (20);

printf(lcd_putc,"adc=");

while(1)
{
aux=read_adc();
tensão = (aux * 5) /1023.0;
lcd_gotoxy(5,1);
printf(lcd_putc,"%1.3fV",tensão);
delay_ms(500);
}
}

Dúvidas pegunte!

Falou

Postado

São poucas diferenças. O delay de 20us depois de selecionar o channel é necessário mesmo? Pois quando vai-se escrever no lcd ja se gasta 40uS de qualquer jeito. Uma coisa é esse #device adc, que no meu está =16. No datasheet diz que é 10 bits, mas nao sabia como era pois nunca tinha usado. De resto você só faz a conversão de divisões pra volts, eu nao fiz pois queria primeiro o basicão.

Vou fazer mais testes. Porque usa sAN0? e não somente AN0? Se for mais de um pino que eu queira ativar, como faz?

EDIT: tem como usar o pic wizard e ele deixar os fuses no codigo principal?

EDIT2: fiz os testes e o problema era o #device adc=16, tem que colocar 10, que é o conversor que esse pic utiliza. De resto estava tudo OK. Para converter da escala normal para tensão basta fazer uma regra de três simples. As duvidas acima seguem.

Postado

Boas dúvidas. São simples, mas como você mesmo disse é o basicão para não ter problemas futuros. Vamos lá:

O delay de 20us depois de selecionar o channel é necessário mesmo? Pois quando vai-se escrever no lcd ja se gasta 40uS de qualquer jeito.

Sim. Não me lembro onde li, se foi no datasheet ou no forum do compilador mas é necessário esse tempo. Mesmo ele gastando o tempo para escrever, antes você tem q setar o canal q você vai ler. E é o tempo necessário para comutação.

Porque usa sAN0? e não somente AN0?

Essa é uma boa questão.

Cada PIC tem uma forma correta de selecionar o canal ADC. Em alguns é simplesmente AN0 e em outros é sAN0. Para saber qual utilizar. Sempre procuro pelo arquivo de cabeçalho do PIC, que nesse exemplo é o 16F690.h. Esses arquivos se encontram na pasta PICC>Devices.

Nesse arquivo .h tem todas as configurações possíveis para cada PIC inclusive os fuses aceitos em cada um. Por exemplo para configurar o canal ADC. Abra o arquivo e procure lá no final por isso:

// Constants used in SETUP_ADC_PORTS() are:
#define sAN0 1 //| A0
#define sAN1 2 //| A1
#define sAN2 4 //| A2
#define sAN3 8 //| A4
#define sAN4 16 //| C0
#define sAN5 32 //| C1
#define sAN6 64 //| C2
#define sAN7 128 //| C3
#define sAN8 0x10000 //| C6
#define sAN9 0x20000 //| C7
#define sAN10 0x40000 //| B4
#define sAN11 0x80000 //| B5
#define NO_ANALOGS 0 // None
#define ALL_ANALOG 0xF00FF // A0 A1 A2 A4 C0 C1 C2 C3 C6 C7 B4 B5

Veja que você pode escolher os canais mostrados acima.

Para um 18F4550 temos:

// Constants used in SETUP_ADC_PORTS() are:
#define NO_ANALOGS 0x0F // None
#define ALL_ANALOG 0x00 // A0 A1 A2 A3 A5 E0 E1 E2 B2 B3 B1 B4 B0
#define AN0_TO_AN11 0x03 // A0 A1 A2 A3 A5 E0 E1 E2 B2 B3 B1 B4
#define AN0_TO_AN10 0x04 // A0 A1 A2 A3 A5 E0 E1 E2 B2 B3 B1
#define AN0_TO_AN9 0x05 // A0 A1 A2 A3 A5 E0 E1 E2 B2 B3
#define AN0_TO_AN8 0x06 // A0 A1 A2 A3 A5 E0 E1 E2 B2
#define AN0_TO_AN7 0x07 // A0 A1 A2 A3 A5 E0 E1 E2
#define AN0_TO_AN6 0x08 // A0 A1 A2 A3 A5 E0 E1
#define AN0_TO_AN5 0x09 // A0 A1 A2 A3 A5 E0
#define AN0_TO_AN4 0x0A // A0 A1 A2 A3 A5
#define AN0_TO_AN3 0x0B // A0 A1 A2 A3
#define AN0_TO_AN2 0x0C // A0 A1 A2
#define AN0_TO_AN1 0x0D // A0 A1
#define AN0 0x0E // A0
#define AN0_TO_AN11_ANALOG 0x03 //!old only provided for compatibility
#define AN0_TO_AN10_ANALOG 0x04 //!old only provided for compatibility
#define AN0_TO_AN9_ANALOG 0x05 //!old only provided for compatibility
#define AN0_TO_AN8_ANALOG 0x06 //!old only provided for compatibility
#define AN0_TO_AN7_ANALOG 0x07 //!old only provided for compatibility
#define AN0_TO_AN6_ANALOG 0x08 //!old only provided for compatibility
#define AN0_TO_AN5_ANALOG 0x09 //!old only provided for compatibility
#define AN0_TO_AN4_ANALOG 0x0A //!old only provided for compatibility
#define AN0_TO_AN3_ANALOG 0x0B //!old only provided for compatibility
#define AN0_TO_AN2_ANALOG 0x0C //!old only provided for compatibility
#define AN0_TO_AN1_ANALOG 0x0D //!old only provided for compatibility
#define AN0_ANALOG 0x0E //!old only provided for compatibility

// The following may be OR'ed in with the above using |
#define VSS_VDD 0x00 // Range 0-Vdd
#define VREF_VREF 0x30 // Range VrefL-VrefH
#define VREF_VDD 0x20 // Range VrefL-Vdd
#define VSS_VREF 0x10 // Range 0-VrefH

Viu a diferença? Para o 18F4550, usa-se apenas AN0

Se for mais de um pino que eu queira ativar, como faz?

Uma coisa curiosa que pude ver no 16F690 é que ele não possui opção de ler mais de um canal analógico direto. Engraçado. Pois por exemplo, se for no 18F4550, se você quiser ler 3 canais analógicos, você usa:

SETUP_ADC_PORTS(AN0_TO_AN2);

E para ler cada pino você faz de modo genérico:

set_adc_channel(0);     \\Escolhe o canal 0   
delay_us (20);
aux_0=read_adc();

set_adc_channel(1); \\Escolhe o canal 1
delay_us (20);
aux_1=read_adc();

set_adc_channel(2); \\Escolhe o canal 2
delay_us (20);
aux_2=read_adc();

tem como usar o pic wizard e ele deixar os fuses no codigo principal?

Nunca usei o PICWizard. Então não posso afirmar. Mas acredito que tenha sim. Normalmente coloco os fuses no braço mesmo.

Para converter da escala normal para tensão basta fazer uma regra de três simples.

Exato. Uma regra de três. Mas veja que tem toda uma teoria por tras. Algo assim:

/*===========================================================================
A resolução do conversor AD segue a seguinte equação:
1LSB=(Vref-)+{[(Vref+)-(Vref-)]/1024}
E nesse caso (Vref+)=Vdd e (Vref-)=Vss então a resolução é:
1LSB=5/1024=4,8mV
Por exemplo, se a leitura no canal analógico for de 512, a tensão
analógica será:
Vin=512*(5/1024)=512*4,8mV=2,4576V
===========================================================================*/

Tá aí...

Qualquer coisa, só perguntar!

Falou

Postado

Quanto a selecionar mais de um canal eu estava dizendo no caso o comando setup. MAs é só colocar | (or) porque cada define seta um bit do registrador, da pra ver bem certim. Ba, valeu mesmo cara. Por enquanto tudo ok com os analógicos. Duvida mais que sanada, muito obrigado fera!

EDIT: Fuçar no header file é o ouro!!!! Brigadão. Por mim pode feixar.

  • Coordenador
Postado

Caso o autor do tópico necessite, o mesmo será reaberto, para isso deverá entrar em contato com a moderação solicitando o desbloqueio.

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!