Autor Tema: libreria DS18S20  (Leído 5048 veces)

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

Desconectado scientist

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 999
libreria DS18S20
« en: 30 de Junio de 2009, 20:58:46 »
hola amigos aqui posteo la libreria que hice para este sensor de temperatura ds18s20
con la ayuda de los AN167 y AN187 de Maxim y tambien a un foro frances hcs08.net

en el foro todo esta en un archivo .h tanto las definiciones como las funciones, y como se que no se debe hacer asi, lo dividi, para que sea mas facil de entender, ahora mismo tengo algunos problemas, pero se que esto se debe mas bien a que no utilizo bien las funciones, a que se encuentren mal, corregi el delay que se necesita para el correcto funcionamiento de todas las funciones a 2us, para un BUS Clock de 8 MHz, esto es modificable para el que ustedes deseen, solo deben cambiar esa parte de programa, yo lo estoy haciendo para un 9S08QE32,


archivo de cabecera
Código: [Seleccionar]
/*****************************************************************************
**
** 1_wire.h
** functions of 1wire sensors
**
*****************************************************************************/

#define TRUE 1
#define FALSE 0
#define OUT 1
#define IN  0


#ifndef PORTS_DQ
#define PORTS_DQ 1
#define DQ_RX     PTAD_PTAD0
#define DQ_TX     PTAD_PTAD1
#define DIR_DQRX  0
#define DIR_DQTX  1
#endif


/*****************************************************************************
**  void delay 2 us
*****************************************************************************/

void delay_2us(unsigned int n);

/*****************************************************************************
**  principal functions
*****************************************************************************/
/* ow_reset function return if there any sensor*/
unsigned char ow_reset(void);
/* read bit functions*/
unsigned char read_bit(void);
/* write bit*/
void write_bit(unsigned char);
/*read byte*/
unsigned char read_byte(void);
/* first */
unsigned char First(void);
/*next*/
unsigned char Next(void);

void ow_scan(void);

void ow_select(char);
/*ow search*/
char ow_search(void);
/*ow verify*/
char ow_verify(void);
/*ow_crc algorithm*/
unsigned char docrc8(unsigned char);


/*****************************************************************************
**  principal functions
**  DS18S20
**
*****************************************************************************/

int ds1820_temperatureX2(char);


aqui esta el archivo .c
yo los nombre
1_wire.h
1_wire.c
ya que no solamente pueden controlar el ds18s20 tambien con esas funciones pueden hacer mas funciones para otros componentes de maxim que manejen 1 wire protocol

Código: [Seleccionar]
/******************************************************************************
**
**  1_wire.c
**  DEFINITIONS FUNCTIONS
**  braulio elias chi salavarria
******************************************************************************/


#include "derivative.h"
#include "1_wire.h"



static 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 components[5][8];   // table that contain all code ROM of components available
                                 // just 5 components
//                          0  1  2  3  4  5  6  7
//          composant[0] : XX XX XX XX XX XX XX XX    ROM code of component index 0
//          composant[1] : XX XX XX XX XX XX XX XX    ROM code of component index 1
//          composant[2] : XX XX XX XX XX XX XX XX    ROM code of component index 2
//          composant[3] : XX XX XX XX XX XX XX XX    ROM code of component index 3
//          composant[4] : XX XX XX XX XX XX XX XX    ROM code of component index 4
 

/******************************************************************************
**
** VARIABLES EXTERNS 
**
******************************************************************************/
// global search state
unsigned char nb_components;
unsigned char ROM_NO[8];
unsigned char LastDiscrepancy;
unsigned char LastFamilyDiscrepancy;
unsigned char LastDeviceFlag;
unsigned char crc8;


/******************************************************************************
**
**  definitions delay_us functions
******************************************************************************/

void delay_2us(unsigned int n)
{
 
  asm {
       LDHX (n)
LOOP1: AIX  #-1    ;[2]
       NOP
       NOP
       CPHX #0     ;[3]
       BNE  LOOP1  ;[3]
  }
}


/*****************************************************************************
**
**  unsigned char ow_reset(void) fundamentals for communications sensor
*****************************************************************************/

unsigned char ow_reset(void)
{
 
 unsigned char presence;
 
 DQ_TX=0; //reset sensor
 delay_2us(235); //delay 470 us
 DQ_TX=1; //high again
 delay_2us(30);//delay 60 us
 presence= DQ_RX;
 delay_2us(230); //delay ~_ 470 us
 return presence;
}


/*****************************************************************************
**
**  unsigned char read_bit(void)
**  reads a bit from the one-wire bus. The delay
**   required for a read is 15us
*****************************************************************************/

