⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ds18b20_search.c

📁 一个DS18B20的库文件
💻 C
字号:
//------------------------------------------------------------------------------
// 文件名:DS18B20_search.c
// 说明:  本程序来自Maxim/Dallas官方应用笔记AN-187 1-wire搜索方法
// 功能:  搜索1-wire总线上的18B20器件,获取其id
// 使用方法:
//    定义一变量reslt,如果单总线上有一个器件,直接用语句
//    reslt=OWFirst()便可以把器件ID读入ROM_NO数组中。
//    如果有多个器件,可参考以下操作。
//    rslt = OWFirst();
//    while(rslt)  过程说明:执行完一次搜索后,判断rslt的返回值,如果rslt返回为1的时候说明总线上
//    {                      还有其他器件,即执行OWNext()函数,直到返回值为0说明所有器件已经都被搜索到
//    此处可以加入处理已找到的第
//    一个器件的代码。
//    rslt = OWNext();
//    }
// 运行平台:   AVR 8bit (M128已验证)
// 依存关系:   DS18B20_driver.c    DS18B20基本驱动(包括读写位、字节方法)
//              DS18B20_driver.h
//              DS18B20_search.h    本文件之头文件(定义了全局变量NUM_NO[],存放ID)
// 移植人:     刘大川
// 最后修改:   2008-6-3
//------------------------------------------------------------------------------

#include <avr/interrupt.h>
#include "DS18B20_driver.h"
#include "DS18B20_search.h"

static unsigned char dscrc_table[] = {
        0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
      157,195, 33,127,252,162, 64, 30, 95,  1,227,189, 62, 96,130,220,
       35,125,159,193, 66, 28,254,160,225,191, 93,  3,128,222, 60, 98,
      190,224,  2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
       70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89,  7,
      219,133,103, 57,186,228,  6, 88, 25, 71,165,251,120, 38,196,154,
      101, 59,217,135,  4, 90,184,230,167,249, 27, 69,198,152,122, 36,
      248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91,  5,231,185,
      140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
       17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
      175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
       50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
      202,148,118, 40,171,245, 23, 73,  8, 86,180,234,105, 55,213,139,
       87,  9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
      233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
      116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53};

//--变量说明:id_bit            第一次从搜索位读取的值是所有器件的逻辑与运算
//            cmp_id_bit        第二次从搜索位读取的所有器件的反的逻辑与运算
//            id_bit_number     记录当前搜索是1 到64位ROM 码中哪一位的量
//            LastDeviceFlag    指明前一次搜索到的已是最后一个器件的标志位
//            LastDiscrepancy   位指针指明下次搜索从哪个值差异位开始
//            last_zero         上次被写入0 的值差异位的位置
//            ROM_NO            记录当前正在查找的ROM 注册码的8 字节缓冲器
//            search_direction  位变量其值用来指明搜索方向具有此数据位规定值的所
//                              有器件继续响应搜索操作其它器件转入等待状态直到下一次1-Wire 复位





unsigned char ROM_NO[8];
int LastDiscrepancy;
int LastFamilyDiscrepancy;
int LastDeviceFlag;
int id_bit_number;
int last_zero, rom_byte_number, search_result;
int id_bit, cmp_id_bit;
unsigned char rom_byte_mask, search_direction;
unsigned char crc8;



//----------CRC校验函数------------------------------
unsigned char docrc8(unsigned char value)
{
    // See Application Note 27

    // TEST BUILD
    crc8 = dscrc_table[crc8 ^ value];
    return crc8;
}


//--------------------------------------------------------------------------
// Perform the 1-Wire Search Algorithm on the 1-Wire bus using the existing
// search state.
// Return TRUE  : device found, ROM number in ROM_NO buffer
//        FALSE : device not found, end of search
// OWSearch()查找函数,如果找到器件返回TRUE,如果没找到则返回FALSE
int OWSearch(void)
{
    cli();
    // 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 (reset_18B20()==FALSE)             //当复位无应答,则没有器件挂在总线上,直接退出
        {
            // reset the search
            LastDiscrepancy = 0;
            LastDeviceFlag = FALSE;
            LastFamilyDiscrepancy = 0;
            return FALSE;
        }
        
        // issue the search command
        write_byte_18B20(0xF0);
        // loop to do the search
        do
        {
            // read a bit and its complement
            id_bit = read_bit_18B20();
            cmp_id_bit = read_bit_18B20();

            // 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_18B20(search_direction);

                // increment the byte counter id_bit_number
                // and shift the mask rom_byte_mask
                id_bit_number++;
                rom_byte_mask <<= 1;

                // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask
                if (rom_byte_mask == 0)
                {
                    docrc8(ROM_NO[rom_byte_number]);  // accumulate the CRC
                    rom_byte_number++;
                    rom_byte_mask = 1;
                }
            }
        }
        while(rom_byte_number < 8);  // loop until through all ROM bytes 0-7
        // if the search was successful then
        if (!((id_bit_number < 65) || (crc8 != 0)))
        {
            // search successful so set LastDiscrepancy,LastDeviceFlag,search_result
            LastDiscrepancy = last_zero;

            // check for last device
            if (LastDiscrepancy == 0)
                LastDeviceFlag = TRUE;

            search_result = TRUE;
        }
    }

    // if no device found then reset counters so next 'search' will be like a first
    if (!search_result || !ROM_NO[0])
    {
        LastDiscrepancy = 0;
        LastDeviceFlag = FALSE;
        LastFamilyDiscrepancy = 0;
        search_result = FALSE;
    }

    sei();
    return search_result;
}


//--------------------------------------------------------------------------
// Find the 'first' devices on the 1-Wire bus
// Return TRUE  : device found, ROM number in ROM_NO buffer
//        FALSE : no device present
//OWFirst()查找第一个器件,如果找到返回TRUE,并把结果存入ROM_NO,如果没找到责返回FALSE
int OWFirst(void)
{
    // reset the search state
    LastDiscrepancy = 0;
    LastDeviceFlag = FALSE;
    LastFamilyDiscrepancy = 0;

    return OWSearch();
}

//--------------------------------------------------------------------------
// Find the 'next' devices on the 1-Wire bus
// Return TRUE  : device found, ROM number in ROM_NO buffer
//        FALSE : device not found, end of search
//查找下一个器件的ROM的ID,如果找到返回TRUE,如果没找到责返回FALSE
//一般在进行完OWFirst()函数或者OWNext后进行使用
int OWNext(void)
{
    // leave the search state alone
    return OWSearch();
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -