- uint8_t OWSearch(void)
 
- {
 
-     uint8_t id_bit_number; //指示当前搜索ROM位(取值范围为1-64)
 
-     /*下面三个状态变量含义:last_zero:指针,记录一次搜索(ROM1-64位)最后一位往0走的混码点编号
 
-                           search_direction:搜索某一位时选择的搜索方向(0或1),也是“一写”的bit位值
 
-                           rom_byte_number:ROM字节序号,作为ROM_no[]数组的下标,取值为1—8
 
-     */
 
-     uint8_t last_zero, rom_byte_number, search_result;
 
 
-     uint8_t id_bit, cmp_id_bit,search_direction; //二读(正码、反码)、及一写(决定二叉搜索方向)
 
-     uint8_t rom_byte_mask ; //ROM字节掩码
 
 
-     //初始化本次搜索变量
 
-     id_bit_number = 1;
 
-     last_zero = 0;
 
-     rom_byte_number = 0;
 
-     rom_byte_mask = 1;
 
-     search_result = 0;
 
-     crc8 = 0;
 
 
-     /*
 
-     是否搜索完成(已到最后一个设备)?
 
-     */
 
-     if(!LastDeviceFlag) //LastDeviceFlag由上轮搜索确定是否为最后器件,当然首次进入前必须置FALSE
 
-     {
 
-         DS18B20_Rst();
 
-         //if(OWReset()) //复位总线
 
-         if(DS18B20_Check())
 
-         {
 
-             LastDiscrepancy = 0; //复位几个搜索变量
 
-             LastDeviceFlag = FALSE;
 
-             LastFamilyDiscrepancy = 0;
 
-             return FALSE; //如果无应答,返回FALSE,退出本轮搜索程序
 
-         }
 
-         DS18B20_Write_Byte(0xF0); //发送ROM搜索命令F0H
 
-         __delay_us(60);
 
 
-         /*
 
-         开始循环处理1-64位ROM,每位必须进行“二读”后进行判断,确定搜索路径
 
-         然后按选定的路径进行“一写”,直至完成全部位的搜索,这样一次循环
 
-         可以完成一轮搜索,找到其中一个ROM码
 
-         */
 
-         do //逐位读写搜索,1-64位循环
 
-         {
 
-             id_bit = DS18B20_Read_Bit(); //二读:先读正码、再读反码
 
-             cmp_id_bit = DS18B20_Read_Bit();
 
 
-             if(id_bit && cmp_id_bit) //二读11,则无器件退出程序
 
-                 break;
 
-             else //二读不为11,则需分二种情况
 
-             {
 
-             /*
 
-             第一种情况:01或10,直接可明确搜索方向
 
-             */
 
-                 if(id_bit != cmp_id_bit)
 
-                     search_direction = id_bit; //记下搜索方向search_direction的值待“一写”
 
-                 else
 
-                 {
 
-                 /* 
 
-                 第二种情况:遇到了混码点,需分三种可能分析:
 
-                 1、当前位未到达上轮搜索的“最末走0混码点”(由LastDiscrepancy存储)
 
-                 说明当前经历的是一个老的混码点,判别特征为当前位在(小于)LastDiscrepancy前
 
-                 不管上次走的是0还是1,只需按上次走的路即可,该值需从ROM_NO中的当前位获取
 
-                 */
 
-                     if(id_bit_number < LastDiscrepancy)
 
-                         search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0);
 
-                     else
 
-                     /*
 
-                     2、当前位正好为上轮标记的最末的混码点,这个混码点也就是上次走0的点,那么这次就需要走1
 
-                     3、除去上二种可能,那就是第3种可能: 这是一个新的混码点,id_bit_number>LastDiscrepancy
 
-                     下一条语句巧妙地将上二种可能合在一起处理
 
-                     */
 
-                         search_direction = (id_bit_number == LastDiscrepancy);
 
 
-                     /* 
 
-                     确定了混码点的路径方向还没完事,还需要更新一个指针:last_zero
 
-                     这个指针每搜索完一位后(注意是一bit不是一轮)总是指向新的混码点
 
-                     凡遇到新的混码点,我们按算法都是先走0,所以凡遇走0的混码点必须更新此指针
 
-                     */
 
-                     if(search_direction == 0)
 
-                     {
 
-                         last_zero = id_bit_number;
 
 
-                     /*
 
-                     下面二条是程序的高级功能了:64位ROM中的前8位是器件的家族代码,
 
-                     用LastFamilyDiscrepancy这个指针来记录前8位ROM中的最末一个混码点
 
-                     可用于在多类型器件的单线网络中对家族分组进行操作
 
-                     */
 
-                         if(last_zero < 9)
 
-                             LastFamilyDiscrepancy = last_zero;
 
-                     }
 
-                 }
 
 
-                 /*
 
-                 确定了要搜索的方向search_direction,该值即ROM中当前位的值,需要写入ROM
 
-                 然而64位ROM需分8个字节存入ROM_NO[],程序使用了一个掩码字节rom_byte_mask
 
-                 以最低位为例:该字节值为00000001,如记录1则二字节或,写0则与反掩码
 
-                 */
 
-                 if(search_direction == 1)
 
-                     ROM_NO[rom_byte_number] |= rom_byte_mask;
 
-                 else
 
-                     ROM_NO[rom_byte_number] &= ~rom_byte_mask;
 
 
-                 //关键的一步操作终于到来了:一写
 
-                 DS18B20_Write_Bit(search_direction);
 
 
-                 /*
 
-                 一个位的操作终于完成,但还需做些工作,以准备下一位的操作:
 
-                 包括:位变量id_bit_number指向下一位,字节掩码左移一位
 
-                 */
 
-                 id_bit_number++;
 
-                 rom_byte_mask <<= 1;
 
 
-                 //如果够8位一字节了,则对该字节计算CRC处理,更新字节号变量,重设掩码
 
-                 if(rom_byte_mask == 0)
 
-                 {
 
-                     GenerateCRC8(ROM_NO[rom_byte_number]); //CRC计算
 
-                     rom_byte_number++;
 
-                     rom_byte_mask = 1;
 
-                 }
 
-             }
 
-         }
 
-         while(rom_byte_number < 8); //ROM bytes编号为 0-7
 
-         //代码中是利用rom_byte_number<8来判断的,至此,完成8个字节共64位的循环处理
 
-  
 
-         //一轮搜索成功,找到的一个ROM码也校验OK,则还要处理二个变量
 
-         if(!((id_bit_number < 65) || (crc8 != 0)))
 
-         {
 
-         /*
 
-         一轮搜索结束后,变量last_zero指向了本轮中最后一个走0的混码位
 
-         然后再把此变量保存在LastDiscrepancy中,用于下一轮的判断
 
-         last_zero在下轮初始为0,搜索是该变量是不断变动的
 
-         */
 
-             LastDiscrepancy = last_zero;
 
 
-             //如果这个指针为0,说明全部搜索结束,再也没有新ROM号器件了
 
-             if(LastDiscrepancy == 0)
 
-                 LastDeviceFlag = TRUE; //设置结束标志
 
-         
 
-                 search_result = TRUE; //返回搜索成功
 
-         }
 
-     }
 
 
-     /*
 
-     //搜索完成,如果搜索不成功包括搜索到了但CRC错误,复位状态变量到首次搜索的状态
 
-     */
 
-     if(!search_result || !ROM_NO[0])
 
-     {
 
-         LastDiscrepancy = 0;
 
-         LastDeviceFlag = FALSE;
 
-         LastFamilyDiscrepancy = 0;
 
-         search_result = FALSE;
 
-     }
 
-     return search_result;
 
- }
测试代码: