CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

One wire library search protocol HELP DS18S20

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
psypersky



Joined: 06 Jul 2008
Posts: 13

View user's profile Send private message

One wire library search protocol HELP DS18S20
PostPosted: Thu Jul 31, 2008 3:48 pm     Reply with quote

Hi, im using one wire library but i have a problem, the functions ow_reset, and search supply, works fine, but when the program enter in the function Find_devices() inside, that function call first() and first call next(), and inside of next when next send write_byte(0xF0); (SearchROM command), then read the first two bits , and always read "1" in the first bit and "1" in the second bit that means there are not sensors conected, and i cant make that part work, i have the sensors conected im using DS18S20

i marked the errors with 2 lines of "####" , you can search the "####" and see where is the error..

Find_devices is called from the main file ans it's in the one wire library.
First() and Next() [Where the problem is] are in the one wire library too.

You can download the complete proyect from here:

http://rapidshare.com/files/133925184/Modulo_Temp_ds1820s.rar.html

This is the main file.

Code:
#include "C:\Archivos de programa\PICC\Examples\Modulo Temp ds1820s\Ds18S20.h"


#include <flex_LCD_ds18s20.C>
#define sensor_pin pin_a5

static int8 inteiro, decimal, i, num_devices;
static int1 parasite_power;


#include <ds1820.c>
int dados[9];



void procurar (void)//-------------------------------------------------------------
{
   if(search_supply()){   
      parasite_power=TRUE;
      printf(lcd_putc,"\fparasit true");
      delay_ms(3000);
   }
   else{
      parasite_power=FALSE;
      printf(lcd_putc,"\fparasit false");
      delay_ms(3000);
   }
   
  // printf(lcd_putc,"\fUNo!");
     
    //  delay_ms(1000);
   
   if(ow_reset()){
      printf(lcd_putc,"\fNenhum Disposit.\n   Detectado! reset");
      num_devices=0;
      delay_ms(5000);
      return;
   }
  // printf(lcd_putc,"\fDoSs!");
   FindDevices();                          //until here its fine, inside this function is the error ###################################################################################################################################
 
     if(num_devices==numROMs)
     return;
   
   if(numROMs>num_devices)
      printf(lcd_putc,"\fNovo Dispositivo\n   Detectado");
   
   else if(numROMs<num_devices)
      printf(lcd_putc,"\f Um dispositivo\nfoi desconectado");

   Delay_ms(400);
   printf(lcd_putc,"\f A Indexar\nDispositivos...");
   delay_ms(600);
   printf(lcd_putc,"\fTotal Disp.: %u",numROMs);
   delay_ms(2000);
   printf(lcd_putc,"\f");
 
   num_devices=numROMs;
} //final de funçao--------------------------------------------------------------------

void main()
{

   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
  // setup_psp(PSP_DISABLED);
   setup_spi(FALSE);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   lcd_init();
   

num_devices=0;//temp
 
 
   procurar();                // procura todos os dispositivos presentes no bus
 
   // printf(lcd_putc,"\fSali de procurar()");//temp
  //delay_ms(500);
   
   num_devices=numROMs;       // guarda o numero de dispositivos encontrados
do{
   
 //  for(i=1;i<=numROMs;i++)
   convert_temp();           // envia o comando para iniciar a conversao de temperatura
                              // para todos os dispositivos presentes no bus

   for(i=1; i<=numROMs;i++){     // faz a leitura de todos os dispositivos
      if(!read_temp(dados, i))   // lê a temperatura do dispositivo 'i'
         procurar();          // se der erro, faz a procura de dispositivos
         
      trata_temperatura(dados);  // processa os valores
     
      if(FoundROM[i][7]==0x35 && FoundROM[i][6]==0x00 && FoundROM[i][5]==0x08 && FoundROM[i][4]==0x00 && FoundROM[i][3]==0xc4 && FoundROM[i][2]==0xb0 && FoundROM[i][1]==0xf6 && FoundROM[i][0]==0x10){
            //se o chip do exterior corresponde ao ROM
         lcd_gotoxy(1,1);
         printf(lcd_putc,"Ext.: %2u,%02u 'C  ",inteiro, decimal);
      }//if
     
      if(FoundROM[i][7]==0xe1 && FoundROM[i][6]==0x00 && FoundROM[i][5]==0x08 && FoundROM[i][4]==0x00 && FoundROM[i][3]==0xc4 && FoundROM[i][2]==0x8f && FoundROM[i][1]==0xbb && FoundROM[i][0]==0x10){
              //se o chip do interior corresponde ao ROM                     //E1000800C48FBB10
         lcd_gotoxy(1,2);
         printf(lcd_putc,"Int.: %02u,%02u 'C  ",inteiro, decimal);
      }//if
     
   }// for

   procurar();    // procura se existem novos dispositivos, ou se algum foi desconectado

}while(TRUE);

}


