【51单片机快速入门指南】6.3.1:使用1-WIRE搜索算法搜索单总线上所有DS18B20的ID(基于二叉树)

目录

  • 源码
    • OWSearch.c
  • 测试程序
    • 实验现象
      • Proteus仿真
      • 实机测试

普中51-单核-A2
STC89C52
Keil uVision V5.29.0.0
PK51 Prof.Developers Kit Version:9.60.0.0


       移植自1-WIRE搜索算法

       串口部分见【51单片机快速入门指南】3.3:USART 串口通信
       DS18B20驱动程序见【51单片机快速入门指南】6.3:DS18B20 单总线数字温度计的多路读取

源码

OWSearch.c

#include "DS18B20.h"
#include <stdio.h>// TMEX API TEST BUILD DECLARATIONS
// long session_handle;
// END TMEX API TEST BUILD DECLARATIONS// definitions
#define FALSE 0
#define TRUE  1// method declarations
int  OWFirst();
int  OWNext();
int  OWVerify();
void OWTargetSetup(unsigned char family_code);
void OWFamilySkipSetup();
int  OWReset();
void OWWriteByte(unsigned char byte_value);
void OWWriteBit(unsigned char bit_value);
unsigned char OWReadBit();
int  OWSearch();
unsigned char docrc8(unsigned char value);// global search state
unsigned char ROM_NO[8];
int LastDiscrepancy;
int LastFamilyDiscrepancy;
int LastDeviceFlag;
unsigned char crc8;//--------------------------------------------------------------------------
// Find the 'first' devices on the 1-Wire bus
// Return TRUE  : device found, ROM number in ROM_NO buffer
//        FALSE : no device present
//
int OWFirst()
{// reset the search stateLastDiscrepancy = 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
//
int OWNext()
{// leave the search state alonereturn OWSearch();
}//--------------------------------------------------------------------------
// 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
//
int OWSearch()
{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;// initialize for searchid_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 oneif (!LastDeviceFlag){// 1-Wire resetif (!OWReset()){// reset the searchLastDiscrepancy = 0;LastDeviceFlag = FALSE;LastFamilyDiscrepancy = 0;return FALSE;}// issue the search command OWWriteByte(0xF0);  // loop to do the searchdo{// read a bit and its complementid_bit = OWReadBit();cmp_id_bit = OWReadBit();// check for no devices on 1-wireif ((id_bit == 1) && (cmp_id_bit == 1))break;else{// all devices coupled have 0 or 1if (id_bit != cmp_id_bit)search_direction = id_bit;  // bit write value for searchelse{// if this discrepancy if before the Last Discrepancy// on a previous next then pick the same as last timeif (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 0search_direction = (id_bit_number == LastDiscrepancy);// if 0 was picked then record its position in LastZeroif (search_direction == 0){last_zero = id_bit_number;// check for Last discrepancy in familyif (last_zero < 9)LastFamilyDiscrepancy = last_zero;}}// set or clear the bit in the ROM byte rom_byte_number// with mask rom_byte_maskif (search_direction == 1)ROM_NO[rom_byte_number] |= rom_byte_mask;elseROM_NO[rom_byte_number] &= ~rom_byte_mask;// serial number search direction write bitOWWriteBit(search_direction);// increment the byte counter id_bit_number// and shift the mask rom_byte_maskid_bit_number++;rom_byte_mask <<= 1;// if the mask is 0 then go to new SerialNum byte rom_byte_number and reset maskif (rom_byte_mask == 0){docrc8(ROM_NO[rom_byte_number]);  // accumulate the CRCrom_byte_number++;rom_byte_mask = 1;}}}while(rom_byte_number < 8);  // loop until through all ROM bytes 0-7// if the search was successful thenif (!((id_bit_number < 65) || (crc8 != 0))){// search successful so set LastDiscrepancy,LastDeviceFlag,search_resultLastDiscrepancy = last_zero;// check for last deviceif (LastDiscrepancy == 0)LastDeviceFlag = TRUE;search_result = TRUE;}}// if no device found then reset counters so next 'search' will be like a firstif (!search_result || !ROM_NO[0]){LastDiscrepancy = 0;LastDeviceFlag = FALSE;LastFamilyDiscrepancy = 0;search_result = FALSE;}return search_result;
}//--------------------------------------------------------------------------
// Verify the device with the ROM number in ROM_NO buffer is present.
// Return TRUE  : device verified present
//        FALSE : device not present
//
int OWVerify()
{unsigned char rom_backup[8];int i,rslt,ld_backup,ldf_backup,lfd_backup;// keep a backup copy of the current statefor (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 deviceLastDiscrepancy = 64;LastDeviceFlag = FALSE;if (OWSearch()){// check if same device foundrslt = TRUE;for (i = 0; i < 8; i++){if (rom_backup[i] != ROM_NO[i]){rslt = FALSE;break;}}}elserslt = 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 verifyreturn rslt;
}//--------------------------------------------------------------------------
// Setup the search to find the device type 'family_code' on the next call
// to OWNext() if it is present.
//
void OWTargetSetup(unsigned char family_code)
{int i;// set the search state to find SearchFamily type devicesROM_NO[0] = family_code;for (i = 1; i < 8; i++)ROM_NO[i] = 0;LastDiscrepancy = 64;LastFamilyDiscrepancy = 0;LastDeviceFlag = FALSE;
}//--------------------------------------------------------------------------
// Setup the search to skip the current device type on the next call
// to OWNext().
//
void OWFamilySkipSetup()
{// set the Last discrepancy to last family discrepancyLastDiscrepancy = LastFamilyDiscrepancy;LastFamilyDiscrepancy = 0;// check for end of listif (LastDiscrepancy == 0)LastDeviceFlag = TRUE;
}//--------------------------------------------------------------------------
// 1-Wire Functions to be implemented for a particular platform
//--------------------------------------------------------------------------//--------------------------------------------------------------------------
// Reset the 1-Wire bus and return the presence of any device
// Return TRUE  : device present
//        FALSE : no device present
//
int OWReset()
{// platform specific// TMEX API TEST BUILD
//   return (TMTouchReset(session_handle) == 1);return (!DS18B20_init());
}//--------------------------------------------------------------------------
// Send 8 bits of data to the 1-Wire bus
//
void OWWriteByte(unsigned char byte_value)
{// platform specific// TMEX API TEST BUILD
//   TMTouchByte(session_handle,byte_value);DS18B20_write_byte(byte_value);
}//--------------------------------------------------------------------------
// Send 1 bit of data to teh 1-Wire bus
//
void OWWriteBit(unsigned char bit_value)
{// platform specific// TMEX API TEST BUILD
//   TMTouchBit(session_handle,(short)bit_value);DS18B20_write_bit((short)bit_value);
}//--------------------------------------------------------------------------
// Read 1 bit of data from the 1-Wire bus 
// Return 1 : bit read is 1
//        0 : bit read is 0
//
unsigned char OWReadBit()
{// platform specific// TMEX API TEST BUILD
//   return (unsigned char)TMTouchBit(session_handle,0x01);return DS18B20_read_bit();
}// TEST BUILD
code 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};//--------------------------------------------------------------------------
// Calculate the CRC8 of the byte value provided with the current 
// global 'crc8' value. 
// Returns current global crc8 value
//
unsigned char docrc8(unsigned char value)
{// See Application Note 27// TEST BUILDcrc8 = dscrc_table[crc8 ^ value];return crc8;
}//--------------------------------------------------------------------------
// TEST BUILD MAIN
//
void OWSearch_Func()
{short PortType=5,PortNum=1;int rslt,i,cnt;// TMEX API SETUP// get a session
//   session_handle = TMExtendedStartSession(PortNum,PortType,NULL);
//   if (session_handle <= 0)
//   {
//      printf("No session, %d\n",session_handle);
//      exit(0);
//   }// setup the port
//   rslt = TMSetup(session_handle);
//   if (rslt != 1)
//   {
//      printf("Fail setup, %d\n",rslt);
//      exit(0);
//   }// END TMEX API SETUP//搜索所有器件的示例// find ALL devicesprintf("\r\nFIND ALL\r\n");cnt = 0;rslt = OWFirst();while (rslt){// print device foundfor (i = 0; i < 8; ++i)printf("%02X", (short)ROM_NO[i]);printf("  %d\r\n",++cnt);rslt = OWNext();}
#if 0	//其他搜索示例// find only 0x1Aprintf("\r\nFIND ONLY 0x1A\r\n");cnt = 0;OWTargetSetup(0x1A);while (OWNext()){// check for incorrect typeif (ROM_NO[0] != 0x1A)break;// print device foundfor (i = 0; i < 8; ++i)printf("%02X", (short)ROM_NO[i]);printf("  %d\r\n",++cnt);}// find all but 0x04, 0x1A, 0x23, and 0x01printf("\r\nFIND ALL EXCEPT 0x10, 0x04, 0x0A, 0x1A, 0x23, 0x01\r\n");cnt = 0;rslt = OWFirst();while (rslt){// check for incorrect typeif ((ROM_NO[0] == 0x04) || (ROM_NO[0] == 0x1A) || (ROM_NO[0] == 0x01) || (ROM_NO[0] == 0x23) ||(ROM_NO[0] == 0x0A) || (ROM_NO[0] == 0x10))OWFamilySkipSetup();else{// print device foundfor (i = 0; i < 8; ++i)printf("%02X", (short)ROM_NO[i]);printf("  %d\r\n",++cnt);}rslt = OWNext();}
#endif// TMEX API CLEANUP// release the session
//   TMEndSession(session_handle);// END TMEX API CLEANUP
}

