单片机控制DS18B20的主程序
-
我只想知道单片机读取DS18B20的程序,不需要数码管或者液晶屏显示,该怎么编程啊?... 我只想知道单片机读取DS18B20的程序,不需要数码管或者液晶屏显示,该怎么编程啊? 展开
全部评论(1条)
-
- 累累的老巢 2016-06-14 00:00:00
- /***温度传感器DS18B20驱动——火柴天堂作品-20120622***/ /***源程序硬件环境:52单片机,12MHz晶振,P37接 DS18B20 数据引脚,非寄生电源(即外部电源接法)***/ /***DS18B20 测量温度范围:-55℃~+125℃***/ #define DS18B02_H #include"reg52.h" //包含52头文件 #include"DS18B20.h" //包含DS1302宏定义文件 sbit DS18B20_DQ=P3^7; //定义 DS18B20 数据口 #define DQ_High DS18B20_DQ=1 //拉高 数据口 #define DQ_Low DS18B20_DQ=0 //拉低 数据口 uchar code CRC_List[256]={//8540 CRC-8校验列表 //x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, xa, xb, xc, xd, xe, xf, 0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65, //0x 157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220, //1x 35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98, //2x 190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255, //3x 70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7, //4x 219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154, //5x 101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36, //6x 248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185, //7x 140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205, //8x 17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80, //9x 175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238, //ax 50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115, //bx 202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139, //cx 87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22, //dx 233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168, //ex 116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53};//fx void Delay(uint delay_time) //延时函数,非精确延时,Fosc=12MHz { while(delay_time--); } uchar CRC_18b20(uchar *buf_p,uchar leng) //CRC校验函数,*buf_p指向待检验数组,leng进行校验的个数,若含CRC码进行校验,结果应为0 { uchar i,crc_data=0; for(i=0;i<leng;i++) crc_data = CRC_List[crc_data^*buf_p++]; //查表校验 return crc_data; } void Reset_18b20() //DS18B20复位函数 { DQ_Low; //拉低 数据口 Delay(80); //==延时500us== DQ_High; //拉高 数据口,等待DS18B20回应 Delay(2); //==延时16~60us== if(DS18B20_DQ) Delay(3); //若DS18B20无回应,再等待一段时间 //if(DS18B20_DQ) return FALSE; //依然无回应,返回 复位失败(带布尔量返回时使用) while(!DS18B20_DQ); //若有回应,等待回应结束 //return TRUE; //返回 复位成功 } uchar Read_18b20() //DS18B20读函数 { uchar i,temp=0; for(i=0;i<8;i++) //读8个位 { DQ_Low; //拉低 数据口 ==延时1us== DQ_High; //拉高 数据口, //Delay(1); //==延时1us== if(DS18B20_DQ) temp|=1<<i; //若DS18B20回应高,则相应位置1 Delay(2); //==延时== } return temp; //返回 读取结果 } void Write_18b20(uchar comm) //DS18B20写函数 { uchar i; for(i=0;i<8;i++) //写8个位 { DQ_Low; //拉低 数据口 //Delay(1); //==延时5us== DS18B20_DQ=comm&0x01; //将数据Z低位赋于 数据口 //if(comm &(1<<i)) DQ_High; //执行周期过长,错过DS18B20读取时间 Delay(2); //==延时50us 以上== DQ_High; //拉高 数据口 comm >>= 1; //将下一位发送数据移到Z低位 //Delay(1); //恢复时间 } } //uchar ReadB20Power() //读DS18B20电源模式,返回:0 寄生电源模式, FF 外部电源模式(20130120增) //{ // Reset_18b20(); //复位DS18B20 // Write_18b20(SkipRom); //写"跳过ROM"指令,只能用于单器件 // Write_18b20(ReadPower); //写"读电源"指令 // return Read_18b20(); //读取1个字节,并返回 //} void GetB20SN(uchar *buf_p,uchar start_loca) //获取DS18B20系列号函数,*buf_p指向存储数组,start_loca为存储的起始位置 { uchar i=8; buf_p+=start_loca; //指向数组中的存储起始位置 Reset_18b20(); //复位DS18B20 Write_18b20(ReadRom); //写"读存储器"指令 while(i--) *buf_p++=Read_18b20(); //读8个字节系列号 } /******************************************************************************/ /***函数名称:ChangeTempValue(转换温度值) ***/ /***功能描述:将读取18B20所得的16位温度值(temp_buf指向的2个连续字节), ***/ /*** 转换成1Byte整数部分,和2Byte小数部分,存于save_buf指向的3个连续字节, ***/ /*** 其中第1个字节为整数部分,第2字节为0.01小数部分,第3字节为0.0001小数部分 ***/ /*** 返回值:0温度为正值,1温度为负值 ***/ /******************************************************************************/ bit ChangeTempValue(uchar *temp_buf,uchar reso_bit,uchar *save_buf,uchar save_start) //返回:0正温度,1负温度 { // 9bit(SSSS SSSS DDDD DDDD): S符号位:0正1负,D数据位,0.5℃单位(/2) //10bit(SSSS SSSD DDDD DDDD): S符号位:0正1负,D数据位,0.25℃单位(/4) //11bit(SSSS SSDD DDDD DDDD): S符号位:0正1负,D数据位,0.125℃单位(/8) //12bit(SSSS SDDD DDDD DDDD): S符号位:0正1负,D数据位,0.0625℃单位(/16) bit polar=0; //温度极性:0正温度,1负温度 uchar temp_int,reso_value; uint temp_dec,temp_A; reso_value=(reso_bit>>5)+9; //分辨率指令码转换数值:Reso_9bit/10bit/11bit/12bit→9/10/11/12 if(reso_value>12) reso_value=12; //默认 12bit分辨率精度 if(*(temp_buf+1)>>3)//正负值识别,温度值高5位为1则为 负值 { polar=1; //负极性 temp_A=(~*(temp_buf+1)<<8 | ~*temp_buf)+1; //取 补码(取反+1) } else temp_A=*(temp_buf+1)<<8 | *temp_buf; //正值,合成16位数据 temp_int=(uchar)(temp_A>>(reso_value-8)); //取整数部分,8bit(可以不加强制转换(uchar)) temp_dec=temp_A & (0x0f>>(12-reso_value)); //取小数部分 switch(reso_bit) //小数转换需进行精度选择 { case Reso_9bit: //9位精度,0.5℃ temp_dec*=5000; //小数扩大10000倍 break; case Reso_10bit: //10位精度,0.25℃ temp_dec*=2500; //小数扩大10000倍 break; case Reso_11bit: //11位精度,0.125℃ temp_dec*=1250; //小数扩大10000倍 break; case Reso_12bit: //12位精度,0.0625℃ default: //其他精度,按12位精度算 temp_dec*=625; //小数扩大10000倍 break; } save_buf+=save_start; //指向存储数组中的存储起始位置 *save_buf++=temp_int; //存温度值整数部分 *save_buf++=temp_dec/100; //存温度值小数点 十分位、百分位 *save_buf=temp_dec%100; //存温度值小数点 千分位、万分位 return polar; //返回温度极性:0正温度,1负温度 } bit GetTemp(uchar rom_mode,uchar *sn_p,uchar reso_bit,uchar *get_buf,uchar start_loca) //返回:0正温度,1负温度 { uchar i,read_buf[9]; //定义数组以存储DS18B20的9字节温度结果 uchar read_count=8; //读次数 Reset_18b20(); //复位 DS18B20 Write_18b20(rom_mode); //写入"ROM操作"模式代码,MatchRom,SkipRom if(rom_mode==MatchRom) for(i=0;i<8;i++) Write_18b20(*sn_p++); //若ROM操作 为匹配Rom,则写入8字节系列号 Write_18b20(TempChange); //写入"温度转换"指令 sn_p-=8; //指向"系列号起始地址" do //读暂存器 操作 { Reset_18b20(); //复位 DS18B20 Write_18b20(rom_mode); //写入"ROM操作"模式代码,MatchRom,SkipRom if(rom_mode==MatchRom) for(i=0;i<8;i++) Write_18b20(*sn_p++); //若ROM操作 为匹配Rom,则写入8字节系列号 Write_18b20(ReadScr); //写入"读暂存器"指令 for(i=0;i<9;i++) read_buf[i]=Read_18b20(); //读取暂存器9字节数据 sn_p-=8; //指向"系列号起始地址" }while(CRC_18b20(read_buf,9) && --read_count); //若校验失败,则重新"读暂存器",Z多读read_count次 return ChangeTempValue(read_buf,reso_bit,get_buf,start_loca); //进行温度转换,将温度结果存于get_buf指向的数组,并返回温度极性:0正温度,1负温度 } void Config_18b20(uchar rom_mode,uchar *sn_buf,uchar sn_start,uchar up_limit,uchar low_limit,uchar reso_bit) //DS18B20配置函数 { //形参:rom_mode操作ROM(SkipRom,MatchRom),up_limit上限,low_limit下限,reso_bit分辨率(Reso_9bit/10bit/11bit/12bit) uchar i,read_buf[9]; //定义数组以存储DS18B20的8字节系列号与1字节CRC校验码 uchar read_count=8; //读次数 sn_buf+=sn_start; //指向 系列号起始地址 do //写暂存器 操作 { Reset_18b20(); //复位 DS18B20 Write_18b20(rom_mode); //写入"ROM操作"模式代码,MatchRom,SkipRom if(rom_mode==MatchRom) for(i=0;i<8;i++) Write_18b20(*(sn_buf+i)); //若ROM操作 为匹配Rom,则写入8字节系列号 Write_18b20(WriteScr); //写暂存器 指令 Write_18b20(up_limit); //写入报警上限温度 Write_18b20(low_limit); //写入报警下限温度 Write_18b20(reso_bit); //写入分辨率 do //读暂存器 操作 { Reset_18b20(); //复位 DS18B20 Write_18b20(rom_mode); //写入"ROM操作"模式代码,MatchRom,SkipRom if(rom_mode==MatchRom) for(i=0;i<8;i++) Write_18b20(*(sn_buf+i)); //若ROM操作 为匹配Rom,则写入8字节系列号 Write_18b20(ReadScr); //写入"读暂存器"指令 for(i=0;i<9;i++) read_buf[i]=Read_18b20(); //读取暂存器9个字节数据 }while(CRC_18b20(read_buf,9) && --read_count); //若校验失败,则重新"读暂存器",Z多读read_count次 }while(read_buf[2]!=up_limit || read_buf[3]!=low_limit); //若读取结果与写入数据不同,则重新 写暂存器 Reset_18b20(); //复位 DS18B20 Write_18b20(rom_mode); //写入"ROM操作"模式代码,MatchRom,SkipRom if(rom_mode==MatchRom) for(i=0;i<8;i++) Write_18b20(*(sn_buf+i)); //若ROM操作 为匹配Rom,则写入8字节系列号 Write_18b20(CopyScr); //"复制暂存器"指令,将暂存器内容复制到DS18B20 EEPROM Reset_18b20(); //复位 DS18B20 Write_18b20(rom_mode); //写入"ROM操作"模式代码,MatchRom,SkipRom if(rom_mode==MatchRom) for(i=0;i<8;i++) Write_18b20(*(sn_buf+i)); //若ROM操作为匹配Rom,则写入8字节系列号 Write_18b20(RecallEE); //调EEPROM数据 指令,将 DS18B20 EEPROM内的数据写到暂存器 } /* uint GetTempData(uchar rom_mode,uchar *sn_p) //返回:16位 温度结果 { uchar i,read_buf[9]; //定义数组以存储DS18B20的9字节温度结果 uchar read_count=8; //读次数 Reset_18b20(); //复位 DS18B20 Write_18b20(rom_mode); //写入"ROM操作"模式代码,MatchRom,SkipRom if(rom_mode==MatchRom) for(i=0;i<8;i++) Write_18b20(*sn_p++); //若ROM操作 为匹配Rom,则写入8字节系列号 Write_18b20(TempChange); //写入"温度转换"指令 sn_p-=8; //指向"系列号起始地址" do //读暂存器 操作 { Reset_18b20(); //复位 DS18B20 Write_18b20(rom_mode); //写入"ROM操作"模式代码,MatchRom,SkipRom if(rom_mode==MatchRom) for(i=0;i<8;i++) Write_18b20(*sn_p++); //若ROM操作 为匹配Rom,则写入8字节系列号 Write_18b20(ReadScr); //写入"读暂存器"指令 for(i=0;i<9;i++) read_buf[i]=Read_18b20(); //读取暂存器9字节数据 sn_p-=8; //指向"系列号起始地址" }while(CRC_18b20(read_buf,9) && --read_count); //若校验失败,则重新"读暂存器",Z多读read_count次 return ((read_buf[1]<<8)|read_buf[0]); //进行温度转换,将温度结果存于get_buf指向的数组,并返回温度极性:0正温度,1负温度 }*/
-
赞(7)
回复(0)
热门问答
- 单片机控制DS18B20的主程序
- 我只想知道单片机读取DS18B20的程序,不需要数码管或者液晶屏显示,该怎么编程啊?... 我只想知道单片机读取DS18B20的程序,不需要数码管或者液晶屏显示,该怎么编程啊? 展开
2016-06-13 08:32:13
696
1
- DS18B20温度传感器如何与单片机相连接
- 单片机是at89s52单片机,引脚该如何相连顺便问下7段LED数码显示管该如何连到单片机上才能显示温度呢... 单片机是at89s52单片机,引脚该如何相连 顺便问下 7段LED数码显示管该如何连到单片机上 才能显示温度呢 展开
2010-06-15 11:30:55
459
4
- ds18b20 单片机测温 干扰疑惑 谢谢
- 工业环境下,上电运行一切正常,但过几小时后会有一定的概率(一百多台中会有随机出现十几台)出现复位不正常,即没有应答信号,或者读到的温度值不在PDF的正常温度范围内。而如果拔掉18B20传感器再插或者设备重新上电就恢复如常,但过段时间还是有可能会出现,... 工业环境下,上电运行一切正常,但过几小时后会有一定的概率(一百多台中会有随机出现十几台)出现复位不正常,即没有应答信号,或者读到的温度值不在PDF的正常温度范围内。而如果拔掉18B20传感器再插或者设备重新上电就恢复如常,但过段时间还是有可能会出现,查了很长时间查不出具体原因,哪位大师能指点一下,万分感谢。 展开
2012-11-07 02:48:37
405
2
- 基于AT89C52单片机和DS18B20温度传感器的实物图,急用!!!!
- 就是基于单片机温度传感器的控制设计,实物图,老师要,不会做,求帮助!!!!... 就是基于单片机温度传感器的控制设计,实物图,老师要,不会做,求帮助!!!! 展开
2016-05-02 04:57:33
258
1
- 单片机控制的信号发生器
- 我要做个系统,把传感器的数据传给单片机,然后单片机调节信号发生器的频率,这个的程序怎么写啊?哪里有类似的程序啊?... 我要做个系统,把传感器的数据传给单片机,然后单片机调节信号发生器的频率,这个的程序怎么写啊?哪里有类似的程序啊? 展开
2014-05-21 06:25:17
317
1
- 用单片机测温,ds18b20一直显示95。0
- 不知道是哪里出现了问题
2017-08-19 21:27:34
329
1
- 若采用多点测温,单片机如何识别ds18b20?
2013-12-17 20:42:10
420
2
- 51单片机 温度控制 1602显示 DS18B20读取温度
- 有偿程序要求:恒温控制... 有偿程序 要求:恒温控制 展开
2011-03-18 10:20:05
513
4
- DS18B20与单片机结合来测量温度。利用数字温度传感器DS18B20测量温度信号
- DS18B20与单片机结合来测量温度。利用数字温度传感器DS18B20测量温度信号,计算后在LED数码管上显示相应的温度值。其温度测量范围为−55℃~125℃,精确到0.5℃。数字温度计所测... DS18B20与单片机结合来测量温度。利用数字温度传感器DS18B20测量温度信号,计算后在LED数码管上显示相应的温度值。其温度测量范围为−55℃~125℃,精确到0.5℃。数字温度计所测量的温度采用数字显示,控制器使用单片机AT89C51,测温传感器使用DS18B20,用3位共阳极LED数码管以串口传送数据,实现温度显示。 展开
2018-01-05 01:15:27
688
2
- 如何用pic单片机写DS18B20数字温度传感器的程序
2016-11-07 11:36:37
452
1
- 单片机控制与PLC控制的区别?
2010-12-01 01:09:26
337
6
- 单片机控制步进电机调速
- 51单片机控制28BYJ-48步进电机我用的是中断方式使其旋转定时时间Z低只能设成1ms1ms时转速差不多4s/r吧定时时间调大会更慢怎么使转速调快点!定时时间过低或者过高电机不转会有震动怎... 51单片机控制28BYJ-48步进电机 我用的是中断方式使其旋转 定时时间Z低只能设成1ms 1ms时转速差不多4s/r吧 定时时间调大会更慢 怎么使转速调快点! 定时时间过低或者过高电机不转 会有震动 怎么回事 展开
2018-11-23 12:39:29
243
0
- 单片机PID控制问题
- 1.单片机在自动控制上有用到PID,比如一个恒温发热系统也可以用PID控制,但我用到现在单片机没用过PID,如果用单片机恒温可以使温度到达预定值就停止加热,低了就加热,用一个温度传感... 1.单片机在自动控制上有用到PID,比如一个恒温发热系统也可以用PID控制,但我用到现在单片机没用过PID,如果用单片机恒温可以使温度到达预定值就停止加热,低了就加热,用一个温度传感器反馈,这样算是一个自动控制吗?为什么有的用PID?是不是用PID要更精确? 2.我感觉很多单片机控制中可以用传感器反馈再用单片机逻辑判断,能简单的代替PID吗?? 哪位能简单讲下用单片机PID算法控制PWM,进行恒温系统的方法? 就是PWM参数是怎么用PID确认的?? 回答了再加分。 展开
2010-11-07 02:36:50
369
5
- 求用51单片机与DS18B20测温的C程序。完整的。
2016-05-21 11:08:36
413
1
- 单片机控制电磁阀的元器件的画法
- 那个类似线圈的L2是什么 以及二位二通电磁阀在peotel怎么画 谢谢
2017-05-25 06:43:42
471
1
- 51单片机如何控制超声波传感器 ?
2018-12-04 16:38:54
407
0
- 如何通过单片机控制光电传感器?
- Z近想做一台避障小车,里面的光电传感器需要用单片机来控制,请问用STC89C52 的单片机可以控制吗?怎么控制呢?谢谢
2013-07-25 06:41:57
466
2
- 如何使用单片机控制MQ135
2014-11-20 19:09:11
328
3
- 怎么通过单片机控制蠕动泵
2017-04-18 13:34:43
325
1
- 请问有人用AT89c52单片机用DS18B20测水温,超声波测水位的设计?
2014-10-27 08:14:01
621
2
1月突出贡献榜
推荐主页
最新话题
-
- #八一建军节——科技铸盾,仪器护航#
- 如何选择到合适的磷青铜绞线?磷青铜绞线的质量...如何选择到合适的磷青铜绞线?磷青铜绞线的质量解析和如何选择到合适的绞线?磷青铜绞线是一种特殊的铜合金导线,由铜、锡和磷等元素组成,具有很好的机械性能、电气性能和耐腐蚀性。磷青铜绞线基本定义与特性:磷青铜是铜与锡、磷的合金,质地坚硬,可制弹簧。典型成分为铜(90%)、锡(6-9%)及磷(0.03-0.6%)锡元素提升合金的强度和耐腐蚀性,磷则细化晶粒、增强耐磨性铸造性能。耐磨性:表面氧化层使其在特殊环境下耐腐蚀,使用寿命长导电性:保持铜很好导电性能的同时有化电子传输路径非铁磁性:不含铁元素,避免在强磁场环境中产生额外能量损耗弹性:受到外力作用时能迅速恢复原状
- 八一建军节 铁血铸军魂













参与评论
登录后参与评论