Termometro con 16f84, ds18b20 y 3 7-seg

Este termometro fue mi primer proyecto con pic. Me parecio interesante para aprender la arquitectura pic, ya que habia tenido un poco de experiencia programando en asm el 68hc11 en la facu.

El codigo esta hecho en C. Lo copie de un ejemplo en la web.

YouTube - termometro digital con pic 16f84

Codigo

Código:
#include <16F84A.h>
#use delay(clock=4000000)
#fuses NOWDT,XT, NOPUT, NOPROTECT

#define ONE_WIRE_PIN PIN_A3

int8 D3=0;  //0x66
int8 D2=0; //0xF2
int8 D1=0;  //0A
int contador=0x00;
int8 lsb=0b01010010;
int8 msb=0b11111111;


///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////

void show(void)
{

disable_interrupts(INT_RTCC);

output_b(D3);
output_high(PIN_A0);
delay_ms(2);
output_low(PIN_A0);

output_b(D2);
output_high(PIN_A1);
delay_ms(2);
output_low(PIN_A1);

output_b(D1);
output_high(PIN_A2);
delay_ms(2);
output_low(PIN_A2);

enable_interrupts(INT_RTCC);

}

void onewire_reset()  // OK if just using a single permanently connected device
{
 show();
 output_low(ONE_WIRE_PIN);
 delay_us( 500 ); // pull1-wire low for reset pulse
 output_float(ONE_WIRE_PIN); // float 1-wire high
 delay_us( 500 ); // wait-out remaining initialisation window.
 output_float(ONE_WIRE_PIN);
}

void onewire_write(int data)
{
 int count;
 show();
 for (count=0; count<8; ++count)
 {
  output_low(ONE_WIRE_PIN);
  delay_us( 2 ); // pull 1-wire low to initiate write time-slot.
  output_bit(ONE_WIRE_PIN, shift_right(&data,1,0)); // set output bit on 1-wire
  delay_us( 60 ); // wait until end of write slot.
  output_float(ONE_WIRE_PIN); // set 1-wire high again,
  delay_us( 2 ); // for more than 1us minimum.
 }
}


int onewire_read()
{
 int count, data;
 show();
 for (count=0; count<8; ++count)
 {
  output_low(ONE_WIRE_PIN);
  delay_us( 2 ); // pull 1-wire low to initiate read time-slot.
  output_float(ONE_WIRE_PIN); // now let 1-wire float high,
  delay_us( 8 ); // let device state stabilise,
  shift_right(&data,1,input(ONE_WIRE_PIN)); // and load result.
  delay_us( 120 ); // wait until end of read slot.
 }
 return( data );
}


void ds1820_read()
{
  int8 busy=0, temp1, temp2;
 signed int16 temp3;
 //float result;
 onewire_reset();
 onewire_write(0xCC);
 onewire_write(0x44);

 while (busy == 0)
  busy = onewire_read();

 onewire_reset();
 onewire_write(0xCC);
 onewire_write(0xBE);
 lsb = onewire_read();
 msb = onewire_read();

 //temp3 = make16(temp2, temp1);

 //result = (float) temp3 / 2.0;   //Calculation for DS18S20 with 0.5 deg C resolution
 //result = (float) temp3 / 16.0;  //Calculation for DS18B20 with 0.1 deg C resolution

 //delay_ms(200);
 //return(result);
}

///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////

int8 int_hex(int8 data)
{
 switch (data){
   case 0: return 0xFC;
         break;
   case 1: return 0x60;
         break;
   case 2: return 0A;
         break;
   case 3: return 0xF2;
         break;
   case 4: return 0x66;
         break;
   case 5: return 0xB6;
         break;
   case 6: return 0xBE;
         break;
   case 7: return 0xE0;
         break;
   case 8: return 0xFE;
         break;
   case 9: return 0xF6;
         break;
   default: return 0x8E;
         break;
   }
}

int8 decimas(int8 data)//aqui metemos el lsb para sacar las decimas
{
data=data & 0x0F;
 switch (data){
   case 0x00:return 0;
            break;
   case 0x01:return 1;
            break;
   case 0x02:return 1;
            break;
   case 0x03:return 2;
            break;
   case 0x04:return 2;
            break;
   case 0x05:return 3;
            break;
   case 0x06:return 4;
            break;
   case 0x07:return 4;
            break;
   case 0x08:return 5;
            break;
   case 0x09:return 6;
            break;
   case 0x0A:return 6;
            break;
   case 0x0B:return 7;
            break;
   case 0x0C:return 7;
            break;
   case 0x0D:return 8;
            break;
   case 0x0E:return 9;
            break;
   case 0x0F:return 9;
            break;
 }
}


int8 grados(int8 msb,lsb)//metemos msb y lsb para sacar un byte con el valor
{
 int8 result,mb,lb;
 mb=msb & 0x0F;
 swap(mb);
 lb=lsb & 0xF0;
 swap(lb);
 result=mb+lb;

 return result;
}

void digitos12(int8 data)
{
 D1=(int8)data/10;
 D2=data-(D1*10);
}

void digitos23(int8 data)
{
 D2=(int8)data/10;
 D3=data-(D2*10);
}


///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
void decimal_positivo(void) //2 cifras de temperatura mas el decimal 51,2
{
 int8 entero;
 entero=grados(msb,lsb);
 D3=decimas(lsb);
 digitos12(entero);

 D3=int_hex(D3);
 D2=int_hex(D2)+1;
 D1=int_hex(D1);
}

void positivo(void)//positivo (3 cifras de temperatura sin decimal)  102
{
 int8 entero;
 entero=grados(msb,lsb);
 D1=0x60;
 entero=entero-100;
 digitos23(entero);

 D3=int_hex(D3);
 D2=int_hex(D2);
}

void decimal_negativo(void)//decimal_negativo(1 cifra de temeratura, mas el decimal mas el signo) -8,6
{
 int8 entero,lb;
 entero=grados(msb,lsb);
 D1=0x02;
 lb=lsb&0x0F;    //enmascarar lsb y despues restar
 lb--;
 lb=lb ^ 0x0F;
 D3=decimas(lb);
 entero=entero & 0x0F;
 D2=entero ^ 0x0F;
 D3=int_hex(D3);
 D2=int_hex(D2)+1;
}

void negativo(void)//negativo (2 cifras de temperatura mas el signo negativo) -13
{
 int8 entero;
 entero=grados(msb,lsb);
 D1=0x02;
 entero=entero ^ 0xFF;
 digitos23(entero);
 D2=int_hex(D2);
 D3=int_hex(D3);
}

void conversion(void)
{
 int8 entero;
 entero=grados(msb,lsb);

  if (!bit_test(msb,7))
    if (entero>100) positivo();
     else decimal_positivo();
  else{
    entero=entero ^ 0xFF;
    if (entero < 0b00001010 ) decimal_negativo();
     else negativo();
  }


}
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////


#int_RTCC
RTCC_isr(){
   ++contador;
   if (contador==30){
      contador=0x00;
      ds1820_read();
      conversion();
   }
}


void main()
{
setup_counters(RTCC_INTERNAL, RTCC_DIV_128); //Actualizacion temperatura cada 2 segundos
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
while(true)
{
show();
}
}
 

Adjuntos

  • esquema_380.gif
    esquema_380.gif
    25.1 KB · Visitas: 185
hola, yo estoy intentando hacer el mismo termómetro, pero con sensor LM35, el sensor esta activo, pero no me enciende ningún 7 segmento, estas utilizando ánodo común o cátodo común?
 
Saludos Mireille:

No sé si estes utilizando el mismo circuito que keith para tu termometro con LM35, en caso de que sea así, pues no funcionará tu termometro, ya que el circuito que colocó keith en esta discución está hecho con un sensor DS18B20 que es un sensor que transmite el valor de temperatura de manera digital (serial one wire), a diferencia del LM35 que transmite la temperatura medida de manera analógica (10mV/C).

Acalro esto porque en tu pregunta no mencionaste si utilizaste el mismo circuito alguno diferente.

Espero sirva mi aporte.

Saludos a todos.
 
Atrás
Arriba