/*************************************************** File name: 温度传感器DS18B20的使用 Main Function: 通过温度传感器DS18B20检测温度, 转换后上传至串口助手 Last modified Date: 2017-10-28 Created by: Zhang Zhihao ****************************************************/ #ifndef _DS18B20_H #define _DS18B20_H #include<STC15W4K.h> #define uchar unsigned char #define uint unsigned int sbit DQ = P3^7; //DS1820数据线IO口 bit nflag; //温度正负标志 sbit test = P5^5; /***************************************************** 延时函数:延时1us ******************************************************/ void delayus(uint i) { while(i--); } /***************************************************** 功能: 延时,最小单位为ms(晶振为11.0592 计算方法:一个for循环 = 8个指令周期 = 8*12个机器周期 = 8*12*1/11.0592 = 0.0086ms xms = 0.0086 * 110 = 0.946 ms ******************************************************/ void delayms(uint xms) { uint i,j; for(i=xms;i>0;i--) for(j=110;j>0;j--); } /***************************************************** DS18B20复位函数: 1 数据线拉低,延时480us 2 数据线拉高,延时480us ******************************************************/ void ds1820rst() { DQ = 1; //初始状态 delayus(4); DQ = 0; //拉低 delayus(480); //延时480us DQ = 1; //拉高 delayus(480); } /**************************************************** 18b20读数据:由低位到高位,重复八次,读一个字节 1 数据线拉低,延时4us 2 数据线拉高,延时10us 3 读数据线状态一位,处理数据,延时45us 4 重复步骤1-3 *****************************************************/ uchar ds1820rd() { uchar i = 0; uchar dat = 0; for(i=8;i>0;i--) { DQ = 0; //拉低数据线 delayus(4); dat>>=1; //空出第一位 DQ = 1; //拉高数据线 delayus(10); if(DQ) //若为高电平,则最高位置一 dat|=0x80; delayus(45);//延时45us } return(dat); } /************************************************** 18b20写数据:由低位到高位,重复八次,写一个字节 1 数据线拉低,延时15us 2 送一位数据到数据线,延时60us 3 数据线拉高 4 重复步骤1-3 **************************************************/ void ds1820wr(uchar wdata) { uchar i = 0; for (i=8; i>0; i--) { DQ = 0; //数据线拉低 delayus(15); DQ = wdata&0x01; //将数据最低位送入数据线 delayus(60); //延时10us DQ = 1; //数据线拉高 wdata>>=1; //字节右移一位 } } /***************************************************** 读温度并转换,根据RAM命令表写命令 0xcc: 不读取序列地址 0x44: 启动温度转换 0xbe: 读取温度 ******************************************************/ uint read_temp() { uchar TL,TH; //TL:低八位 TH:高八位 uchar wd; //最终温度的绝对值 ds1820rst(); //先复位 ds1820wr(0xcc); //不读取64位地址,因为总线上只有一个DB1820,单片工作 ds1820wr(0x44); //启动温度转换 delayus(125); ds1820rst(); ds1820wr(0xcc); //跳过读序列号 ds1820wr(0xbe); //读取温度 TL = ds1820rd(); //读低八位 TH = ds1820rd(); //读高八位 wd = TL/16+TH*16; // tvalue = TH; //tvalue为16位 // tvalue = (tvalue<<8)+TL; // if((tvalue&0xf800) == 0xf800) //判断负温度 // { // tvalue=~tvalue+1; //补码=反码+1 // nflag = 0; //置标志位为0 // } // else // nflag = 1; // // wd = tvalue*0.625; //计算温度值 return(wd); //返回温度值 } /***************************************************** 串口初始化函数: ******************************************************/ void init() { P1M0 = 0;P1M1 = 0; SCON = 0x40; T2L = 0xe0; T2H = 0xfe; AUXR = 0x14; AUXR |= 0x01; TI = 1; } /***************************************************** 串口通讯函数:发送两个字节,首字节为正负标志位, 第二个字节为温度值 ******************************************************/ void comm(uchar temper) { // while(!TI == 1); // { // TI = 0; // SBUF = nflag; // } while(!TI == 1); { TI = 0; SBUF = temper; } } #endif
#include "function.h" void main() { uchar temp; //临时变量存储温度 init(); //串口的初始化 test = 0; //蓝色的led,测试使用 while(1) { temp=read_temp(); //读取温度 delayms(500); //延时0.5s comm(temp); //发送至上位机 } }