1-wire HC908 implementation

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

1-wire HC908 implementation

7,658件の閲覧回数
andremun
Contributor I
Greetings,
I want to know if anybody has used a 1-wire protocol device with an HC908 device.
Thanks
ラベル(1)
0 件の賞賛
20 返答(返信)

2,052件の閲覧回数
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 件の賞賛

2,052件の閲覧回数
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 件の賞賛

2,052件の閲覧回数
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 件の賞賛

2,052件の閲覧回数
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 件の賞賛

2,052件の閲覧回数
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 件の賞賛

2,052件の閲覧回数
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 件の賞賛

2,051件の閲覧回数
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 件の賞賛

2,052件の閲覧回数
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 件の賞賛

2,052件の閲覧回数
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 件の賞賛

2,052件の閲覧回数
andremun
Contributor I
Thanks Roger...  I'll check it out.
0 件の賞賛

2,052件の閲覧回数
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 件の賞賛

2,052件の閲覧回数
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 件の賞賛

2,052件の閲覧回数
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 件の賞賛

2,052件の閲覧回数
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 件の賞賛

2,052件の閲覧回数
andremun
Contributor I
Thanks Bigmac, I will get back when I test it.
0 件の賞賛

2,052件の閲覧回数
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 件の賞賛

2,052件の閲覧回数
peterkranl
Contributor I
JUST LOOK HERE
 
 
HAVE A NICE TIME
0 件の賞賛

2,052件の閲覧回数
andremun
Contributor I
thanks peterkranl...  Problem solved.
0 件の賞賛

2,052件の閲覧回数
peg
Senior Contributor IV
Hello,

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

0 件の賞賛

2,052件の閲覧回数
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 件の賞賛