This is the one wire library

Code:
//******************************************************************************
//                              onewire.c
//
// DESCRIÇAO GERAL: Driver para comunicaçoes sobre o bus ONEWIRE.
//
//    *  ow_reset(); Envia um pulso de reset, devolve: 0 se um ou mais dispositivos presentes
//                                                     1 se nenhum dispositivo presente
//
//    *  read_bit(); Lê um bit do bus onewire
//
//    *  write_bit(bitval); escreve um bit 'bitval' no bus onewire
//
//    *  read_byte(); Lê um byte do bus onewire
//
//    *  write_byte(val); Escreve um byte 'val' no bus
//
//    *  ow_crc(x); Processa o valor de CRC
//
//    *  FindDevices(); Procura dispositivos no bus onewire
//
//    *  Send_MatchRom();  Envia o comando Match_rom e depois o endereço do dispositivo
//
//******************************************************************************

// Variaveis Globais
int8 ROMM[8];            // ROM bit
int8 lastDiscrep = 0;
short doneFlag = 0;
int8 FoundROM[7][8];    // Tabela dos codigos ROM encontrados, 8 bytes para cada um
int8 numROMs=0;
int8 dowcrc;            // acumula o CRC

// crc lookup table
int8 const 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
};

//******************************************************************************
// DESCRIÇAO: Faz reset no bus
//
// INPUT: Nada
//
// OUTPUT: 0 se um dispositivo presente
//         1 se nenhum dispositivo presente
//------------------------------------------------------------------------------
int1 ow_reset(void)
{
   int1 presence;

   output_low(sensor_pin);
   delay_us(488);          // Min. 480uS
   output_float(sensor_pin);
   delay_us(72);           // Takes 15 to 60uS for devices to respond
   presence = input(sensor_pin);
   delay_us(424);          // Wait for end of timeslot
   return(presence);       //devolve 0 se um dispositivo esta presente
}
//******************************************************************************

//******************************************************************************
// DESCRIÇAO: Lê um bit no bus
//
// INPUT:   nada
//
// OUTPUT:  bit lido
//------------------------------------------------------------------------------
int8 read_bit(void)
{
   output_low(sensor_pin);
   delay_us(1);         // 1uS min. Original code relied on 8051 being slow
   output_float(sensor_pin);
   delay_us(20);        // Wait at least 15mS from start of time slot
   return(input(sensor_pin));   // Delay to finish time slot (total 60 to 120uS)
}                       // must be done next.
//******************************************************************************
//
//******************************************************************************
// DESCRIÇAO:  Escreve um bit no bus
//
// INPUT:   bit a ser enviado para o bus
//
// OUTPUT: nada
//------------------------------------------------------------------------------
void write_bit(int8 bitval)
{
   output_low(sensor_pin);

   if(bitval == 1) {
      delay_us(1);      // 1uS min. Original code relied on 8051 being slow
      output_float(sensor_pin);
   }
   delay_us(105);       // Wait for end of timeslot
   output_float(sensor_pin);
}
//******************************************************************************
//
//******************************************************************************
// DESCRIÇAO:  Lê um byte do bus
//
// INPUT:   nada
//
// OUTPUT:  um byte lido do bus
//------------------------------------------------------------------------------
int8 read_byte(void)
{
   int8 i;
   int8 val = 0;

   for(i=0;i<8;i++)
   {
      if(read_bit()) val |= (0x01 << i);
      delay_us(120);  // To finish time slot
   }

   return val;
}
//******************************************************************************
//
//******************************************************************************
// DESCRIÇAO:  escreve um byte no bus
//
// INPUT: byte a ser enviado
//
// OUTPUT:  nada
//------------------------------------------------------------------------------

void write_byte(int8 val)
{
   int8 i;
   int8 temp;

   for (i=0;i<8;i++)
   {
      temp = val >> i;
      temp &= 0x01;
      write_bit(temp);
   }

   delay_us(105);
}


//******************************************************************************

