1-wire HC908 implementation

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

1-wire HC908 implementation

7,611 Views
andremun
Contributor I
Greetings,
I want to know if anybody has used a 1-wire protocol device with an HC908 device.
Thanks
Labels (1)
0 Kudos
20 Replies

2,005 Views
andremun
Contributor I
Greetings,
It has been a while since my last post.  I was able to get a reset pulse and it appeared that my network responded.  But when I tried to get an scan of the addresses, it failed.  I used the 1-wire library provided in http://www.68hc08.net/ site, and I modified to my clock period.  I also made some modifications in the routines for writting and reading a bit.  I'm also using embedded beans to control the GPIO pin and the delays larger than 100us.  The routines are:
 
bool OWReset(void){
  bool result;
  Bit1_SetDir(TRUE);
  Bit1_ClrVal();        //envoi du reset
  //esperando 480us
  Cpu_Delay100US(4);
  asm{
          LDA 132
    RST1: DBNZA RST1
  }
  Bit1_SetVal();
  //esperar 70us
  asm{
          LDA 116
    RST2: DBNZA RST2
  }
  Bit1_SetDir(FALSE);
  result = Bit1_GetVal(); //on regarde si le composant répond
  //esperando 410us
  Cpu_Delay100US(4);
  asm{
          LDA 16
    RST3: DBNZA RST3
  }
  Bit1_SetDir(TRUE);
  return result;
}
 
char OWReadBit(void){
  char result;
  Bit1_SetDir(TRUE);         //Recibiendo el dato
  Bit1_ClrVal();
  //esperando 6us
  asm{
          LDA 10
    RAD1: DBNZA RAD1
  }
  Bit1_SetVal();
  //esperando 6us
  asm{
          LDA 10
    RAD2: DBNZA RAD2
  }
  Bit1_SetDir(FALSE);
  result = Bit1_GetVal();
  //esperando 55us
  asm{
          LDA 91
    RAD3: DBNZA RAD3
  }
  Bit1_SetDir(TRUE);
  return result;
}
 
void OWWriteBit(char bit){
  Bit1_SetDir(TRUE);
  if (bit){
    Bit1_ClrVal();            //Escribir '1'
    asm{
            LDA 10
      WRT1: DBNZA WRT1
    }
    Bit1_SetVal();
    asm{
            LDA 106
      WRT2: DBNZA WRT2
    }
  }
  else
  {
    Bit1_ClrVal();            //Escribir '0'
    asm{
            LDA 106
      WRT3: DBNZA WRT3
    }
    Bit1_SetVal();
    asm{
            LDA 16
      WRT4: DBNZA WRT4
    }
  }
  Bit1_SetDir(TRUE);
}
 
I want to know if maybe anybody has been able to get the routines from 68hc08.net/ to work.  Or if I have a code error.  I know that the acknowledgement pulse its not being recorded by the mcu, although it is produced by the device (I checked this out with an osciloscope).
 
0 Kudos

2,005 Views
bigmac
Specialist III
Hello,
 
For your code listed in the previous post, there seem to be a fundamental problem with your delay code.  The following code typically occurs a a number of locations -
 
   // esperar 70us
   asm {
      LDA 116
RST2: DBNZA RST2
   }
 
This code requres that the delay value representing 70 us be resident at address 116 (decimal).  I suspect this is not what you intend, and that you actually require immediate addressing for the delay parameter.
 
Assuming a HC908 device with 6 MHz bus, the parameter value should be 140, for a 70 us delay,
i.e. 70 * 6 / 3 = 140
 
Regards,
Mac
0 Kudos

2,005 Views
andremun
Contributor I
Greetings to all,
We finally were able to make it work.  Thanx to everybody that wrote, your help was invaluable.
Bye!
0 Kudos

2,005 Views
thinkchip
Contributor II

Hi, I got problems with the driver, I decided do my own driver based in the application notes AN167 and AN187 from maxim dallas semiconductor web, I post the header file and tha c file, but i dont know where are the problem, because my program didn't work