测试程序

void OWSearch_Func();void main(void)
{Timer_Init(TIMER_0, TIMER_MODE_2, GATE_DISABLE, CLK_Internal, 22118400, 10, STC_TIM_Priority_Highest);	//定时器配置为10us中断一次,8位重装载USART_Init(USART_MODE_1, Rx_ENABLE, STC_USART_Priority_Lowest, 22118400, 57600, DOUBLE_BAUD_DISABLE, USART_TIMER_1);while(1){		OWSearch_Func();delay_ms(1000);}	
}

实验现象

Proteus仿真

如图,成功正确搜索到各器件的ID
在这里插入图片描述

实机测试

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/400337.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

卡拉丁发布第四代车用空调滤清器

5月15日&#xff0c;卡拉丁“全澄行动”第四代车用空调滤清器产品发布会在京举行&#xff0c;据悉&#xff0c;该车用空调滤清器PM2.5过滤效率可高达99%。经国家权威检测机构广东省微生物分析检测中心检测&#xff0c;卡拉丁第四代车用空调滤清器对大肠杆菌、金***葡萄球菌抗菌…

【 Grey Hack 】大数四则运算

目录效果加减乘除乘方源码版本&#xff1a;Grey Hack v0.7.3619 - Alpha 在Gs中&#xff0c;位数大于15的整数将以科学计数法显示&#xff0c;故这里提供一种基于字符串加法的四则大数运算算法。由于位数大于10的字符串无法用to_int方法转化为整数&#xff0c;因此本示例中以长…