//******************************************************************************
//DESCRIÇAO: Processa o valor de CRC recebido
//
// INPUT: Valor lido no bus
//
// OUTPUT: Valor processado
//------------------------------------------------------------------------------
int8 ow_crc(int8 x)
{
   dowcrc = dscrc_table[dowcrc^x];
   return dowcrc;
}
//******************************************************************************

//******************************************************************************
// DESCRIÇAO:  Procura o proximo dispositivo no bus e armazena o seu serial
//
// INPUT:   Nada
//
// OUTPUT:  1 se novos dispositivos encontrados
//          0 se nao houver novos dispositivos
//------------------------------------------------------------------------------
int8 Next(void)
{
   int8 m = 1;             // ROM Bit index
   int8 n = 0;             // ROM Byte index
   int8 k = 1;             // Bit mask
   int8 x = 0;
   int8 discrepMarker = 0;
   int8 g;                 // Output bit
   int8 nxt;               // Return value
   short flag;


   nxt = FALSE;            // Reset next flag to false

   dowcrc = 0;             // Reset the dowcrc

   flag = ow_reset(); // igual a 1 si no hay dispositivos ..

   if (flag||doneFlag)     // If no parts return false y no estamos en first()...
   {
      lastDiscrep = 0;     // Reset the search
      return FALSE;
   }

   write_byte(0xF0);       // Send SearchROM command

   do
   {
      x = 0;
      if (read_bit() == 1) x = 2;
     delay_us(120);
      if (read_bit() == 1) x |= 1;   // And it's complement
     
//always read "1" and "1" HERE IS THE ERROR
################################
###########################################################################################################################
###########################################################################################################################
    printf(lcd_putc,"\fFOUND %u",x);
  //delay_ms(5000);
      if (x == 3)                   // There are no devices on the one wire bus
      break;
      else
      {
         if (x > 0)                 // All devices coupled have 0 or 1
            g = x >> 1;             // Bit write value for search

         // If this discrepancy is before the last discrepancy on a previous
         // Next then pick the same as last time.
         else
         {
            if (m < lastDiscrep)
               g = ((ROMM[n] & k) > 0);
            // If equal to last pick 1
            else
               g = (m == lastDiscrep);  // If not then pick 0

               // If 0 was picked then record position with mask k
               if (g == 0) discrepMarker = m;
         }

         // Isolate bit in ROM[n] with mask k
         if (g == 1) ROMM[n] |= k;
         else ROMM[n] &= ~k;

         write_bit(g);  // ROM search write

         m++;           // Increment bit counter m
         k = k << 1;    // and shift the bit mask k
         // If the mask is 0 then go to new ROM
         if (k == 0)
         {  // Byte n and reset mask
            ow_crc(ROMM[n]);      // Accumulate the crc
            n++;
            k++;
         }
      }
   } while (n < 8);  // Loop through until through all ROM bytes 0-7

   if (m < (65||dowcrc))   // If search was unsuccessful then
      lastDiscrep = 0;     // reset the last Discrepancy to zero

   else  // Search was successful, so set lastDiscrep, lastOne, nxt
   {
      lastDiscrep = discrepMarker;
      doneFlag = (lastDiscrep == 0);
      nxt = TRUE; // Indicates search not yet complete, more parts remain
   }

   return nxt;
}
//******************************************************************************

//******************************************************************************
// DESCRIÇAO: Reseta a actual procura e chama a funçao 'Next()' para iniciar a
//            procura do primeiro dispositivo no bus.
//
// INPUT:   Nada
//
// OUTPUT: O valor da funçao Next().
//------------------------------------------------------------------------------
int8 First(void)
{
   lastDiscrep = 0;
   doneFlag = FALSE;
   return Next();    // Call Next and return it's return value;
}
//******************************************************************************

//******************************************************************************
// DESCRIÇAO:  Procura novos dispositivos no bus
//
// INPUT: Nada
//
// OUTPUT: Nada
//------------------------------------------------------------------------------
void FindDevices(void)
{
   int8 m;

   if(!ow_reset())//(Si hay un dispositivo presente) devuelve 0 si un dispositivo esta presente
   {
     
   
      if(First())    // Begins when at least one part found
      {
     
         numROMs = 0;

         do
         {
            numROMs++;

            for (m=0;m<8;m++)
            {
               FoundROM[numROMs][m] = ROMM[m];   // Identifies ROM no. on device
            }
           
/*
            printf("\r\nEndereco do dispositivo No %u: ",numROMs);

            printf("%X%X%X%X%X%X%X%X\n\r",
            FoundROM[numROMs][7],FoundROM[numROMs][6],FoundROM[numROMs][5],
            FoundROM[numROMs][4],FoundROM[numROMs][3],FoundROM[numROMs][2],
            FoundROM[numROMs][1],FoundROM[numROMs][0]);
           
*/
         } while (Next() && (numROMs<10));   // Continues until no additional
                                             // devices found.
       
         
               
         
      }
    //  printf(lcd_putc,"\fFOUND %u",numROMs);
          delay_ms(2000);
   }
 // putc('\n'); putc('\r');
}
//******************************************************************************

