DS18B20多ROM搜索并读取温度
来源:互联网 发布:知道qq如何 知乎 编辑:程序博客网 时间:2024/06/05 07:07
测试采用4个DS18B20挂在6m长得网线上面,使用的是5V供电,4.7K上拉,STM32驱动,
程序实现ROM搜索并分别读取每一个DS18B20的温度.
/************************************************************************************************************* * 文件名:ds18b20.c * 功能:STM32 DS18B20驱动 * 作者:cp1300@139.com * 创建时间:2012年9月17日22:45 * 最后修改时间:2012年9月17日 * 详细:需要延时函数支持 * 注意延时精度尽可能的高 * 读取的时候不要长时间的被中断,因为1wire对时间要求很严格*************************************************************************************************************/#include "system.h"#include "delay.h"#include "ds18b20.h"//PC1#define DS18B20_OUTPBout(15)#define DS18B20_INPBin(15)//DS18B20使用的是GPIOE0#define Set18b20IOout()GPIOx_Init(GPIOB,BIT15,OUT_PP,SPEED_10M);//设置DS18B20 IO为输出,#define Set18b20IOin()GPIOx_Init(GPIOB,BIT15,IN_IPU,0);//设置DS18B20 IO为上拉输入,#define Read18b20IO()((DS18B20_IN) ? 1 : 0)//读取DS18B20 IO#define Write18b20IO(x)(DS18B20_OUT = x)//写DS18B20 IO/**************************************************************************************************************************函数 :bool DS18B20_Reset(void)*功能 :复位DS18B20*参数 :无*返回 :TRUE:成功;FALSE:失败*依赖: 底层宏定义*作者 :cp1300@139.com*时间 :20120917*最后修改时间:20120917*说明 :无*************************************************************************************************************************/bool DS18B20_Reset(void){u8 i = 0;Set18b20IOout();//主机端口推挽输出模式Write18b20IO(1);Delay_US(1);Write18b20IO(0);//拉低总线480us~240usDelay_US(500); //>480US延时Write18b20IO(1);Delay_US(2);//复位完成Set18b20IOin();//主机端口浮空输入模式while(Read18b20IO())//等待低电平应答信号{i ++;Delay_US(1);if(i > 100){uart_printf("DS18B20 error!\r\n");return FALSE;//等待超时,初始化失败,返回FALSE;}}Delay_US(250);//跳过回复信号return TRUE;//检测到DS18B20,并且初始化成功}/**************************************************************************************************************************函数 :__inline u8 DS18B20_ReadBit(void)*功能 :读取DS18B20 1bit数据*参数 :无*返回 :数据,最低位有效*依赖: 底层宏定义*作者 :cp1300@139.com*时间 :20130402*最后修改时间:20130402*说明 :无*************************************************************************************************************************/__inline u8 DS18B20_ReadBit(void){u8 data = 0;Set18b20IOout();//主机端口推挽输出模式Write18b20IO(0);//拉低总线10-15usDelay_US(12);Write18b20IO(1);//释放总线Set18b20IOin();//主机端口浮空输入模式Delay_US(10);if(Read18b20IO())//读取数据,读取后大约延时40-45usdata = 0x01;Delay_US(40);return data;}/**************************************************************************************************************************函数 :u8 DS18B20_ReadData(void)*功能 :读取DS18B20数据*参数 :无*返回 :数据*依赖: 底层宏定义*作者 :cp1300@139.com*时间 :20120917*最后修改时间:20120917*说明 :无*************************************************************************************************************************/u8 DS18B20_ReadData(void){u8 i,data = 0;for(i = 0;i < 8;i ++){data >>= 1;if(DS18B20_ReadBit())data |= 0x80;}return data;}/**************************************************************************************************************************函数 :__inline void DS18B20_WriteBit(u8 bit)*功能 :向DS18B20写一位数据*参数 :数据,只发送最低位*返回 :无*依赖: 底层宏定义*作者 :cp1300@139.com*时间 :20130402*最后修改时间:20130402*说明 :无*************************************************************************************************************************/__inline void DS18B20_WriteBit(u8 bit){Set18b20IOout();//主机端口推挽输出模式 Write18b20IO(0);//拉低总线10-15usDelay_US(12);Write18b20IO(bit & 0x01);//写入数据位,保持20-45usDelay_US(30);Write18b20IO(1);//释放总线Delay_US(5);}/**************************************************************************************************************************函数 :void DS18B20_WriteData(u8 data)*功能 :向DS18B20写数据*参数 :数据*返回 :无*依赖: 底层宏定义*作者 :cp1300@139.com*时间 :20120917*最后修改时间:20120917*说明 :无*************************************************************************************************************************/void DS18B20_WriteData(u8 data){u8 i;for(i = 0;i < 8;i ++){DS18B20_WriteBit(data);data >>= 1;}}/**************************************************************************************************************************函数 :s16 DS18B20_ReadTemper(void)*功能 :读取DS18B20温度*参数 :无*返回 :温度值*依赖: 底层宏定义*作者 :cp1300@139.com*时间 :20120917*最后修改时间:20120917*说明 :温度值扩大了100倍,温度值是个有符号数.*************************************************************************************************************************/s16 DS18B20_ReadTemper(void){u8 th, tl;s16 data;if(DS18B20_Reset() == FALSE){return 0xffff;//返回错误}DS18B20_WriteData(0xcc);//跳过读序列号DS18B20_WriteData(0x44);//启动温度转换DS18B20_Reset();DS18B20_WriteData(0xcc);//跳过读序列号DS18B20_WriteData(0xbe);//读取温度tl = DS18B20_ReadData();//读取低八位th = DS18B20_ReadData(); //读取高八位data = th;data <<= 8;data |= tl;data *= 6.25;//温度值扩大100倍,精确到2位小数return data;}/**************************************************************************************************************************函数 :__inline u8 DS18B20_Read2Bit(void)*功能 :读取DS18B20 2bit数据*参数 :无*返回 :数据*依赖: 底层宏定义*作者 :cp1300@139.com*时间 :20120917*最后修改时间:20120917*说明 :无*************************************************************************************************************************/u8 DS18B20_Read2Bit(void){u8 i,data = 0;for(i = 0;i < 2;i ++){data <<= 1;if(DS18B20_ReadBit())data |= 1;}return data;}////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////以下代码为多DS18B20相关#define MAXNUM 4 //定义最多有4个 DS18B20/**************************************************************************************************************************函数 :u8 DS18B20_SearchROM(u8 (*pID)[8],u8 Num)*功能 :搜索DS18B20 ROM*参数 :pID:DS18B20 ID缓冲区指针Num:DS18B20数目,必须事先知道*返回 :搜索到的DS18B20数目*依赖: 底层宏定义*作者 :cp1300@139.com*时间 :2013-04-17*最后修改时间:2013-04-17*说明 :程序必须事先知道DS18B20数目,搜索的数目只会小于这个数目代码移植于互联网*************************************************************************************************************************/u8 DS18B20_SearchROM(u8 (*pID)[8],u8 Num){ unsigned char k,l,chongtuwei,m,n;unsigned char zhan[(MAXNUM)];unsigned char ss[64];u8 num = 0;l=0;do{DS18B20_Reset();DS18B20_WriteData(0xf0);for(m=0;m<8;m++){unsigned char s=0;for(n=0;n<8;n++){k=DS18B20_Read2Bit();//读两位数据k=k&0x03;s>>=1;if(k==0x01)//01读到的数据为0 写0 此位为0的器件响应{ DS18B20_WriteBit (0); ss[(m*8+n)]=0;}else if(k==0x02)//读到的数据为1 写1 此位为1的器件响应{s=s|0x80;DS18B20_WriteBit (1);ss[(m*8+n)]=1;}else if(k==0x00)//读到的数据为00 有冲突位 判断冲突位 {//如果冲突位大于栈顶写0 小于栈顶写以前数据 等于栈顶写1chongtuwei=m*8+n+1;if(chongtuwei>zhan[l]){DS18B20_WriteBit (0);ss[(m*8+n)]=0;zhan[++l]=chongtuwei;}else if(chongtuwei<zhan[l]){s=s|((ss[(m*8+n)]&0x01)<<7);DS18B20_WriteBit (ss[(m*8+n)]);}else if(chongtuwei==zhan[l]){s=s|0x80;DS18B20_WriteBit (1);ss[(m*8+n)]=1;l=l-1;}}else{return num;//搜索完成,//返回搜索到的个数}}pID[num][m]=s;}num=num+1;}while(zhan[l]!=0&&(num<MAXNUM));return num;//返回搜索到的个数}/**************************************************************************************************************************函数 :s16 DS18B20_ReadDesignateTemper(u8 pID[8])*功能 :读取指定ID的DS18B20温度*参数 :pID:DS18B20 ID,必须事先知道,如果不知道请启动ROM搜索*返回 :温度值*依赖: 底层宏定义*作者 :cp1300@139.com*时间 :2013-04-17*最后修改时间:2013-04-17*说明 :温度值扩大了100倍,温度值是个有符号数.*************************************************************************************************************************/s16 DS18B20_ReadDesignateTemper(u8 pID[8]){u8 th, tl;s16 data;if(DS18B20_Reset() == FALSE){return 0xffff;//返回错误}DS18B20_WriteData(0xcc);//跳过读序列号DS18B20_WriteData(0x44);//启动温度转换DS18B20_Reset();DS18B20_WriteData(0x55);//发送序列号匹配命令for(data = 0;data < 8;data ++)//发送8byte的序列号{ DS18B20_WriteData(pID[data]);}Delay_US(10);DS18B20_WriteData(0xbe);//读取温度tl = DS18B20_ReadData();//读取低八位th = DS18B20_ReadData(); //读取高八位data = th;data <<= 8;data |= tl;data *= 6.25;//温度值扩大100倍,精确到2位小数return data;}
#ifndef DS18B20_H_#define DS18B20_H_//DS18B20指令typedef enum {SEARCH_ROM=0xf0,//搜索ROM指令READ_ROM=0x33,//读取ROM指令MATH_ROM=0x55,//匹配ROM指令SKIP_ROM=0xcc,//忽略ROM指令ALARM_SEARCH=0xec,//报警索索指令CONVERT_T=0x44,//温度转换指令WRITE_SCRATCHPAD=0x4e,//写暂存器指令READ_SCRATCHPAD=0xbe,//读取暂存器指令COPY_SCRATCHPAD=0x48,//拷贝暂存器指令RECALL_E2=0xb8,//召回EEPROM指令READ_POWER_SUPPLY=0xb4,//读取电源模式指令} DS18B20_CMD;//DS18B20 ROM编码typedef struct{ u8DS18B20_CODE;//DS18B20单总线编码:0x19u8SN_1;//序列号第1字节u8SN_2;//序列号第2字节u8SN_3;//序列号第3字节u8SN_4;//序列号第4字节u8SN_5;//序列号第5字节u8SN_6;//序列号第6字节u8crc8;//CRC8校验码} DS18B20_ROM_CODE;#define DS18B20_Init()(DeviceClockEnable(DEV_GPIOB,ENABLE))//使能GPIOB时钟s16 DS18B20_ReadTemper(void);//读取DS18B20温度void DS18B20_WriteData(u8 data);u8 DS18B20_SearchROM(u8 (*pID)[8],u8 Num);//搜索ROM;s16 DS18B20_ReadDesignateTemper(u8 pID[8]);//读取指定ID的DS18B20温度#endif /*DS18B20_H_*/
#define DS18B20_NUM4u8 ID_Buff[DS18B20_NUM][8];int main(void){OS_CPU_SR cpu_sr;s16 temp;u8 buff[16];u8 i,j,num;SYSTEM_ClockInit(9);//初始化系统时钟72MHzJTAG_Set(SWD_ENABLE);//只开启SWD调试模式DevInit();uart_printf("start system ...\r\n\r\n");num = DS18B20_SearchROM(ID_Buff,DS18B20_NUM);uart_printf("总线上实际挂载DS18B20数量: %d\r\n",DS18B20_NUM);uart_printf("搜索到的DS18B20数量: %d\r\n",num);for(i = 0;i < num;i ++){uart_printf("\r\n DS18B20 No%d ID: ",i);for(j = 0;j < 8;j ++){uart_printf("%02X ",ID_Buff[i][j]);}}i = 0;while(1){LED1 = ~LED1;Delay_MS(1000);temp = DS18B20_ReadDesignateTemper(ID_Buff[i ++]);uart_printf("\r\n DS18B20 No%d Temp:%d ",i,temp);if(i == 4){ i = 0;uart_printf("\r\n");}}}
结果
- DS18B20多ROM搜索并读取温度
- 树莓派3 读取DS18B20 温度
- imx6ul linux读取DS18B20温度
- DS18B20显示温度并报警
- DS18B20温度读取笔记1-复位函数
- C51单总线操作,读取温度DS18B20
- STC15F2K60S2读取DS18B20温度串口显示
- DS18B20 1-WIRE ROM搜索算法详解
- 基于51单片机多路温度采集系统 采用读取ds18b20的序列号进行测量
- DS18B20 单总线多器件的ROM 搜索, ALARM 检测, CRC 校验 源码实现, 基于 STM32F103
- S3C6410 DS18B20温度传感器驱动(四) --- 读取温度的应用程序
- 树莓派通过C语言读取ds18b20的温度值
- 51单片机 DS18B20 (测温度 读取序列号 温度警报)
- DS18B20-Onewire Bus-单总线 单片机读取温度
- ATMEGA16读取DS18B20温度,1602显示,并用proteus仿真,成功。
- 【实例讲解】DS18B20 ROM码的搜索算法
- DS18B20的温度测量
- DS18B20温度模块.C
- Using ViewPager for Screen Slides 使用屏幕幻灯片ViewPager
- Android消息机制
- 学习mysql(5) function 创建
- twisted学习笔记
- c++高级---图解:C++中类的内存分布(总结)
- DS18B20多ROM搜索并读取温度
- 1064 三数求大值
- oracle 28000错误解决方法
- 拾取之选择模式
- μc/GUI学习笔记之一入门学习
- OGC之路(3)之 WFS初探
- Displaying Card Flip Animations 显示卡片翻转动画
- Solr集群Replication配置与实践,solrconfig.xml 介绍
- 编译动态库中设置路径出现的问题