the diferents its the delay, I change the original for the posted bigmac, but my bus clock is 8MHz, I don't know if that's are the problem, again sorry for my patetic english

 

 

my delay is this 

 

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

for a BUS CLOCK of 8 MHz

 

I used the MC9S08QE32

 

header file 

1_wire.h

 

 

/********************************************************************************* 1_wire.h** functions of 1wire sensors*******************************************************************************/#define TRUE 1#define FALSE 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/*******************************************************************************  principal functions**  DS18S20*******************************************************************************/void ow_scan(void);/*******************************************************************************  principal functions**  DS18S20*******************************************************************************/void ow_select(char);/*******************************************************************************  principal functions**  DS18S20*******************************************************************************/char ow_verify(void); /*******************************************************************************  principal functions**  DS18S20*******************************************************************************/int ds1820_temperatureX2(char);void Read_Temperature(void);void read_ROM_code(void);

 

and the 1_wire.c file
 
/**********************************************************************************  1_wire.c**  DEFINITIONS FUNCTIONS**  braulio elias chi salavarria******************************************************************************/#include "derivative.h"#include "1_wire.h"#include "sci.h"/********************************************************************************** VARIABLES EXTERNS  ********************************************************************************/ // global search stateunsigned char nb_components;unsigned char ROM_NO[8];unsigned char LastDiscrepancy;unsigned char LastFamilyDiscrepancy;unsigned char LastDeviceFlag;unsigned char crc8;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 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};/*******************************************************************************  void delay 2 us*****************************************************************************/static void delay_2us(unsigned int n);/*******************************************************************************  principal functions*****************************************************************************//* ow_reset function return 0 if there any sensor*/static char ow_reset(void);/* read bit functions*/static char read_bit(void);/* write bit*/static void write_bit(char);/*read byte*/static void write_byte(unsigned char);/* read byte */static unsigned char read_byte(void);/* read crc configuration */static unsigned char docrc8(unsigned char);/*******************************************************************************  secundary functions*****************************************************************************//*First*/static unsigned char First(void);/*next*/static unsigned char Next(void);/*ow search*/char ow_search(void);/**********************************************************************************  definitions delay_us functions******************************************************************************/ void delay_2us(unsigned int n){   asm {       LDHX (n)LOOP1: AIX  #-1    ;[2]       NOP         ;[1]       NOP         ;[1]       CPHX #0     ;[3]       BNE  LOOP1  ;[3]  }}/*********************************************************************************  unsigned char ow_reset(void) fundamentals for communications sensor*****************************************************************************/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*****************************************************************************/char read_bit(void){   char i; DQ_TX=0; // delay_2us(1); DQ_TX=1; delay_2us(7);//delay for 16 us i=DQ_RX; delay_2us(24);//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(char bit){ if(bit){   DQ_TX=0; delay_2us(1); //delay for 2 us DQ_TX=1; delay_2us(30); }else{ DQ_TX=0; delay_2us(30);//delay for 30us DQ_TX=1; delay_2us(2);  }  }/*********************************************************************************  unsigned char read_byte(void)**  *****************************************************************************/unsigned char read_byte(void){   unsigned char loop, result;    result=0;    for (loop = 0; loop < 8; loop++){          //read lSB     result >>= 1;     //Right shift    if (read_bit())  {result |= 0x80;}          }  return result;}/*********************************************************************************  void write_byte(unsigned char);**  *****************************************************************************/  void write_byte(unsigned char value){       char loop;    for (loop = 0; loop < 8; loop++){    write_bit(value & 0x01);         //write bit to bit (LSB first)    value >>= 1;                          }      }  /*********************************************************************************  ONE WIRE CRC**  *****************************************************************************/      unsigned char docrc8(unsigned char value){  crc8=dscrc_table[crc8^value]; return crc8;   }  /*********************************************************************************  second layer of functions**  FIRST NEXT AND OW_SEARCH**  *****************************************************************************/  /*********************************************************************************  FIRST**  *****************************************************************************/    unsigned char First(void){    // reset the search state   nb_components=0;   LastDiscrepancy = 0;   LastDeviceFlag = FALSE;   LastFamilyDiscrepancy = 0;   return ow_search();  }        /*********************************************************************************  Next**  *****************************************************************************/    unsigned char Next(void){ return ow_search();}      /*********************************************************************************  ow search**  *****************************************************************************/   char ow_search(){  unsigned char id_bit_number;    //unsigned char last_zero;        //unsigned char rom_byte_number;  //unsigned char search_result;    //unsigned char id_bit;           //unsigned char cmp_id_bit;       //unsigned char rom_byte_mask;    //unsigned char search_direction; //char i;    // 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;                for(i=0;i<8;i++)  components[nb_components][i] = ROM_NO[i]; ////write table of code ROM               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  }}/*********************************************************************************  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;  }}/*********************************************************************************  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;  }/*********************************************************************  function for only one devices 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;  }*/void read_ROM_code(void){int n;char dat[9];SCI1_send_string("\nReading ROM Code\n\r");ow_reset();write_byte(0x33);for (n=0;n<8;n++){dat[n]=read_byte();}SCI1_send_string(dat);}void Read_Temperature(void){char get[10];char temp_lsb,temp_msb;char temperature [4];int k;//char temp_f,temp_c;ow_reset();write_byte(0xCC);  //Skip ROMwrite_byte(0x44);  // Start Conversiondelay_2us(2);ow_reset();write_byte(0xCC); // Skip ROMwrite_byte(0xBE);  // Read Scratch Padfor (k=0;k<9;k++){get[k]=read_byte();}SCI1_send_string("\n ScratchPAD DATA\r");SCI1_send_string(get); SCI1_send_string("\r"); SCI1_send_string("\r"); SCI1_send_string("\r"); SCI1_send_string("\r");temp_msb = get[1]; // Sign byte + lsbittemp_lsb = get[0]; // Temp data plus lsbif (temp_msb <= 0x80){temp_lsb = (temp_lsb/2);} // shift to get whole degreetemp_msb = temp_msb & 0x80; // mask all but the sign bitif (temp_msb >= 0x80) {temp_lsb = (~temp_lsb)+1;} // twos complementif (temp_msb >= 0x80) {temp_lsb = (temp_lsb/2);}// shift to get whole degreeif (temp_msb >= 0x80) {temp_lsb = ((-1)*temp_lsb);} // add sign bitSCI1_send_string( "\nTempC=\n");  // print temp. CSCI1_send_string("\r");SCI1_send_string("\r");SCI1_send_string("\r");SCI1_send_string("\r");bin_to_string(temp_lsb,temperature);SCI1_send_string(temperature); SCI1_send_string("\r");/*temp_c = temp_lsb; // ready for conversion to Fahrenheittemp_f = (((int)temp_c)* 9)/5 + 32;printf( "\nTempF=  %d degrees F\n", (int)temp_f );  // print temp. F*/}

 

