温馨提示:读者若要彻底理解并会灵活使用DS18B20温度传感器,请详细阅读中文手册,并且对照代码注释充分分析代码。请不要觉得中文手册内容繁多!如能静心分析,定能深有体会,获益匪浅!

一、DS18B20中文手册(节选)

主函数操作顺序(执行序列)

功能指令

数码管温度计详解代码如下:

#include #include #define MAIN_Fosc 11059200UL//宏定义主时钟HZ/*==================================== 自定义类型名====================================*/typedef unsigned char INT8U;typedef unsigned char uchar;typedef unsigned int INT16U;typedef unsigned int uint;/*==================================== 硬件接口位声明====================================*/sbit DS= P2^2; //DS18B20单总线sbit DU= P2^6; //数码管段选sbit WE= P2^7; //数码管位选/*====================================共阴极数码管段选码====================================*/uchar code table[]={ //01 2 3 4 5 6 7 80x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F,//9 A B C D E F- .关显示0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x40, 0x80, 0x00 };/*====================================数码管位选码====================================*///第1位2位3位 4位 5位6位7位8位uchar code T_COM[] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f};//数码管位码/*====================================函数:void Delay_Ms(INT16U ms)参数:ms,毫秒延时形参描述:12T 51单片机自适应主时钟毫秒级延时函数====================================*/void Delay_Ms(INT16U ms){ INT16U i; do{i = MAIN_Fosc / 96000; while(--i); //96T per loop }while(--ms);}/*us延时函数,执行一次US--所需6.5us进入一次函数需要11.95us*/void Delay_us(uchar us){while(us--);}/*====================================函数:void Display(INT16U Value)参数:Value,显示值 取值0-65535描述:共阴极数码管显示函数可显示一个字节的数====================================*/void Display(INT16U Value)//注意由于需要显示的数大于一个字节所有形参需为int型{//------------------------------DU = 0;//关闭段选P0 = table[Value/100];//数码管显示百位DU = 1;//打开段选DU = 0;//关闭段选WE = 0;//关闭位选P0 = T_COM[0];//第一位数码管WE = 1;//打开位选WE = 0;//关闭位选Delay_Ms(3);//-------------------------------DU = 0;P0 = table[Value%100/10]|0x80; //显示十位DU = 1;DU = 0;WE = 0;P0 = T_COM[1];//第二位数码管WE = 1;WE = 0;Delay_Ms(3);//-------------------------------DU = 0;P0 = table[Value%10];//显示个位DU = 1;DU = 0;WE = 0;P0 = T_COM[2];//第三位数码管WE = 1;WE = 0;Delay_Ms(3);}/*单总线初始化时序*//*出始化时序里包含了复位DS18B20和接收DS18B20返回的存在信号*/bit ds_init() {bit i;DS = 1;_nop_();DS = 0;Delay_us(75); //拉低总线499.45us 挂接在总线上的18B20将会全部被复位DS = 1; //释放总线(检测到上升沿)Delay_us(4); //延时37.95us 等待18B20发回存在信号(存在脉冲)i = DS;Delay_us(20); //141.95usDS = 1;_nop_();return (i);//返回一个存在信号}/*写一个字节*/void write_byte(uchar dat){uchar i;for(i=0;i>= 1;}}uchar read_byte(){uchar i, j, dat;for(i=0;i<8;i++){DS = 0;_nop_();//产生读时序 1us,延时一个指令周期,空指令DS = 1;//释放总线_nop_(); //延时时间可以通过单步调试来计算j = DS;Delay_us(10);//76.95usDS = 1;_nop_();dat = (j<>1);}return (dat);}void main(){uint i;uchar L, M;while(1){ds_init();//初始化DS18B20write_byte(0xcc);//发送跳跃ROM指令write_byte(0x44);//发送温度转换指令ds_init();//初始化DS18B20write_byte(0xcc);//发送跳跃ROM指令(注意:当只有一只从机在总线上时,无论如何,//忽略ROM指令之后只能跟着发出一条暂存器指令【BEh】)write_byte(0xbe);//读取DS18B20暂存器值,读取将从字节0开始,一直进行下去,直到第9字节(字节8,CRC)读完L = read_byte();//总线控制器在发出温度转换指令之后进行读时序M = read_byte();//总线控制器在发出温度转换指令之后进行读时序i = M; //高速暂存器(共8位),详见中文手册i <<= 8; //将最低位移至高位i |= L;i = i * 0.0625 * 10 + 0.5;Display(i);}}