unsigned char read_bit(void){
 
 unsigned char i;
 DQ_TX=0; //
 delay_2us(1);
 DQ_TX=1;
 delay_2us(7);//delay for 16 us
 i=DQ_RX;
 delay_2us(22);//delay for 44 us
 return i;
}


/*****************************************************************************
**
**  unsigned char write_bit(void)
**   writes a bit to the one-wire bus, passed in bitval.
*****************************************************************************/

void write_bit(unsigned char bit){
 if(bit){
 
 DQ_TX=0;
 delay_2us(1); //delay for 2 us
 DQ_TX=1;
 delay_2us(15);

 }else{
 DQ_TX=0;
 delay_2us(15);//delay for 30us
 DQ_TX=1;
 delay_2us(1);
 
 }
 
}

/*****************************************************************************
**
**  unsigned char read_byte(void)
** 
*****************************************************************************/

unsigned char read_byte(void){
 
 unsigned char i;
 unsigned char value=0;
 
 for (i=0;i<8;i++){
  if(read_bit()){value|=0x01<<i;}
  }
  return value;
}


/*****************************************************************************
**
**  void write_byte(unsigned char);
** 
*****************************************************************************/

  void write_byte(unsigned char value){
   
   unsigned char i, temp;
   
   for(i=0;i<8;i++){
    temp=value>>i;
    temp&=0x01;
    write_bit(temp);
   }
   
  }
 
/*****************************************************************************
**
**  ONE WIRE CRC
** 
*****************************************************************************/     
unsigned char docrc8(unsigned char value){
 
 crc8=dscrc_table[crc8^value];
 return crc8;
 
}
 
/*****************************************************************************
**
**  FIRST
** 
*****************************************************************************/ 
 
unsigned char First(void){
 
  // reset the search state
   LastDiscrepancy = 0;
   LastDeviceFlag = FALSE;
   LastFamilyDiscrepancy = 0;
   return ow_search();
 
}

/*****************************************************************************
**
**  ow_scan
** 
*****************************************************************************/ 
 
void ow_scan(void){
char a;
  a=First();  //in search for the fist component on the  bus
  nb_components=a;
  while(a){
    a=Next();   // new search
    nb_components += a;
  }

/*****************************************************************************
**
**  Next
** 
*****************************************************************************/   

unsigned char Next(void){
 return ow_search();
}
 
 

 
/*****************************************************************************
**
**  ow search
** 
*****************************************************************************/   
char ow_search(){
 

    unsigned char id_bit_number;
    unsigned char last_zero, rom_byte_number;
    unsigned char search_result;
    unsigned char id_bit, cmp_id_bit;
    unsigned char rom_byte_mask, search_direction;
    // initialize for search
    id_bit_number = 1;
    last_zero = 0;
    rom_byte_number = 0;
    rom_byte_mask = 1;
    search_result = 0;
    crc8 = 0;
   // if the last call was not the last one
   if (!LastDeviceFlag)
   {
      // 1-Wire reset
      if (!ow_reset())
      {
         // reset the search
         LastDiscrepancy = 0;
         LastDeviceFlag = FALSE;
         LastFamilyDiscrepancy = 0;
         return FALSE;
      }
      // issue the search command
      write_byte(0xF0); 
      // loop to do the search
      do
      {
         // read a bit and its complement
         id_bit = read_bit();
         cmp_id_bit = read_bit();
         // check for no devices on 1-wire
         if ((id_bit == 1) && (cmp_id_bit == 1))
            break;
         else
         {
            // all devices coupled have 0 or 1
            if (id_bit != cmp_id_bit)
               search_direction = id_bit;  // bit write value for search
            else
            {
               // if this discrepancy if before the Last Discrepancy
               // on a previous next then pick the same as last time
               if (id_bit_number < LastDiscrepancy)
                  search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0);
               else
                  // if equal to last pick 1, if not then pick 0
                  search_direction = (id_bit_number == LastDiscrepancy);
               // if 0 was picked then record its position in LastZero
               if (search_direction == 0)
               {
                  last_zero = id_bit_number;
                  // check for Last discrepancy in family
                  if (last_zero < 9)
                     LastFamilyDiscrepancy = last_zero;
               }
            }
            // set or clear the bit in the ROM byte rom_byte_number
            // with mask rom_byte_mask
            if (search_direction == 1)
              ROM_NO[rom_byte_number] |= rom_byte_mask;
            else
              ROM_NO[rom_byte_number] &= ~rom_byte_mask;
            // serial number search direction write bit
            write_bit(search_direction);
            // increment the byte counter id_bit_number
            // and shift the mask rom_byte_mask
            id_bit_number++;
            rom_byte_mask <<= 1;
            // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask
            if (rom_byte_mask == 0)
            {
                docrc8(ROM_NO[rom_byte_number]);  // accumulate the CRC
                rom_byte_number++;
                rom_byte_mask = 1;
            }
         }
      }
      while(rom_byte_number < 8);  // loop until through all ROM bytes 0-7
      // if the search was successful then
      if (!((id_bit_number < 65) || (crc8 != 0)))
      {
         // search successful so set LastDiscrepancy,LastDeviceFlag,search_result
         LastDiscrepancy = last_zero; // check for last device
         if (LastDiscrepancy == 0)
            LastDeviceFlag = TRUE;
         
         search_result = TRUE;
      }
   }
   // if no device found then reset counters so next 'search' will be like a first
   if (!search_result || !ROM_NO[0])
   {
      LastDiscrepancy = 0;
      LastDeviceFlag = FALSE;
      LastFamilyDiscrepancy = 0;
      search_result = FALSE;
   }
   return search_result;
}
 
     
 /*****************************************************************************
**
**  ow_verify
** 
*****************************************************************************/       
 
 char ow_verify()
{
   unsigned char rom_backup[8];
   unsigned char i,rslt,ld_backup,ldf_backup,lfd_backup;
   // keep a backup copy of the current state
   for (i = 0; i < 8; i++)
      rom_backup[i] = ROM_NO[i];
   ld_backup = LastDiscrepancy;
   ldf_backup = LastDeviceFlag;
   lfd_backup = LastFamilyDiscrepancy;
   // set search to find the same device
   LastDiscrepancy = 64;
   LastDeviceFlag = FALSE;
   if (ow_search())
   {
      // check if same device found
      rslt = TRUE;
      for (i = 0; i < 8; i++)
      {
         if (rom_backup[i] != ROM_NO[i])
         {
            rslt = FALSE;
            break;
         }
      }
   }
   else
     rslt = FALSE;
   // restore the search state
   for (i = 0; i < 8; i++)
      ROM_NO[i] = rom_backup[i];
  LastDiscrepancy = ld_backup;
   LastDeviceFlag = ldf_backup;
   LastFamilyDiscrepancy = lfd_backup;
   // return the result of the verify
   return rslt;
}

/*****************************************************************************
**
**  ow_select
** 
*****************************************************************************/       
void ow_select(char index_components){
char i;
  if(!ow_reset()){            // enable all components
    write_byte(0x55);  //command MATCH ROM
    for(i=0;i<8;i++)  write_byte(components[index_components][i]);   //   about the send of the 64 bits of the component
  }
}
/*****************************************************************************
**
**  Read_Temperature();   from ds18s20
** 
*****************************************************************************/       
 
int ds1820_temperatureX2(char index_component){
char k;
unsigned char get[9];
int temp2=0;
  if(components[index_component][0]!=0x10){   
    temp2=0xFFFF;                             
    return temp2;
  }
  write_byte(0x44);  //demand of conversion
  delay_2us(1);
  ow_select(index_component);
  write_byte(0xBE);  //demand the lecture of memory ds1820
  for (k=0;k<9;k++){get[k]=read_byte();}  //lecture scratchpad
 
  temp2=get[1]<<8;              //if get[1]=FF > temperature negative
                                 //if get[1]=00 > temperature positive
  if(get[1]){get[0]=(~get[0])+1;} //if negative
  temp2|=get[0];
return temp2; 
}



puede haber errores, les pido que si lo pueden probar y dejarme comentarios les agradecere muchismo, saludos

 :) :) :) :) :)
NO le digas a DIOS que tienes un gran problema, dile a tu problema que tienes un GRAN DIOS!!
Alma mia y castillo mio, mi Dios en quien yo confiare....

Desconectado RICHI777

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1498
Re: libreria DS18S20
« Respuesta #1 en: 01 de Julio de 2009, 12:37:07 »
Hola Braulio !, fantastico lo que posteaste. Tengo simplemente algunas recomendaciónes según mi punto de vista que no implica que sea la verdad absoluta.
Cuando implementas una libreria con determinada funcionalidad es importante mantener los detalles de la implementación ocultos al resto de la aplicación, es decir en el archivo H solo se colocan las funciones que van a ser usadas externamente, en tu caso :

Código: C
  1. int ds1820_temperatureX2(char);

Que es en definitiva la función que se usara para leer el valor de la temperatura, el resto de las definiciones o funciones las podes incluir dentro del archivo C directamente, ya que esas funciones las utiliza tu módulo nada mas.
Otra cosa tambien sugerida es que a las funciones internas las antepongas con la palabra reservada static de esa manera te aseguras que solo tu módulo las accede permaneciendo ocultas para el resto de la aplicación, es mas o menos el concepto de objetos llamado encapsulación.