Any recommendations are welcome
 
regards

 

 

 

0 Kudos

2,005 Views
bigmac
Specialist III

Hello,

 

If your assumption is that the delay_2us() function will generate a delay in 2 microsecond increments, for 8MHz bus frequency, this is incorrect.  The loop period is actually 10 cycles, or 1.25 us.  The loop period would need to be 16 cycles for 2 us increment.

 

However, without the added NOP instructions, the loop period would be 8 cycles, or 1.0 us. This is what I would prefer to use.

 

I have not checked the rest of your code for other problems. 

 

Regards,

Mac

 

0 Kudos

2,005 Views
thinkchip
Contributor II

Hi. thanks bigmac, I realize you are right, because I check the frecuency and I sorprise with the results, so I think that changed the value delays in the diferent functions and works right

 

Thanks again bigmac

 

regards

0 Kudos

2,004 Views
thinkchip
Contributor II

Hi, again a have problems with the delay, this time, its for a bus clock of jm60 with connection usb, so the bus clock its 24Mhz, my count says that I need 24cycles for a delay of 1us,

 

1us/(1/24Mhz)=24 cycles, but again a got problems, i try to use again the delay that bigmac post, for a delay of 1us

 

 

 

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

 

 

 

 but didnt work

 

best regards, sorry for my bad english

 

 

 

