Autor Tema: Busqueda de sensor de temperatura I2C  (Leído 8812 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado pelusac

  • PIC16
  • ***
  • Mensajes: 118
Re: Busqueda de sensor de temperatura I2C
« Respuesta #15 en: 23 de Septiembre de 2006, 17:32:50 »
Muchas gracias colega .

Otro saludo desde Sevilla.

Desconectado Azicuetano

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1020
    • Aplicaciones Electrónicas en Alicante.
Re: Busqueda de sensor de temperatura I2C
« Respuesta #16 en: 23 de Septiembre de 2006, 18:09:10 »
Hola pelusac!

El código que pongo a continuación está a medio programar. El sensor de temperatura funciona perfectamente pero... no es la versión definitiva [ esta tarde he conseguido que me reconozca varias sondas (pero... sigue estando a medio programar  :mrgreen: :mrgreen:)]

En unos días pondré la versión final.



Temperaturas.c

Código: [Seleccionar]
/************************************************************

    Sensor de temperatura DS18B20 + RTD DS1302 + RS232
   
   (versión experimental para pelusac del foro TODOPIC)
         
                        AZICUETANO
                       
   El programa está a mitad. Solo se monitoriza en la pantalla
   del ordenador la temperatura de la sonda DS18B20 que
   tengamos enganchada en el pin RB7.                       
                       
************************************************************/

#include <18F4550.h>
#include <ds1302.c>               //libreria de rtc ds1302
#include <1wire.h>                 //librería para las sondas de temperatura

#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=pin_C6, rcv=pin_C7)

byte day=18,mth=9,year=06,dow=1,hour=20,min=40,sec=12;   //variabes para ds1302
char Keypress=' ';
int8 segundos=0;
int8 temporal_timer2=0;
int  indice_buffer=0;
int const  longitud_buffer=16;
char buffer[longitud_buffer];
char buffer_guardado[longitud_buffer];
//-----------------------
//signed int16 t=0,t1;
float t=0,t1;
byte  temperatura_l=0, temperatura_h=0;
//-----------------------

//void configurar(void);
void buffer_char(char c);
void borrar_buffer(void);
void guardar_buffer(void);
void envia_buffer_guardado(void);

#int_rda
void serial_isr()
{
   Keypress=0x00;
   if(kbhit())
   {
      buffer_char(getc());                       // lo recibo y lo añado al Buffer de Recepcion

//      Keypress=getc();

//      rtc_get_date(day,mth,year,dow);      //coge hora,minuto,segundo
//      printf("\n%2u/%2u/%2u/%2u", day, mth, year, dow);
  }
}

#INT_TIMER2
void interrupcion2()
{
   temporal_timer2++;

   if(temporal_timer2==16)
   {
      segundos++;
      if(segundos>=60)
      {
         segundos=0;
      }
      temporal_timer2=0;

//      rtc_get_time(hour,min,sec);      //coge hora,minuto,segundo
//      printf("\n%2u:%2u:%2u", hour, min, sec);
   }
}

void buffer_char(char c)
{
   switch(c)
   {
      case 0x0D:                                // Si pulsamos el INTRO
         indice_buffer=0;
         guardar_buffer();
         borrar_buffer();
         envia_buffer_guardado();

      default:
         buffer[indice_buffer]=c;               // Añade caracter recibido al Buffer
         putc(c);                               // y lo monitorizo
   }
   indice_buffer++;
}

void borrar_buffer(void)
{
   int n=0;

   for(n=0; n<longitud_buffer; n++)
   {
      buffer[n]=0;
   }
}

void guardar_buffer(void)
{
   int n=0;

   for(n=0; n<longitud_buffer; n++)
   {
      buffer_guardado[n]=buffer[n];
   }
}

void envia_buffer_guardado(void)
{
   int n=0;

   for(n=0; n<longitud_buffer; n++)
   {
      putc(buffer_guardado[n]);
   }
}

/*
void configurar(void)
{
   disable_interrupts(GLOBAL);               //desactivadas interrupciones

   day=21;
   mth=7;
   year=6;
   hour=2;
   min=34;
   day=3;


   rtc_set_datetime(day,mth,year,dow,hour,min);   //nueva hora,minuto,...

   enable_interrupts(GLOBAL);               //desactivadas interrupciones
}
*/

void main(void)
{
   char  caracter=0;
   int   read_ok=0;
   
//   unsigned char caca=2;

   rtc_init();          //inicializa rtc

   delay_ms(1000);

   rtc_set_datetime(day,mth,year,dow,hour,min);   //nueva hora,minuto,...

//////////////////////////////////////////////////////////
//    setup_timer_2 ( T2_DIV_BY_4, 0xc0, 2);
//    At 20mhz, the timer will increment every 800ns,
//    will overflow every 153.6us,
//    and will interrupt every 307.2us.
//
//    Para un WT de 4 Mhz tenemos que:
//
//    4/4Mhz = 1 uS
//    como tenemos 'T2_DIV_BY_4'
//    1 uS * 4 = 4 uS
//    4 uS * 192 = 768 uS             (0x0c = 192)
//    768 uS * 2 = 1.536 ms
//
//    Como lo que queremos es temporizar 1 segundo tenemos que:
//
//    setup_timer_2 ( T2_DIV_BY_16, 0xFF, 16);
//
//    4/4Mhz = 1 uS
//    ponemos 'T2_DIV_BY_16'
//    1 uS * 16 = 16 uS
//    16 uS * 255 = 4.08 ms           (0xFF = 255)
//    4.08 ms * 16 = 0.06528 s.
//
//    0.06528 * x = 1
//    x = 15
//    Es decir, la interrupción tiene que saltar 15 veces para tener un retardo
//    de 0.9792 segundos.
//
//////////////////////////////////////////////////////////

   setup_timer_2 ( T2_DIV_BY_16, 0xFF, 16); // Temporización para la base de tiempos de 1 segundo.
   enable_interrupts(INT_TIMER2); // Habilita Interrupción del TIMER2.

   enable_interrupts(int_rda);               // Habilita Interrupción del USART

   enable_interrupts(global);


   printf("PIC16F874 a la espera");        // Envío mensaje de "estoy vivo"
   delay_ms(500);
/*   
   while(1)
   {
      if(init_1wire())
    {
      write_1wire(0xcc);      //skip ROM
      write_1wire(0x44);     //convert T
    }

      if(init_1wire())
    {
      write_1wire(0xcc); //skip ROM
      write_1wire(0xbe); //read scratchpad

      temperatura_l=read_1wire();
         temperatura_h=read_1wire();


         read_ok=1;
    }

      if(read_ok)
      {
         t=make16(temperatura_h,temperatura_l);        //calcula la temperatura
         t=t*50;
         t=t-25;
         t=t/1000;
         printf(" Temperatura=%2.1f ", t);                 // Envío mensaje de temperatura.

         delay_ms(500);
      }
   }
*/

/*   if(Next()==TRUE)
   {
      printf("-Hay X varios dispositivos 1wire-");
   }
   else
   {
      printf("-Hay 1 dispositivo 1wire-");
   }
*/

//   printf("\n caca = %d \n", caca);
   FindDevices();
   printf("\n Número de dispositivos = %d \n", numROMs);
   printf("\nROM CODE =%02X%02X%02X%02X\n",FoundROM[4][7],FoundROM[4][6],FoundROM[4][5],FoundROM[4][4],FoundROM[4][3],FoundROM[4][2],FoundROM[4][1],FoundROM[4][0]);
   
   while(1)
   {
      if(ow_reset()==0)
    {
      write_byte(0xcc);      //skip ROM
      write_byte(0x44);     //convert T
    }

      if(ow_reset()==0)
    {
      write_byte(0xcc); //skip ROM
      write_byte(0xbe); //read scratchpad

      temperatura_l=read_byte();
         temperatura_h=read_byte();


         read_ok=1;
    }

      if(read_ok)
      {
         t=make16(temperatura_h,temperatura_l);        //calcula la temperatura
         t=t*50;
         t=t-25;
         t=t/1000;
         printf(" Temperatura=%2.1f ", t);                 // Envío mensaje de temperatura.

         delay_ms(500);
      }
   }
}


1wire.h

Código: [Seleccionar]
//----------------------------------------------------------------
//
// 1wire.h
//
//
//
//
//
//
//----------------------------------------------------------------


//-------------------------data pin definition--------------------
#define DQ pin_b7
//----------------------------------------------------------------

//-------------------------1wire reset----------------------------
/*
init_1wire()
{
int a;

output_low(DQ);
delay_us(480);
output_float(DQ);
delay_us(65);
a=!input(DQ);
delay_us(240);
if(a)
return(1);
else
return(0);
}
*/
//-------------------------read byte------------------------------
/*
byte read_1wire()
{
byte a,data;

for(a=0;a<8;a++)
{
output_low(DQ);
delay_us(14);
output_float(DQ);
delay_us(5);
shift_right(&data,1,input(DQ));
delay_us(100);
}
return(data);
}
*/
//--------------------------write byte----------------------------
/*
byte write_1wire(byte data)
{
byte a;

for(a=0;a<8;a++)
{
output_low(DQ);
delay_us(10);
if(shift_right(&data,1,0))
output_high(DQ);
else
output_low(DQ);
delay_us(50);
output_high(DQ);
delay_us(50);
}
return(1);
}
*/
//-----------  AÑADIDO POR AZI - ------------------------------------

////////////////////////////////////////////////////////////////////////////
// GLOBAL VARIABLES
//

unsigned char ROM_NO[8];
unsigned char ROM[8]; // ROM Bit
unsigned char lastDiscrep = 0; // last discrepancy
unsigned char doneFlag = 0; // Done flag
unsigned char FoundROM[5][8]; // table of found ROM codes
unsigned char numROMs;
unsigned char dowcrc;

unsigned char dscrc_table[] = {
0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7,
219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154,
101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36,
248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185,
140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139,
87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53};
unsigned char page_data[32];

//////////////////////////////////////////////////////////////////////////////
// OW_RESET - performs a reset on the one-wire bus and
// returns the presence detect. Reset is 480us, so delay
// value is (480-24)/16 = 28.5 - we use 29. Presence checked
// another 70us later, so delay is (70-24)/16 = 2.875 - we use 3.
//

ow_reset(void)
{
   int presence;
   output_low(DQ); //pull DQ line low
   delay_us(480);// leave it low for 480us
   output_bit(DQ,1); // allow line to return high
   delay_us(72); // wait for presence
   presence = input(DQ); // get presence signal
   delay_us(424);
   return(presence); // presence signal returned
} // 0=presence, 1 = no part

//////////////////////////////////////////////////////////////////////////////
// READ_BIT - reads a bit from the one-wire bus. The delay
// required for a read is 15us, so the DELAY routine won't work.
// We put our own delay function in this routine in the form of a
// for() loop.
//

byte read_bit(void)
{
   byte i;
   
   output_bit(DQ,0); // pull DQ low to start timeslot
   output_bit(DQ,1); // then return high
   delay_us(15); // delay 15us from start of timeslot
   return(input(DQ)); // return value of DQ line
}

//////////////////////////////////////////////////////////////////////////////
// WRITE_BIT - writes a bit to the one-wire bus, passed in bitval.
//

void write_bit(byte bitval)
{
   output_bit(DQ,0); // pull DQ low to start timeslot
   if(bitval==1) output_bit(DQ,1); // return DQ high if write 1
   delay_us(104); // hold value for remainder of timeslot
   output_bit(DQ,1);
}// Delay provides 16us per loop, plus 24us. Therefore delay(5) = 104us

//////////////////////////////////////////////////////////////////////////////
// READ_BYTE - reads a byte from the one-wire bus.
//

byte read_byte(void)
{
   byte i;
   byte value=0;
   for (i=0;i<8;i++)
      {
      if(read_bit()) value|=0x01<<i; // reads byte in, one byte at a time and then
      // shifts it left
      delay_us(120); // wait for rest of timeslot
      }
   return(value);
}

//////////////////////////////////////////////////////////////////////////////
// WRITE_BYTE - writes a byte to the one-wire bus.
//

void write_byte(byte val)
{
   byte i;
   byte temp;
   for (i=0; i<8; i++) // writes byte, one bit at a time
      {
      temp = val>>i; // shifts val right 'i' spaces
      temp &= 0x01; // copy that bit to temp
      write_bit(temp); // write bit in temp into
      }
   delay_us(104);
}

//////////////////////////////////////////////////////////////////////////////
// ONE WIRE CRC
//

unsigned char ow_crc( unsigned char x)
{

   dowcrc = dscrc_table[dowcrc^x];
   return dowcrc;
}

/////////////////////////////////////////////////////////////////////////////////
// NEXT
// The Next function searches for the next device on the 1-wire bus. If
// there are no more devices on the 1-wire then false is returned.
//

unsigned char Next(void)
{
   unsigned char m = 1; // ROM Bit index
   unsigned char n = 0; // ROM Byte index
   unsigned char k = 1; // bit mask
   unsigned char x = 0;
   unsigned char discrepMarker = 0; // discrepancy marker
   unsigned char g; // Output bit
   unsigned char nxt; // return value
   int flag;
   nxt = FALSE; // set the next flag to false
   dowcrc = 0; // reset the dowcrc
   flag = ow_reset(); // reset the 1-wire
   if(flag||doneFlag) // no parts -> return false
      {
      lastDiscrep = 0; // reset the search
      return FALSE;
      }
   write_byte(0xF0); // send SearchROM command
   do
   // for all eight bytes
      {
      x = 0;
      if(read_bit()==1) x = 2;
      delay_us(120);
      if(read_bit()==1) x |= 1; // and its complement
      if(x ==3) // there are no devices on the 1-wire
      break;
      else
         {
         if(x>0) // all devices coupled have 0 or 1
         g = x>>1; // bit write value for search
         else
            {
            // if this discrepancy is before the last
            // discrepancy on a previous Next then pick
            // the same as last time
            if(m<lastDiscrep)
            g = ((ROM[n]&k)>0);
            else // if equal to last pick 1
            g = (m==lastDiscrep); // if not then pick 0
            // if 0 was picked then record
            // position with mask k
            if (g==0) discrepMarker = m;
            }
         if(g==1) // isolate bit in ROM[n] with mask k
         ROM[n] |= k;
         else
         ROM[n] &= ~k;
         write_bit(g); // ROM search write
         m++; // increment bit counter m
         k = k<<1; // and shift the bit mask k
         if(k==0) // if the mask is 0 then go to new ROM
            { // byte n and reset mask
            ow_crc(ROM[n]); // accumulate the CRC
            n++; k++;
            }
         }
      }while(n<8); //loop until through all ROM bytes 0-7
   if(m<65||dowcrc) // if search was unsuccessful then
   lastDiscrep=0; // reset the last discrepancy to 0
   else
      {
      // search was successful, so set lastDiscrep,
      // lastOne, nxt
      lastDiscrep = discrepMarker;
      doneFlag = (lastDiscrep==0);
      nxt = TRUE; // indicates search is not complete yet, more
      // parts remain
      }
   return nxt;
}

////////////////////////////////////////////////////////////////////////////
// FIRST
// The First function resets the current state of a ROM search and calls
// Next to find the first device on the 1-wire bus.
//

unsigned char First(void)
{
   lastDiscrep = 0; // reset the rom search last discrepancy global
   doneFlag = FALSE;
   return Next(); // call Next and return its return value
}

////////////////////////////////////////////////////////////////////////////////
// FIND DEVICES

void FindDevices(void)
{
   unsigned char m;
   
   if(!ow_reset()) //Begins when a presence is detected
   {
      if(First()) //Begins when at least one part is found
      {
         numROMs=0;
         do
         {
            numROMs++;
            for(m=0;m<8;m++)
            {
               FoundROM[numROMs][m]=ROM[m];  //Identifies ROM
                                             //number on found device
            }

//          printf("\nROM CODE =%02X%02X%02X%02X\n",FoundROM[4][7],FoundROM[4][6],FoundROM[4][5],FoundROM[4][4],FoundROM[4][3],FoundROM[4][2],FoundROM[4][1],FoundROM[4][0]);
         }while (Next()&&(numROMs<10)); //Continues until no additional devices are found
      }
   }
   else
   {
      numROMs=55;
   }
}


Ante cualquier duda aquí estoy para intentar resolverla.


Un saludo desde Alicante.

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: Busqueda de sensor de temperatura I2C
« Respuesta #17 en: 23 de Diciembre de 2007, 03:44:04 »
Iván, ¿terminaste la librería?. Tengo que usar este chisme en un proyecto, y me apetece ahorrarme escribir el código si ya lo ha hecho un maestro.