//******************************************************************************
// DESCRIÇAO:  envia o comando Match_rom e depois o endereço do dispositivo
//
// INPUT: Nada
//
// OUTPUT: 0 se o dispositivo nao esta presente
//         1 se o dispositivo esta presente
//------------------------------------------------------------------------------
int8 Send_MatchRom(int num_dispositivo)
{
   int8 i;
   if (ow_reset()) return FALSE;          // 0 if device present
   write_byte(0x55);                      // Match ROM

   for (i=0;i<8;i++)
   {
      write_byte(FoundRom[num_dispositivo][i]);   // Send ROM code
   }

   return TRUE;
}
/******************************************************************************/


And the ds1820 driver..

Code:
//******************************************************************************
//                               ds1820.c
//
//    Driver para o sensor de temperatura digital ds1820
//
//    *tem que definir 2 variaveis globais no programa main: int8 inteiro, decimal;
//
// AUTOR: Ricardo Lopes    DATA: Março 2006
//------------------------------------------------------------------------------

#if !defined sensor_pin
   #error   Tem que definir o pino de comunicaçao //#define sensor_pin pin_XX (onde XX é o pino)
#endif

#include <onewire.c>

#define SEARCH_ROM        0XF0
#define MATCH_ROM         0X55
#define READ_ROM          0X33
#define SKIP_ROM          0xcc
#define READ_SCRACHPAD    0xbe
#define CONVERT           0x44
#define READ_POWER_SUPPLY 0xb4

//******************************************************************************
// void read_ds1820_scrachpad(void)
//
// DESCRIÇAO: Lê o scrachpad (9 bytes);
//
// INPUT: vector com 9 elementos que vai armazenar os valores;
//
// OUTPUT: Vector inicial com os dados adquiridos;
//
//------------------------------------------------------------------------------
void read_ds1820_scrachpad(int8 data[9]){
byte i,j;

     for(i=0;i<9;i++){ // para ler 9 bytes
         for(j=0;j<8;j++){ // para ler 8 bits

            output_low(sensor_pin);
            delay_us(2);
            output_float(sensor_pin);
            delay_us(9);
            shift_right(&data[i],1,input(sensor_pin));
            delay_us(60);  //tempo de slot

         }
     }
}
//******************************************************************************

//******************************************************************************
// void ler_temp (void)
//
// DESCRIÇÃO: Faz a sequencia de leitura dos valores do scrachpad;
//
// INPUT:   Vector que vai armazenar os dados lidos;
//
// OUTPUT:  Vector preenchido com os valores recebidos
//
// OBS: A funçao 'convert_temp(dispositivo)' deve ser chamada imediatamente antes
//      da leitura de temperatura.
//------------------------------------------------------------------------------
int1 read_temp (int data[9], int num_dispositivo)
{
   
   if(!send_MatchRom(num_dispositivo))    //envia o rom code e se encontrado, devolve 1
      return FALSE;
   write_byte(READ_SCRACHPAD);  //envia o comando para leitura de scratchpad
   read_ds1820_scrachpad(data);        //faz a leitura do scratchpad
   return TRUE;
}
//******************************************************************************

//******************************************************************************
// int1 convert_temp(void)
//
// DESCRIÇAO:  Envia para todos os dispositivos o comando de inicio de conversao de temperatura
//
// INPUT:   Numero do dispositivo
//
// OUTPUT:  nada
//------------------------------------------------------------------------------

int1 convert_temp(void)
{

   if(ow_reset())
      return FALSE;
   
   write_byte(SKIP_ROM);  // Selecciona todos os dispositivos
   write_byte(CONVERT);   // envia o comando para iniciar a conversao de temperatura

   if(parasite_power){      //se nao estiver alimentado por Vcc
      output_high(sensor_pin);   //aplicar um forte pull up
      delay_ms(750);                //delay obrigatório para conversao de temperatura
      return TRUE;
   }
   else{                   // Se estiverem alimentados por Vcc
      while(!input(sensor_pin))  //|
         delay_ms(5);            //|Espera que todos terminem a conversao
      return TRUE;
   }
}

//******************************************************************************
// void ler_rom(int rom[8])
//
// DESCRIÇAO: Lê os 64 bits que compoêm o endereço de rom
//
// INPUT:   Vector que vai armazenar os valor da rom
//
// OUTPUT:  Vector preenchido com o codigo serial do chip
//------------------------------------------------------------------------------
void read_ds1820_rom(int romm[8])
{
   int i,j;

   if(!ow_reset()){
      write_byte(READ_ROM);

      for(i=0;i<8;i++){
         for(j=0;j<8;j++){

            output_low(sensor_pin);
            delay_us(2);
            output_float(sensor_pin);
            delay_us(9);
            shift_right(&romm[i],1,input(sensor_pin));
            delay_us(60);
         }//for
      }//for
   } //if
}  //final de funçao
//******************************************************************************

void trata_temperatura (int dados[9])
{
int count_rem, count_per_c, i;
static int16 valor, sub, div, final, final_aux, aux;

   count_rem = dados[6];
   count_per_c = dados[7];

   shift_right(dados,2,0);    //discarta o bit menos significativo
   valor=dados[0];            //passa para uma variavel de 16 bits (byte menos significativo)

   for(i=0;i<8;i++)
      shift_left(&valor,2,0);    //passa para o byte mais significativo

   valor= valor - 0x40;    //subtrai 0.25 (0x40 em hexadecimal)

   sub=count_per_c - count_rem;  //faz a subtracçao do numerador

   for(i=0;i<8;i++)
      shift_left(&sub,2,0);      //multiplica por 100 (basta mover 8 bits para a esquerda)

   div=sub/count_per_c;       //faz a divisao

   final= valor + div;        //efectua a soma da equaçao (com o resultado anterior)
   aux=final;                 //passa para uma variavel auxiliar

   for(i=0;i<8;i++)           //|
      shift_left(&aux,2,0);      //|
                           // ficar com o byte menos significativo e abdicar do mais significativo
   for(i=0;i<8;i++)           //|
      shift_right(&aux,2,0);     //|

   final_aux=aux*0x64;        //converter o resultado da fracçao para decimal

   for(i=0;i<8;i++)
      shift_right(&final_aux,2,0);  //passar para o byte menos significativo

   decimal=final_aux;         //passar para uma variavel de 8 bits

   for(i=0;i<8;i++)           //passar para o byte menos significativo
      shift_right(&final,2,0);

   inteiro=final;             //passar para uma variavel de 8 bits
}
//******************************************************************************

//******************************************************************************
// int1 search_supply (void)
//
// DESCRIÇAO: Pesquisa no bus se existe algum dispositivo com parasite_power
//
// INPUT:   Nada
//
// OUTPUT: 0 se nao houver nenhum dispositivo com parasite_power
//         1 se houver algum dispositivo com parasite_power
//------------------------------------------------------------------------------
int1 search_supply (void)
{
   int1 power;

   if(!ow_reset())
   {
      write_byte(SKIP_ROM);
      write_byte(READ_POWER_SUPPLY);
      power=read_bit();
      return !power; //
   }   
}
//******************************************************************************
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Jul 31, 2008 7:10 pm     Reply with quote

Today someone reminded me: 'A lazy programmer is a good programmer.'
- I don't want to read your large posted program. I like the problems presented as a short test program.
- If possible I use tested code. Have a look at the CCS supplied driver ds2432.c It contains a function search_rom() for finding all chips on the bus.


Remark: your function ow_reset() has several timings barely within specifications. If bus loading is a bit larger you will read wrong data.
herselmann



Joined: 31 May 2008
Posts: 7

View user's profile Send private message

PostPosted: Fri Aug 01, 2008 1:30 am     Reply with quote

Have a look at the app notes on the Maxim website. They have an app note with the complete search function. Do a search and you should find the links.

All you need to do is to port it to CCS, which is really not that difficult. I am currently working on a new OW lib with just about all the functions found in the OW Public Domain kit. I can however not release it yet as it is not 100% tested yet, but should do so soon.

I do remember though that the Match ROM command does not 'follow' the flow chart in the datasheets. Effectively you have to do a search ROM and then see if the device you want to match is in the list of found devices, if so, then send your Match ROM command followed by your specific command. The datasheet gave the impression that the device echos each bit sent to it (well at least thats how I understood it ).
_________________
There are only 10 kinds of people, those who understand binary and those who don't.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group