0 Kudos

2,005 Views
bigmac
Specialist III
Hello,
 
The main issue with the one-wire code given at the French website is that all the low level functions are dependent on the timing function delay_us(), which is intended for HCS08 devices.  This function uses inline assembly code for tight timing control, and provides an inner loop duration of 8 bus cycles, for a timing increment of one microsecond when the bus frequency is 8 MHz.
 
Unfortunately, this function has not been correctly implemented, and will give a gross timing error when the timing parameter value is an exact multiple of 256.  But this is a lurking bug, and probably does not affect its use in the one-wire routines.
 
However, my understanding is that you require to use a HC908 device (rather than the HCS08), and this function is problematic on two additional counts.  Firstly, the inner loop duration is reduced to 7 bus cycles, thus affecting the delay calibration.  Additionally, the function would appear incompatible with the parameter passing associated with the HC908 - it implicitly assumes that the first 16-bit parameter will be passed in H:X, which I seem to recall is not the case for the HC908.  Possibly this is a major reason you were unable to get the code to work.
 
When considering alternative coding that eliminates the first bug, I was unable to reduce the loop period below 8 cycles, so it would not be possible to get an exact calibration, in microseconds for a 6 MHz bus frequency.  This would require a loop period of six cycles.  Therefore the delay parameter will need to be scaled by a factor of 6/8 = 0.75.
 
The following alternative code should work correctly for both device families, and because the parameter is now explicitly used, one of the previous compiler warnings is eliminated -
 
void delay_us( unsigned int n)
{
  asm {
       LDHX (n)
LOOP1: AIX  #-1    ;[2]
       CPHX #0     ;[3]
       BNE  LOOP1  ;[3]
  }
}
 
For the HCS08 device, the total function overhead is 14 cycles, or about 2 microseconds.  This would mean that the parameter should be reduced by the amount of 2.
 
