LusoRobótica - Robótica em Português
Sistemas específicos => 8051 => Tópico iniciado por: MariaET em 13 de Janeiro de 2010, 14:29
-
Olá a todos!
Estou a usar uns módulos da texas o cc2431 que têm um 8051 lá dentro. É a primeira vez que estou a utilizar este microcontrolador e estou a ter problemas em ler os valores da ADC. Estou a utilizar o IAR workbench e a tentar ler um valor no pino P0_0, com uma resolução de 12 bits e uma tensão de refeência interna de 1.25V. O código que usei é o seguinte. Alguém me pode dar uma mãozinha e dizer o que estou a fazer de errado? Obrigada!
unsigned int canalT;
do {
ADCCFG = 0x01;
ADCCON2 = 0x30;
ADCCON1 = 0x73;
while(!(ADCCON1 & 0x80));
canalT = ADCL;
canalT |= (((unsigned int)ADCH) << 8 );
} while(0);
canalT >>= 4;
-
Olá e Bem-vinda Maria.
Estive a olhar para o código e não conhecendo a arquitectura, não sei o que são aqueles bytes de configuração com que estás a afectar as variáveis de sistema, contudo creio que o código não está completo. Estás a ler o valor de canalT em debug após finalizar a execução de todo o código?
Onde tens a finalização do mesmo para garantir que não ficam em loop?
De qualquer das formas, e tendo em conta que o ADCCON1 passa pelo valor 0x80 antes de o ADC estar pronto para ser lido, tudo o resto faz sentido.
Desculpa não ser grande ajuda mas é o melhor que posso fazer de momento.
unsigned int canalT;
do {
ADCCFG = 0x01;
ADCCON2 = 0x30;
ADCCON1 = 0x73;
while(!(ADCCON1 & 0x80));
canalT = ADCL;
canalT |= (((unsigned int)ADCH) << 8 );
} while(0);
canalT >>= 4;
PS - não é ADCON2 em vez de ADCCON2 ?
-
Olá Tiago!
Antes de mais obrigada pla tua resposta. De facto o código não está completo, eu estou a ler o valor de canalT. O resto do código são apenas umas contas sobre o valor de canalT e o retorno deste.
O while(!(ADCCON1 & 0x80)); significa "enquanto a conversão não terminar".
-
Podes postar o link para o datasheet?
-
Olá metRo_!
O datasheet podem sacar aqui: http://dl.dropbox.com/u/2409862/cc2430.pdf (http://dl.dropbox.com/u/2409862/cc2430.pdf)
Obrigada!
-
Estive a confirmar a mascara do ADCCON1 parece correcta.
ADCCON2 também parece correcto para os 12 bits com referencia interna e AIN0 como pin de leitura.
Já a ler o ADCL só os 2 bits da direita é que não têm valor válido e estão sempre a zero logo seria:
canalT = ADCL>>2; //para ignorar os 2 bits sem valor
canalT |= (((unsigned int)ADCH) << (8-2) );
Estás a obter valores inválidos? está a bloquear o código? o que está a acontecer?
-
Estou a obter valores inválidos. Basicamente tenho um sensor de temperatura ligado. Já tive esse sensor ligado a uma PIC e funciona correctamente. Quando o liguei ao cc2431, após as conversões recebi uma temperatura negativa (e deveria ter recebido uma temperatura à volta dos 20 graus)...
-
Vê a indicação que te dei referente ao ADCL só ter os 2 bits da direita a zero e por isso os shifts estarem diferentes.
-
Vou experimentar isso hoje à tarde, porque de momento não tenho os módulos comigo. Depois digo alguma coisa!
obrigada!
-
Bem, não funcionou...
O meu código completo é o seguinte:
void Temperatura (void)
{
float tensaoT;
float tempZero, tempAmb;
unsigned int canalT;
# define tzero 400.0;
# define tcoef 19.5;
do {
ADCCFG = 0x01; // activa o pino 0 da ADC
ADCCON2 = 0x30; // selecciona o pino 0 da ADC, coloca uma resoluçao de 12 bits e escolhe tensão referencia interna de 1.25V
ADCCON1 = 0x73; // xis
while(!(ADCCON1 & 0x80)); // enquanto a conversão não terminar
canalT = ADCL;
canalT |= (((unsigned int)ADCH) << 8); // canalT = ADCH ADCL
} while(0);
canalT >>= 4; // shift 4 devido aos 12 bits de resolução
tensaoT = canalT * 0.61065; //(1250/2047) -> 1.25V de referencia e 2047 de resoluçao
tempZero = tensaoT - tzero;
tempAmb = tempZero/tcoef;
TestMessage(tempAmb,203);
}
O sensor de temperatura é um MCP9701A. TestMessage é uma função que imprime o valor temAmb numa trama do zigbee. O valor é impresso em hexadecimal.
Imprimindo passo a passo, o valores que me aparecem são:
canalT = 0x114 = 276 em decimal
tensaoT = 0xAC = 172 em decimal
tempZero = 0xFF1B -> aqui como subtraio 400 dá um valor negativo (digo eu)
tempAmb = 0xFFF5 -> este também deve ser o valor negativo
Com as alterações que propuseste aparecia o seguinte:
canalT = 0x46 = 70 em decimal;
tempAmb = 0xFFEE
-
Bem, já sei qual era o problema!
O código está correcto. O problema estava na tensão de referência. Eu estava a usar 1.25V de referência, mas o sensor estava a mandar uma tensão superior, logo a ADC saturava!
Obrigada na mesma pessoal!
-
Ainda bem que ficou resolvido. Boa sorte para o projecto ;)