¿Cómo leer el voltaje negativo del sensor de temperatura LM34 con atmega32?

0

Estoy tratando de leer la temperatura witr LM34 pero solo lee de 0 a 50 F y la rabia de ut se sabe de -50 a +300 F, así que pregunté mucho y encontré que mi circuito a continuación no puede lea un voltaje negativo,

entonces,¿quédebohacerparaleerelvoltajenegativo?Tambiénloencontréporqueusounsolopinparaleerlatemperatura,estohacequesolomidaunpardegrados,notodoslosgrados,asíque¿quédebohacerparaleertodoslosgradosycuálseríaelcódigo?micódigo

#include<util/delay.h>#include<stdio.h>#include<avr/io.h>//defineportC#defineLCD_DDDRDDRC/*LCDDATADDR*/#defineLCD_DPRTPORTC/*LCDDATAPORT*/#defineLCD_DPINPINC/*LCDDATAPIN*///defineportD#defineLCD_CDDRDDRD/*LCDCOMMANDDDR*/#defineLCD_CPRTPORTD/*LCDCOMMANDPORT*/#defineLCD_CPINPIND/*LCDCOMMANDPIN*/#defineLCD_RS0//LCDRS#defineLCD_RW1//LCDRW#defineLCD_EN2//LCDENvoiddelay_us(unsignedintd){while(d){_delay_us(1);d--;}}voidlcdCommand(unsignedcharcmnd){LCD_DPRT=cmnd;//sendcmndtodataportLCD_CPRT&=~(1<<LCD_RS);//RS=0forcommandLCD_CPRT&=~(1<<LCD_RW);//RW=0forwriteLCD_CPRT|=(1<<LCD_EN);//EN=1forH-to-Lpulsedelay_us(1);//waittomakeenablewideLCD_CPRT&=~(1<<LCD_EN);//EN=0forH-to-Tpulsedelay_us(100);//waittomakeenablewide}voidlcdData(unsignedchardata){LCD_DPRT=data;//senddatatodataportLCD_CPRT|=(1<<LCD_RS);//RS=1fordataLCD_CPRT&=~(1<<LCD_RW);//RW=0forwriteLCD_CPRT|=(1<<LCD_EN);//EN=1forH-to-Lpulsedelay_us(1);//waittomakeenablewideLCD_CPRT&=~(1<<LCD_EN);//EN=0forH-to-lpulsedelay_us(100);//waittomakeenablewide}voidlcd_init(){LCD_DDDR=0xff;//allpinsinportCoutputLCD_CDDR=0xff;//allpinsinportDoutputLCD_CPRT&=~(1<<LCD_EN);//LCD_EN=0delay_us(2000);//waitforinitlcdCommand(0x38);//init.lcd2line,5x7matrixlcdCommand(0x0e);//displayon,cursoronlcdCommand(0x01);//clearLCDdelay_us(2000);//waitlcdCommand(0x06);//shiftcursorright}voidlcd_gotoxy(unsignedcharx,unsignedchary){unsignedcharfirstCharAdr[]={0x80,0xc0,0x94,0xd4};lcdCommand(firstCharAdr[y-1]+x-1);delay_us(100);}voidlcd_print(char*str){while(*str){lcdData(*str++);}}intmain(void){charbuffer[3];DDRA|=0b00000111;//pin0,1,2output&pin3,4,5,6,7input.DDRB|=0xFF;//makeportBoutput.ADCSRA|=0x87;//makeADCenableandselectck/128.ADMUX|=0xE6;//2.56vvref,selectADC6andmakeleftjustified.lcd_init();lcd_gotoxy(1,1);lcd_print("temperature:");

    while(1)
    {
        ADCSRA |= (1 << ADSC);                               //start conversion

        while (ADCSRA & (1 << ADSC));
        PORTB = ADCH;

        if (ADCSRA&0b00000101)
        {
            sprintf(buffer, "%d", PORTB);
            lcd_gotoxy(1, 2);
            lcd_print(buffer);
        }
    }
    return 0;
}
    
pregunta Ahmed Rifaat

1 respuesta

1

Como se señaló en los comentarios, el LM34 solo podrá leer temperaturas en el rango \ $ [5 ^ \ circ F, 300 ^ \ circ F] \ $ configurado como lo tiene. En esta configuración, la tensión de salida nunca será negativa, por lo que no tiene que hacer nada especial para conectarlo a su ADC.

Sin embargo, si desea el rango de temperatura completo, deberá proporcionar un riel de suministro negativo. (Consulte la hoja de datos para saber cómo elegir la resistencia \ $ R_1 \ $):

simular este circuito : esquema creado usando CircuitLab

Una posible solución es simplemente mover lo que designas "tierra", es decir, usar un suministro dividido para el LM34, pero designar el riel negativo como tierra.

simular este circuito

Tenga en cuenta que esta solución reducirá significativamente su rango de ADC ya que ahora el punto neutral está en \ $ V_s \ $ en lugar de tierra, y porque el rango de voltaje de salida es sesgado positivo (\ $ V_ {out} \ in [-0.5 , 3] + V_s \ $).

Otra opción es agregar un voltaje constante a la salida mediante un circuito de amplificación operativa:

simular este circuito

Tenga en cuenta que \ $ V_ {off} \ $ se eligió para ser 500mV ya que es el voltaje de salida más bajo que puede emitir LM34 . Este tipo de diseño se puede hacer para obtener el rango completo de su ADC cambiando \ $ R_f \ $ y \ $ V_ {off} \ $, pero tiene el costo de requerir más componentes.

Agregué un amplificador inversor de ganancia unitaria como última etapa, ya que el diseño del amplificador sumador invierte el voltaje, por lo que su salida es estrictamente no positiva. Puede omitir esta etapa cambiando el terreno que se define como y haciendo la inversión en su código.

También puede agregar una etapa de amplificador de salida diferencial en lugar de la etapa de amplificación sumadora, aunque generalmente es mejor vincularlo a un ADC que acepta una entrada diferencial. No estoy lo suficientemente familiarizado con el ATMEGA32 para saber si los ADC pueden configurarse en modo de entrada diferencial o no. Ya que el rango de voltaje de salida está sesgado hacia el riel positivo, está perdiendo parte de la resolución de su ADC. Los amplificadores de salida diferencial generalmente le permiten establecer el nivel de voltaje en modo común para que pueda establecerlo en 1.25V para obtener el rango ADC completo, pero esto nuevamente agrega tener que compensar el desplazamiento en el código. En teoría, puedes usar dos ADC de entrada única como un ADC de entrada pseudo diferencial, aunque esto no es lo ideal.

    
respondido por el helloworld922

Lea otras preguntas en las etiquetas