uniapp打包小程序上传测试后,使用有的插件显示空白页面,问题解决方【有效 / 最新】

目录 问题1图在微信开发者平台正常能使用 打包上传微信小程序测试问题2图在微信开发者平台正常能使用 打包上传微信小程序测试解决步骤一1.2.3. 解决步骤二打开微信小程序官网看图跨域网址 最后 问题1图 在微信开发者平台正常能使用 未上传小程序&#xff0c;开发过程中&…

django加载本地html

django加载本地html from django.shortcuts import renderfrom django.http import HttpResponse from django.shortcuts import render,render_to_response # Create your views here. def hello(request): return render_to_response("hello.html") 传递数据到htm…

Java知多少(68)面向字符的输出流

面向字符的输出流都是类 Writer 的子类&#xff0c;其类层次结构如图 10-5 所示。 图10-5 Writer的类层次结构图表 10-3 列出了 Writer 的主要子类及说明。 表 10-3 Writer 的主要子类类名功能说明CharArrayWriter写到字符数组的输出流BufferedWriter缓冲输出字符流PipedWriter…

Linux虚拟机的替代品:Docker与WSL2上手笔记

目录安装Docker可能出现的问题内核需更新Linux 内核更新包将 WSL 2 设置为默认版本An error occurred安装镜像使用Microsoft Store安装所选的 Linux 分发手动安装镜像及文件夹的共享Docker run 命令Windows Terminal的安装在Windows Terminal中直接运行已有的容器Windows 10 20…

flask需求文件requirements.txt的创建及使用

1.简介 Python项目中必须包含一个 requirements.txt 文件&#xff0c;用于记录所有依赖包及其精确的版本号用以新环境部署。 2.进入虚拟环境然后输入pip freeze > requirements.txt 每次安装或者升级了包之后最好也一并使用这个命令更新这个文件。 需求文件的内容示例…

【联盛德W806上手笔记】一、开发环境和烧录程序

目录简介芯片外观MCU 特性安全特性低功耗模式芯片结构管脚定义极限参数开发环境SDK的获取从官网获取从Q群获取iosetting大佬 维护的wm-sdk-w806打开工程编译固件烧录现象Windows 10 20H2 HLK-W806-V1.0-KIT WM_SDK_W806_v0.6.0 引自《W80X_MCU_快速入门V0.2》、《W806 MCU 芯片…

Mac os + Flask + PyCharm python开发环境集成

1. 打开mac自带终端安装virtualenv 执行 sudo easy_install virtualenv / sudo pip install virtualenv 2.安装完 virtualenv &#xff0c;打开一个 shell &#xff0c;创建自己的环境。 $ mkdir myapp $ cd myapp $ virtualenv venv New python executable in env/bin/py…

zookeeper注意几点

为什么80%的码农都做不了架构师&#xff1f;>>> Zookeeper 作为一个分布式的服务框架&#xff0c;主要用来解决分布式集群中应用系统的一致性问题&#xff0c;它能提供基于类似于文件系统的目录节点树方式的数据存储&#xff0c;但是 Zookeeper 并不是用来专门存储…

【51单片机快速入门指南】7:片上EEPROM

目录硬知识IAP及EEPROM新增特殊功能寄存器介绍EEPROM空间大小及地址小常识大建议常见问题示例程序EEPROM.cEEPROM.h测试程序main.c普中51-单核-A2 STC89C52 Keil uVision V5.29.0.0 PK51 Prof.Developers Kit Version:9.60.0.0 硬知识 摘自《STC89C52系列单片机器件手册》 ST…

wndows系统命令总结

window8系统下 打开运行窗口----------鼠标放到任务栏的windows图标下&#xff0c;右击&#xff0c;弹出菜单中如上图或者 打开运行窗口---------按“WINR”键&#xff0c; cmd-------打开命令窗口 services.msc--------打开服务命令 calc-----------启动计算器 dvdplay-------…

【RK3399Pro学习笔记】三、Debian 9 安装 ROS (Thinker Edge R)

目录配置源设置 Key安装初始化rosdep环境配置测试安装rosinstall卸载平台&#xff1a;华硕 Thinker Edge R 瑞芯微 RK3399Pro 固件版本&#xff1a;Tinker_Edge_R-Debian-Stretch-V1.0.4-20200615 参考资料&#xff1a; RK3399(Debian9 - stretch) 安装 ROS Lunar —— WB893…

perl学习(二)

2019独角兽企业重金招聘Python工程师标准>>> 在perl中又两个必须搞清楚&#xff0c;就是标量值和标量变量&#xff0c;列表和数组。 直接量就是数值在perl程序代码中的表现方式&#xff0c;就是直接写在程序里的数据&#xff0c;是标量值。如12&a…

【RK3399Pro学习笔记】四、ROS 创建工作空间与功能包

目录创建工作空间编译工作空间功能包创建功能包编译功能包设置环境变量检查环境变量平台&#xff1a;华硕 Thinker Edge R 瑞芯微 RK3399Pro 固件版本&#xff1a;Tinker_Edge_R-Debian-Stretch-V1.0.4-20200615 记录自【古月居】古月ROS入门21讲 | 一学就会的ROS机器人入门教…

hip-hop初探

啥都不说了&#xff0c;上两张图片先 1、使用hiphop的 2、不使用这玩意的 都是前端部署nginx&#xff0c;转发的后面php的 hhvm的配置文件 /etc/hhvm.hdf 目前结论&#xff1a;facebook的这玩意可能适用于facebook业务&#xff0c;对于我的业务来说反而拖后腿转载于:https://ww…

表达式求值(二叉树方法/C++语言描述)(二)

表达式二叉树节点的数据可能是运算数或运算符&#xff0c;可以使用一个联合体进行存储&#xff1b;同时还需要一个变量来指示存储的是运算数还是运算符&#xff0c;可以采用和栈方法求值中一样的枚举类型TokenType&#xff1a; 1 typedef enum2 {3 BEGIN,4 NUMBER,5 …

【RK3399Pro学习笔记】五、ROS与USB摄像头

目录usb_cam方法一安装一些要用的包测试usb摄像头方法二下载usb_cam源码编译测试usb摄像头uvc-camera平台&#xff1a;华硕 Thinker Edge R 瑞芯微 RK3399Pro 固件版本&#xff1a;Tinker_Edge_R-Debian-Stretch-V1.0.4-20200615 参考资料&#xff1a; ROS下usb_cam的安装 ——…

这是我们的第一篇博客----偕行软件

欢迎您光临我们的网站&#xff1a;链接 转载于:https://www.cnblogs.com/udsoft/p/3259366.html

MFC编程之创建Ribbon样式的应用程序框架

Ribbon界面就是微软从Office2007開始引入的一种为了使应用程序的功能更加易于发现和使用、降低了点击鼠标的次数的新型界面。从实际效果来看&#xff0c;不仅外观美丽&#xff0c;并且功能直观&#xff0c;用户操作简洁方便。 利用MFC向导创建Ribbon样式的单文档应用程序框架的…