LusoRobótica - Robótica em Português

Sistemas específicos => PIC => Tópico iniciado por: FCarvalho5555 em 17 de Junho de 2013, 14:10

Título: ADC + UART
Enviado por: FCarvalho5555 em 17 de Junho de 2013, 14:10
Boas pessoal, sou novo nestas andanças de pic e estou com umas duvidas.

Estou a fazer um projecto que é um sensor de temperatura utilizando o pic16F887 e o LM335AZ, já tenho os registos da ADC, SFR e uma função que envia uma String para a porta UART a funcionar correctamente.
Para fazer debug se o canal ADC esta a funcionar passo o valor do ADRESH para o led's da portoD (estou a utilizar PICKit 2) e vejo os led's a acender, ou seja, está a converter o valor, a minha duvida é como faço para ir buscar os outros dois bits do ADRESL e enviar para a UART.

Penso que seja assim:
int resultado = (ADRESH << 8 ) + ADRESL;

writeUART(resultado)

função wirteUART:
void writeUART(const char *data)
{
   do
   {   
   while(!TXIF);
   TXREG = *data;
   } while( *data++ );
}

Mas nao me aparece nada no putty, ao fazer a compilação do codigo da-me um aviso do tipo warming Interger to char converter.
Título: Re: ADC + UART
Enviado por: beirao em 17 de Junho de 2013, 16:25
em vez de int resultado = (ADRESH << 8 ) + ADRESL;

mete

unsigned int resultado = (ADRESH) ;
resultado = (ADRESH <<8  );
resultado = (unsigned int) ((resultado & 0xFF00) | (ADRESL & 0x00FF));

(não tenho aqui nenhum compilador, mas penso que está bem)
Título: Re: ADC + UART
Enviado por: FCarvalho5555 em 17 de Junho de 2013, 17:03
Desde ja obrigado pela ajuda :)

Não deu erro nenhum ao compiler, estou a utilizar o Hi-Tech.
Agora como faço para enviar o resultado via UART para o PC ? Visto que só consigo enviar char
Título: Re: ADC + UART
Enviado por: beirao em 17 de Junho de 2013, 17:23
uso o que já tinhas. essa função nao enviar só char.. ela aponta para o 1º byte da variavel que recebe, e depois incrementa (através do while(*data++) )

experimentar enviar e vais ver que funciona ;) ou nao? :P
Título: Re: ADC + UART
Enviado por: FCarvalho5555 em 17 de Junho de 2013, 17:46
Vou colocar aqui a função de atendimento as interrupções:
void interrupt isr()
{   
   //Verifica se a interrupção foi gerado pela ADC
   if(ADIF == 1)
   {
      resultado = (ADRESH);
      resultado = (ADRESH <<8);
      resultado = (unsigned int) ((resultado & 0xFF00) | (ADRESL & 0x00FF));
      writeUART("Resultado=");
      writeUART(resultado);

      //Reset a flag ADC e volta a colocar GO_DONE a 1
      ADIF = 0;
      GO_DONE = 1;   
   }
}

Em anexo tem um print do putty, nao esta a aparecer valor nenhum :/
Título: Re: ADC + UART
Enviado por: beirao em 17 de Junho de 2013, 19:14
tens razão.

em vez de       
writeUART("Resultado=");
writeUART(resultado);

Experimenta assim:
char str [];
sprintf ( str, "Resultado = %u ", resultado);
while (!TXSTAbits.TRMT); // para saberes que ta livre para enviar
writeUART(str);

se não der, define o tamanho do vector str
Título: Re: ADC + UART
Enviado por: FCarvalho5555 em 17 de Junho de 2013, 20:27
Ja estou a conseguir ver o valor no putty, obrigado:) mas esta a aparecer um um bocado alto :/

47000 ? a minha ADC é de 10 bits, devia aparecer um numero menor ou igual a 1024 nao ?
Título: Re: ADC + UART
Enviado por: beirao em 17 de Junho de 2013, 22:32
Pois, mais de 1024 não pode ser! ;)