Código: C
  1. static unsigned char read_bit(void);

Por último y espero que sepas perdonarme por las sugerencias, es tratar de utilizar el tipo de datos correcto o más portable, el tema es asi, al usar CodeWarrior te aseguras que el tipo int es de 16 bits signeado, el HCS08 lo puede manejar eficientemente porque el registro H:X es de ese tamaño y ademas maneja operaciones signeadas, el problema es que si esa función la tratas de mover a otro micro sin estas caracteristicas, digamos x ejemplo a un 8051 el overhead que se le mete al tratar signeados es muy significativa con respecto a los unsigned. En tu caso todo bien, pero mi experiencia me dice que es recomendable escribir codigo portable, cuando te acostumbras a eso vas a notar que ciertas cosas que hagas te van a servir para aplicarlas a otros micros sin demasiado esfuerzo y eso te salva mucho tiempo. Yo utilizo estos tipos:

Código: C
  1. /* Types definition */
  2. typedef unsigned char bool;
  3. typedef unsigned char byte;
  4. typedef unsigned short int word;
  5. typedef unsigned long dword;

Otros usan conbinaciones de int8, int16, int32, etc.

Saludos !

Desconectado scientist

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 999
Re: libreria DS18S20
« Respuesta #2 en: 01 de Julio de 2009, 13:12:13 »
ok ok ya te entendi richard, es mejor manejarlo asi como dices, por que si quiero ir expandiendo la libreria no solo para el ds18s20, tambien para otros sensores de 1 wire solo pondria las funciones que realmente voy a utilizar, asi ya no me confundo buscando cual era la que hiba a utilizar, y protego que mis funciones como write_bit no tengan conflicto con otras funciones de otras librerias que puedan llamarse igual, lo habia leido acerca del stactic, pero no le encontraba aplicacion, en cuanto al typedef, este debe de ir en el archivo de cabecera? o dentro de mi archivo .c?  muchas gracias por tus comentarios, como siempre acertados, hay algunos errores que tiene esta libreria, pequeños que estoy tratando de corregir, en cuanto lo tenga ,lo posteo, saludos
NO le digas a DIOS que tienes un gran problema, dile a tu problema que tienes un GRAN DIOS!!
Alma mia y castillo mio, mi Dios en quien yo confiare....

Desconectado RICHI777

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1498
Re: libreria DS18S20
« Respuesta #3 en: 01 de Julio de 2009, 13:17:40 »
Braulio, yo normalmente las definiciones de tipos las coloco dentro de un H separado, donde ademas coloco macros de uso general, MIN, MAX, etc. y al mismo lo incluyo en todos los modulos.

Saludos !

Desconectado scientist

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 999
Re: libreria DS18S20
« Respuesta #4 en: 01 de Julio de 2009, 13:55:04 »
hola, aqui posteo como es que estoy conectando el circuito, no se si esto es lo que tenga que ver para que no me este funcionando correctamente, como pueden ver en el archivo de cabecera, defino DQ_RX y DQ_TX, como los pines A0 y A1, uno como entrada y otro como salida, para hacer mas simple el programa, debido  a que las librerias de los AN de maxim estan hechos con un micro de arquitectura 8051, y como sabran no hay que configurar los pines si son entrada o salida, automaticamente por su arquitectura fisica pueden funcionar como las dos cosas sin tener que configurarlos como tal, entonces no se si ahi este el problema, si alguien me puede ayudar a hacerlo con un solo pin, podemos colaborar conjuntamente, saludos
NO le digas a DIOS que tienes un gran problema, dile a tu problema que tienes un GRAN DIOS!!
Alma mia y castillo mio, mi Dios en quien yo confiare....

Desconectado scientist

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 999
Re: libreria DS18S20
« Respuesta #5 en: 04 de Julio de 2009, 23:45:57 »
ya pude hacerlo funcionar, en proxima posteare una version lite

saludos   :-/ :-/ :-/ :-/ quiero poner las cosas en orden como el typdef antes de postearla
NO le digas a DIOS que tienes un gran problema, dile a tu problema que tienes un GRAN DIOS!!
Alma mia y castillo mio, mi Dios en quien yo confiare....

Desconectado elotrogonzalo

  • PIC10
  • *
  • Mensajes: 25
Re: libreria DS18S20
« Respuesta #6 en: 07 de Marzo de 2014, 16:14:25 »
Hola scientist! pudiste hacerlo andar entonces?? yo estaba buscando una rutina así para manejar ese sensor. Cuando podrías subir esa versión del programa que decías ahí arriba como lite? Saludos!!!!