LusoRobótica - Robótica em Português
Sistemas específicos => PIC => Tópico iniciado 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.
-
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)
-
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
-
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
-
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 :/
-
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
-
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 ?
-
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
-
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.
-
depende do compilador, penso eu.
e o cast está bem feito, a variavel resultado está declarada como unsigned int ;)
-
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 ?
-
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
-
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
-
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
-
ja estou a obter uma valor entre 0 e 1024 :)
coloquei uma imagem do putty
-
Ok, ainda bem! ;)