Deve ser no "cálculo" do resultado. Mete aí um print do resultado mas a ver em binário. Não envies a palavra resultado, envia só o valor e mete aí os valores binários para ver
Título: Re: ADC + UART
Enviado por: senso em 17 de Junho de 2013, 23:07
Isso não dá para escrever simplesmente só ADRES?
Tenho ideia que já vi um compilador PIC que suporta isso, e assim fica logo o valor de 10 bits como deve ser.
Mas o problema deve ser estares a fazer um cast para unsigned int com com uma máscara 0xFF00 e a guardar num int, que é signed.

Título: Re: ADC + UART
Enviado por: beirao em 17 de Junho de 2013, 23:10
depende do compilador, penso eu.

e o cast está bem feito, a variavel resultado está declarada como unsigned int ;)
Título: Re: ADC + UART
Enviado por: FCarvalho5555 em 18 de Junho de 2013, 01:12
Agora ja esta a dar valores mais concretos, aqui esta o codigo que utilizei.

        if(ADIF == 1)
   {
      PORTD = ADRESH;
      sprintf (str, "%d", ADRESH);
      writeUART(" ADRESH = ");
      writeUART(str);
      sprintf (str, "%d", ADRESL);
      writeUART(" ADRESL = ");
      writeUART(str);
      resultado = high + low;
      sprintf (str, "%d", ADRESH + ADRESL);
      writeUART(" SOMA = ");
      writeUART(str);

      //Reset a flag ADC e volta a colocar GO_DONE a 1
      ADIF = 0;
      GO_DONE = 1;   
   }

Em aenxo segue um print do putty, como o valor da soma do ADRESH e ADRESL como chego a temperatura ?
Título: Re: ADC + UART
Enviado por: beirao em 18 de Junho de 2013, 17:06
Espera lá que isso está mal :p

O teu valor é dado pelos 8 bits do ADRESH e 2bits do ADRESL, fazendo os 10bits. Ou seja, o teu resultado é 11111 11111 11xx xxxx, sendo os bits com numero "1" os que te importam e os que estão com "x" devem ser lido a 0. Portanto, faz:

unsigned int resultado = (ADRESH) ;
resultado = (ADRESH <<8  );
resultado = (unsigned int) ((resultado & 0xFF00) | (ADRESL & 0x00C0));

vê se funciona ;)

Para teres isso em tensão:
O teu valor vai de 0 a 1024 (2^10 = 1024)
o que em termos de tensão corresponde a GND e +Vcc

ou seja, tensão = (resultado/1024)*(+Vcc-GND);
é uma regra de 3 simples ;)
depois, olhando para o datasheet, vê qual a relação V/ºC

Se tiveres alguma dúvida, apita
Título: Re: ADC + UART
Enviado por: FCarvalho5555 em 18 de Junho de 2013, 18:54
Continua a dar valores muito elevados :/

O codigo esta assim:

void interrupt isr()
{
   unsigned int resultado;
   char str [];

   //Verifica se a interrupção foi gerado pela ADC
   if(ADIF == 1)
   {
      PORTD = ADRESH;
      
      resultado = (ADRESH);
      resultado = (ADRESH << 8);
      resultado = (unsigned int)((resultado & 0xFF00) | (ADRESL & 0x00C0));

      sprintf ( str, "Resultado = %u ", resultado);
      writeUART(str);

      //Reset a flag ADC e volta a colocar GO_DONE a 1
      ADIF = 0;
      GO_DONE = 1;   
   }
}

Esta a dar uma valor +- 46000, muito acima do valor máximo da ADC.
Deixo uma imagem do putty e o meu ficheiro C
Título: Re: ADC + UART
Enviado por: senso em 18 de Junho de 2013, 19:02
Porque deves estar a justificar os dados á esquerda, justifica á direita e volta a meter a máscara 0xFF, assim já ficas com os valores entre 0 e 1023
Título: Re: ADC + UART
Enviado por: FCarvalho5555 em 18 de Junho de 2013, 19:15
ja estou a obter uma valor entre 0 e 1024 :)

coloquei uma imagem do putty
Título: Re: ADC + UART
Enviado por: beirao em 19 de Junho de 2013, 10:14
Ok, ainda bem! ;)