Assuming a similar overhead for the HC908 device (it probably won't be identical because of the different parameter passing), the formula for manually calculating the required parameter value would be -
n = (delay * 0.75) - 2
 
I also note that the code for the various function definitions is placed within a header file.  This is a doubtful coding practice.  The definitions should really be within a .c file.  But this has no bearing on the current problem.
 
Regards,
Mac
 
0 Kudos

2,005 Views
RogerSchaefer
Contributor III
Hi,
You may wish to check out my Digital Thermometer project
 
which uses the DS18B20 1-wire temperature sensor.
 
Roger Schaefer
0 Kudos

2,005 Views
andremun
Contributor I
Thanks Roger...  I'll check it out.
0 Kudos

2,005 Views
JimDon
Senior Contributor III
Roger,
What a fantastic job you did.

Any one who wishes to use asm programming, should take a look at this.
He has routines for mult-byte math in asm.
It also shows how a 3.3V mcu can be used with 5V logic.

Of course the MC14489 5 channel LED driver is obsolete as 7-segment leds are not used much anymore (not that I don't like them), but still it is a great example.

Thanks!


0 Kudos

2,005 Views
andremun
Contributor I
Greetings (again).  Sorry if I'm getting annoying.  I downloaded the library for 1-wire communication from 68hc08.net but I haven't been able to make it work with my application.  This is what I need to do:
I use a HC908BD48 device and the PTE0 pin for output and the PTC4 for Input.  In the MCU datasheet these pins are referenced as:
 
DDRE(E) bit / PTE(C) bit / IO Pin Mode
0                   / X                / Input, Hi-Z
1                   / X                / Output
 
I have a pull-up resistor connected to this device (470 Ohm).  I use a DS18B20 temperature sensor (family code 0x28).
The first problem that I have is that the MCU max op.Frequency is 6Mhz (unlike the other HC908).  This gives a 166.66ns cycle period.  The 1-wire library uses a software delay routine for timing, which claims a 1us period:
 
void delay_us(unsigned int n){
  //n est stocké dans les accus H puis X
  asm {       PSHH            // (2 c:  333.33ns)
                   PULA            // (2 c:  333.33ns)
    RETAR: NOP             // (1 c:  166.67ns)
                  NOP             // (1 c:  166.67ns)
                  NOP             // (1 c:  166.67ns)
                  NOP             // (1 c:  166.67ns)
                  DBNZX RETAR     // (3 c:  500.00ns)
                  CMP #0          // (2 c:  333.33ns)
                  BNE BCL2        // (3 c:  500.00ns)
                  RTS             // (4 c:  666.66ns)
    BCL2:    DECA            // (1 c:  166.66ns)
                  LDX #$FF        // (2 c:  333.33ns)
                  BRA RETAR       // (3 c:  500.00ns)    
    }
}
 
The routine in this MCU clearly exceeds the 1us period (I think it would also exceed the period in a 8Mhz MCU).
The timing requirements for the 1-wire interface are given by the information in the attached images.  So I think I could make a delay routine for 6us instead, by including a total fo 14 NOP instructions in the cycle, which still would not be very accurate.  This approach did not work.
I wonder if there is a better solution for this problem, since I have to use 26 sensors in the same bus.  I think software delays are not the best way to go.  Is there any way to create a hardware delay through a timer?
Also, If anybody has any experience in 1-wire communication with HC908, please tell me if the library works "off-the-shelf".
Thanks again.
0 Kudos

2,005 Views
bigmac
Specialist III
Hello,
 
The attached assembly code is untested, but you may be able to glean some ideas about generating software delays.  By the use of macros, I am able to take into account the actual bus frequency at the time the code is assembled.
 
Standard one-wire timing is assumed (not over-drive).  The code is intended for HCS08 devices, and may need some adjustment for HC908 parts, because of differing number of cycles for some instructions.  The PROCBIT sub-routine is the most time critical, and the OW_RESET sub-routine to a lesser extent.
 
The code makes use of a single pin, as defined in the .inc file, and it is intended that the one-wire device would be co-located with the MCU, to avoid the need for additional buffers.  A pull-up resistor value of 470 ohms seems somewhat low to directly connect to the MCU pin.
 
Regards,
Mac
 
0 Kudos

2,005 Views
bigmac
Specialist III
Hello,
 
Some additional information about my previous post - too late to edit.
 
The use of assembly code should provide the necessary timing control.  The low-level assembly routines can be called from within a C function.  The following is an example -
 
/* Send and receive one-wire byte */
byte ByteProc_1W( byte val)
{
   asm {
      lda  val
      jsr  OW_BYTEPROC  ; Call assembly subroutine
      sta  val
   }
   return (val);
}
 
Regards,
Mac
 
0 Kudos

2,005 Views
andremun
Contributor I
Thanks Bigmac, I will get back when I test it.
0 Kudos

2,005 Views
bigmac
Specialist III
Hello,
 
You will notice some errors in the original .inc file posted - I changed some sub-routine names at the last minute, and forgot to update the other file.  The corrected file is attached.
 
Regards,
Mac
 
0 Kudos

2,005 Views
peterkranl
Contributor I
JUST LOOK HERE
 
 
HAVE A NICE TIME
0 Kudos

2,005 Views
andremun
Contributor I
thanks peterkranl...  Problem solved.
0 Kudos

2,005 Views
peg
Senior Contributor IV
Hello,

Plugging 1-wire into the search box below produces several results.
So I guess the answer is yes.

0 Kudos

2,005 Views
andremun
Contributor I
Thanks for your answer, but this does not what I wanted to know, since the first thing that I did was use the search engine.  The other posts do not have any tech info about the implementation and only they mention it.
I wonder if anybody has made a software implementation for the protocol.
0 Kudos