LCD1602温度显示

#include #include #include #define uchar unsigned char#define uint unsigned int sbit dula = P2^6;//数码管段选 sbit wela = P2^7;//数码管位选 sbit rw = P3^6; //LCD1602读/写选择端 sbit RS = P3^5;//LCD1602数据/命令选择端 sbit LCDEN = P3^4; //LCD1602使能端void delayUs(){_nop_();//空指令,延时一个指令周期} void delayMs(uint a){uint i, j;for(i = a; i > 0; i--)for(j = 100; j > 0; j--); }void writeComm(uchar comm) //写指令{RS = 0;P0 = comm;LCDEN = 1;delayUs();LCDEN = 0;delayMs(1);}//写数据:RS=1, RW=0;void writeData(uchar dat){RS = 1;P0 = dat;LCDEN = 1;delayUs();LCDEN = 0;delayMs(1); } void init() //LCD1602初始化函数 {rw = 0; //LCD1602读/写选择端dula = wela = 0;writeComm(0x38);//LCD1602显示设置writeComm(0x0c);//开显示 writeComm(0x06);//当读或写一个字符后地址指针加一,且光标加一writeComm(0x01);//清屏指令 }void writeString(uchar * str, uchar length)//LCD1602写字符串{ uchar i;for(i = 0; i 0) i--;//用于延时(严格按照时序来写)ds = 1; i = 4;while(i>0) i--; } void dsWait()//等待信号 {unsigned int i;while(ds);while(~ds);i = 4;while(i > 0) i--;}bit readBit()//读一个bit位,一节数据共8个bit位,故后面会连续读到8次来实现读一个字节的数据{unsigned int i;bit b;ds = 0;i++; ds = 1; i++; i++;b = ds;i = 8; while(i>0) i--;return b;//返回数据}unsigned char readByte() //读一个字节的数据{unsigned int i;unsigned char j, dat;dat = 0;for(i=0; i<8; i++)//每一次读一位,一节数据共8位,读8次{j = readBit();dat = (j <> 1);}return dat;}void writeByte(unsigned char dat)//写一节数据{unsigned int i;unsigned char j;bit b;for(j = 0; j >= 1; //右移一位 if(b) { ds = 0;i++; i++;//延时以产生时序 ds = 1; i = 8; while(i>0) i--; //延时以产生时序 }else{ds = 0;i = 8;while(i>0) i--;//延时以产生时序ds = 1;i++; i++;//延时以产生时序} }}void sendChangeCmd()//发送指令{dsInit();dsWait(); delayMs(1);writeByte(0xcc);//发送跳跃ROM指令(注意:当只有一只从机在总线上时,无论如何,//忽略ROM指令之后只能跟着发出一条暂存器指令【BEh】)writeByte(0x44);//发送温度转换指令}void sendReadCmd()//读操作{dsInit();dsWait();delayMs(1);writeByte(0xcc);//发送跳跃ROM指令 writeByte(0xbe);//发送温度转换指令 }int getTmpValue()//获取温度值{unsigned int tmpvalue;int value; float t;unsigned char low, high;sendReadCmd();low = readByte(); high = readByte(); tmpvalue = high;tmpvalue < 0 " />

最后希望我的分享对你有所帮助!敬请关注,持续更新!