📄 ds18b20_search.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 + -