ds18b20c程序proteus仿真
ds18b20 C程序proteus仿真
DS18B20测温显示,proteus仿真。
Written by jinsongliang具体程序如下Main、c:#include<reg51、h>#include"lib51v3、c"#include"18b20、c"#include"segv3、c"void main (void){unsigned char disp[5]={10,0,0,14,2};signed char temp=0;while(1){/*1、读取温度值*/temp=Get_Temputer();//2、显示前处理*/if(temp<0){disp[0]=13;temp=-temp;disp[1]=temp/10;disp[2]=temp%10;}else{disp[0]=temp/100;disp[1]=temp/10-disp[0]*10;disp[2]=temp%10;if(!disp[0]) //百位数不为0则显示,若要显示0,可将其注释掉disp[0]=10;}//3、显示*/Seg_Display(disp);}}Lib51v3、cvoid Delay_Nus (unsigned char n) {while(n--);//for (;n>0;n--);}18b20、c:/****************************************************************** 时序很重要,移植时注意延时函数******************************************************************/#define B20_PORT P1 //此处可以设置I/O口#define B20_CHANNEL 0#define R_B20_CHANNEL() B20_PORT&(1<<B20_CHANNEL)#define W_B20_CHANNEL_1() B20_PORT|=(1<<B20_CHANNEL)#define W_B20_CHANNEL_0() B20_PORT&=~(1<<B20_CHANNEL)#define SKIP_ROM 0xCC#define TEMPUTER_CONVERT 0x44#define READ_ROM 0xBE//one/*初始化函数,失败会返回1,初始化过程见注释若单片机读到了数据线上的低电平“0”后,还要做延时,其延时的时间从单片机发出的高电平算起最少要480微秒。
DS18B20原理及应用实例(源程序+原理图+Proteus仿真)
2、DS18B20 结构:如右图所示,DS18B20 有三只引脚,
VCC、DQ 和 GND。DQ 为数字信号输入/输出端(DQ 一般接控制器(单片机)的一个 I/O 口上,由于单总线为开漏所以需要外接一个 4.7K 的上拉电阻) ;GND 为电源地;VDD 为外 接供电电源输入端 (在寄生电源接线方式时接地) 。 DS18B20 内部结构主要由四部分组成: 64 位光刻 ROM、温度传感器、非挥发的温度报警触发器 TH 和 TL、配置寄存器。 光刻ROM中的64位序列号是出厂前被光刻好的,它可以看作是该DS18B20的地址序列 码。64位光刻ROM的排列是:开始8位是产品类型标号,接着的48位是该DS18B20自身的序 列号,最后8位是前面56位的CRC校验码(循环冗余校验码)。光刻ROM的作用是使每一个 DS18B20都各不相同,这样就可以实现一根总线上挂接多个DS18B20的目的。 温度传感器可完成对温度的测量,以12位转化为例,用16位符号扩展的二进制补码读 数形式提供。 RAM数据暂存器,数据在掉电后丢失,DS18B20共9个字节RAM,每个字节为8位。如 下图所示, 当温度转换命令发布后, 经转换所得的温度值以二字节补码形式存放在暂存器的 第0和第1个字节。单片机可通过单线接口读到该数据,读取时低位在前,高位在后,第2、3 字节是用户EEPROM(常用于温度报警值储存)的镜像,用户用来设置最高报警和最低报 警值,在上电复位时其值将被刷新。第4个字节则是用户第3个EEPROM的镜像,用来配置 9~12位的转换精度(即分辨率) 。第5、6、7个字节为计算机自身使用。第8个字节为前8个字 节的CRC码。EEPROM 非易失性记忆体,用于存放长期需要保存的数据,上下限温度报警 值和校验数据,DS18B20共3位EEPROM,并在RAM都存在镜像,以方便用户操作。
多个DS18B20测温的proteus仿真电路及C语言程序设计
多个DS18B20测温的proteus仿真电路及C语言程序设计proteus仿真电路元器件组成C语言程序:#include<reg51.h>sbit DQ=P1^2;sbit DQ1=P1^1;sbit DQ2=P1^0;sbit DQ3=P1^3;#define uchar unsigned char#define uint unsigned intuchar temp_value,temp_value1,temp_value2;uchar code table[]={0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F,0X40};void delay_18B20(uint i){while(i--);}void Init_DS18B20(void){uchar x=0;DQ = 1; //DQ复位delay_18B20(8); //稍做延时DQ = 0; //单片机将DQ拉低delay_18B20(60); //精确延时大于480usDQ = 1; //拉高总线delay_18B20(14);x=DQ; //稍做延时后如果x=0则初始化成功x=1则初始化失败delay_18B20(20);}uchar ReadOneChar(void){uchar i=0;uchar dat = 0;for (i=8;i>0;i--){DQ = 0; // 给脉冲信号dat>>=1;DQ = 1; // 给脉冲信号if(DQ)dat|=0x80;delay_18B20(4);}return(dat);}void WriteOneChar(uchar dat){uchar i=0;for (i=8; i>0; i--){DQ = 0;DQ = dat&0x01;delay_18B20(5);DQ = 1;dat>>=1;}}void Init_DS18B201(void){uchar x=0;DQ1 = 1; //DQ复位delay_18B20(8); //稍做延时DQ1 = 0; //单片机将DQ拉低delay_18B20(80); //精确延时大于480usDQ1 = 1; //拉高总线delay_18B20(14);x=DQ1; //稍做延时后如果x=0则初始化成功x=1则初始化失败delay_18B20(20);}uchar ReadOneChar1(void){uchar i=0;uchar dat = 0;for (i=8;i>0;i--){DQ1 = 0; // 给脉冲信号dat>>=1;DQ1 = 1; // 给脉冲信号if(DQ1)dat|=0x80;delay_18B20(4);}return(dat);}void WriteOneChar1(uchar dat){uchar i=0;for (i=8; i>0; i--){DQ1 = 0;DQ1 = dat&0x01;delay_18B20(5);DQ1 = 1;dat>>=1;}}void Init_DS18B202(void){uchar x=0;DQ2 = 1; //DQ复位delay_18B20(8); //稍做延时DQ2 = 0; //单片机将DQ拉低delay_18B20(80); //精确延时大于480usDQ2 = 1; //拉高总线delay_18B20(14);//x=DQ1; //稍做延时后如果x=0则初始化成功x=1则初始化失败delay_18B20(20);}uchar ReadOneChar2(void){uchar i=0;uchar dat = 0;for (i=8;i>0;i--){DQ2 = 0; // 给脉冲信号dat>>=1;DQ2 = 1; // 给脉冲信号if(DQ2)dat|=0x80;delay_18B20(4);}return(dat);}void WriteOneChar2(uchar dat){uchar i=0;for (i=8; i>0; i--){DQ2 = 0;DQ2 = dat&0x01;delay_18B20(5);DQ2 = 1;dat>>=1;}}void ReadTemp(void){uchar a=0;uchar b=0;uchar t=0;float tt=0;Init_DS18B20();WriteOneChar(0xCC); // 跳过读序号列号的操作WriteOneChar(0x44); // 启动温度转换delay_18B20(100); // this message is wery importantInit_DS18B20();WriteOneChar(0xCC); //跳过读序号列号的操作WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器)前两个就是温度delay_18B20(100);a=ReadOneChar(); //读取温度值低位b=ReadOneChar(); //读取温度值高位temp_value=b<<4;temp_value+=(a&0xf0)>>4;}void ReadTemp1(void){uchar c=0;uchar d=0;uchar t=0;Init_DS18B201();WriteOneChar1(0xCC); // 跳过读序号列号的操作WriteOneChar1(0x44); // 启动温度转换delay_18B20(100); // this message is wery importantInit_DS18B201();WriteOneChar1(0xCC); //跳过读序号列号的操作WriteOneChar1(0xBE); //读取温度寄存器等(共可读9个寄存器)前两个就是温度delay_18B20(100);c=ReadOneChar1(); //读取温度值低位d=ReadOneChar1(); //读取温度值高位temp_value1=d<<4;temp_value1+=(c&0xf0)>>4;}void ReadTemp2(void){uchar e=0;uchar f=0;uchar t=0;Init_DS18B202();WriteOneChar2(0xCC); // 跳过读序号列号的操作WriteOneChar2(0x44); // 启动温度转换delay_18B20(100); // this message is wery importantInit_DS18B202();WriteOneChar2(0xCC); //跳过读序号列号的操作WriteOneChar2(0xBE); //读取温度寄存器等(共可读9个寄存器)前两个就是温度delay_18B20(100);e=ReadOneChar2(); //读取温度值低位f=ReadOneChar2(); //读取温度值高位temp_value2=f<<4;temp_value2+=(e&0xf0)>>4;}//显示延时函数void delay(unsigned int z){unsigned int x;unsigned char y;for(x=z;x>0;x--)for(y=200;y>0;y--);}void display (uchar num0,uchar num1,uchar num2,uchar num3,uchar num4,uchar num5) { P2=0XFE;P0=0x00;P0=table[num1];delay(6);P2=0XFD;P0=0x00;P0=table[num0];delay(6);P2=0XFB;P0=0x00;P0=table[10];delay(6);P2=0XF7;P0=0x00;P0=table[num3];delay(6);P2=0XEF;P0=0x00;P0=table[num2];delay(6);P2=0XDF;P0=0x00;P0=table[10];delay(6);P2=0XBF;P0=0x00;P0=table[num5];delay(6);P2=0X7F;P0=0x00;P0=table[num4];delay(6);}main(){ unsigned int i=0;uchar a ,b,c,d,e,f ;while(1){ReadTemp();ReadTemp1();ReadTemp2();b=temp_value/10; //十位a=temp_value%10; //个位d=temp_value1/10; //十位c=temp_value1%10; //个位f=temp_value2/10; //十位e=temp_value2%10; //个位display(b,a,d,c,f,e);}}。
protues DS18B20仿真
程序代码#include <reg52.h>#include <intrins.h>#define uint unsigned int#define uchar unsigned char#define nops(); {_nop_();_nop_();_nop_();_nop_();} sbit DQ=P3^0;uchar code led []={ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};uchar code leddg []={ 0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,0xf7,0xfc} ;void display (double x);void delayms(uint z);void delay1(uint z);uint ds18b20();uchar reset18b20();void main (){double a;while(1){a=ds18b20();display(a);}}/////////////////////////////////////////////////////void delayms(uint z) //延时函数{uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}///////////////////////////////void delay1(uint z){while(--z);}/////////////////////////////////////////////////void display (double x) //显示函数{ uint a,b,d,e;int c;double g,h;if (x<=128){ c=(int)x;//45 10.12a=c/100; //提取个位,百位b=c%100/10;d=c%100%10;g=x-c;//0.119999 有误差/* if((((int)(g*100)+1)-g*100)<=0.0001 ) //判断下消除误差g=g+0.01;d=(int)(g*10);h=10*g-d;e=(int)(h*10);*/e=(int)(10*g);P2=0xfe;P0=led[a];delayms(10);P2=0xfd;P0=led[b];delayms(10);P2=0xfb;P0=leddg[d];delayms(10);P2=0xf7;P0=led[e];delayms(10);}else{c=(int)(256-x);b=c/10;d=c%10;e=0;P2=0xfe;P0=0x40;delayms(10);P2=0xfd;P0=led[b];delayms(10);P2=0xfb;P0=leddg[d];delayms(10);P2=0xf7;P0=led[e];delayms(10);}}////////////////////////////////////////////////////uchar reset18b20() //复位18B20{uchar a;DQ=1;_nop_();_nop_();DQ=0;delay1(80);DQ=1;nops();a=DQ;delay1(20);return a ;}////////////////////////////////////////void write (uchar dat) //向18B20里写{uchar i;DQ=1;_nop_();for(i=0;i<8;i++){DQ=0;DQ=dat&0x01;delay1(51);DQ=1;dat>>=1;}}/////////////////////////////////////uchar read() //读取18b20{uchar i,dat=0;DQ=1;_nop_();for(i=0;i<8;i++){DQ=0;nops();dat>>=1;DQ=1;nops();if(DQ){dat|=0x80;}delay1(30);DQ=1;}return dat;}/////////////////////////////////////////////uint ds18b20() //启动18B20温度传感器{uint a,b;reset18b20();write(0xcc); //跳过ID地址write(0x44); //启动温度转换reset18b20();write(0xcc);write(0xbe); //读取温度a=read();b=read();b=b&0x0f;b<<=4;b+=(a&0xf0)>>4 ; //取出A的低4位在和B相加刚好B中存的温度的高低值return b;}。
Proteus仿真的DS18B20测温设计
目录前言 (1)正文 (1)2.1 设计目的和意义 (1)2.1.1 设计目的 (1)2.1.2 设计意义 (1)2.2 设计方法和步骤 (1)3.1 单片机最小系统设计 (2)3.1.1 电源电路 (2)3.1.2 振荡电路与复位电路 (2)3.2 DS18B20与单片机的接口电路 (3)3.3 PROTEUS仿真电路图 (3)4.1 程序流程 (3)4.1.1 主程序流程图 (4)4.1.2 各子程序流程图 (4)4.2 汇编语言程序源代码 (8)5.1 DS18B20简单介绍 (10)5.1.1 DS18B20 的性能特点如下: (11)5.1.2 DS18B20使用中的注意事项 (11)5.1.3 DS18B20内部结构 (12)5.2 DS18B20测温原理 (14)总结 (15)参考文献 (16)前言随着现代信息技术的飞速发展和传统工业改造的逐步实现,能够独立工作的温度检测和显示系统应用于诸多领域。
传统的温度检测以热敏电阻为温度敏感元件。
热敏电阻的成本低,但需后续信号处理电路,而且可靠性相对较差,测温准确度低,检测系统也有一定的误差。
这里设计的数字温度计具有读数方便,测温范围广,测温精确,数字显示,适用范围宽等特点。
本设计选用AT89C51型单片机作为主控制器件,DS18B20作为测温传感器,通过LCD1602实现温度显示。
通过DS18B20直接读取被测温度值,进行数据转换,该器件的物理化学性能稳定,线性度较好,在0℃~100℃最大线性偏差小于0.01℃。
该器件可直接向单片机传输数字信号,便于单片机处理及控制。
另外,该温度计还能直接采用测温器件测量温度,从而简化数据传输与处理过程。
正文2.1 设计目的和意义2.1.1 设计目的作为理工科的学生应该在学习与动手实践中提高自己的专业技能知识,通过课程设计使我进一步熟悉了单片机的内部结构和工作原理,掌握了单片机应用系统设计的基本方法和步骤;通过利用MCS-51单片机,理解单片机在自动化装置中的作用以及掌握单片机的编程调试方法;通过设计一个简单的实际应用输入控制及显示系统,掌握protues和Wave以及各种仿真软件的使用。
温度传感器DS18B20在Proteus中的仿真
际需 要 通 过 软 件 设 置 选 择 9 1 位 分 辨 率 ; 户 设 置 的 报 ~ 2 用
警 温 度 存 储 在 芯 片 内 部 EE ROM 中 , 掉 电 保 持 ; 个 P 可 每
且 数 据 的传 输 时 双 向 的 , 有 线 路 简 单 、 件 开 销 少 、 本 具 硬 成 低 、 于 总线 扩 展 和 维 护 等 优 点 。 便 ] D 1B 0是典 型 的 单 总 线 数 字 式 温 度 传 感 器 , 作 电 S8 2 工
压 为 3 5V, 量 温 度 范 围 为 一 5 ~ + 1 5℃ , 根 据 实 ~ 测 5 2 可
Ch n F n e a g,J a g He in
( z o i e st Fu h u 3 0 0 Fu h u Un v r i y, z o 5 1 8,Ch n ) ia
Ab ta t s r c :The pa e n r du e he wor ng p i il c m u c ton p o oc d us ge of1 wie diia t r o e e p r it o c s t ki rncp e, om nia i r t olan a - r g t l he m m t r DS1 8B20 .T h e s fw a e pr e soft m p r t e r a n a he Pr t us sm u a in a egie o t r oc s e e a ur e dig nd t o e i l to r v n. Co p rs t e n sm ulto e u t nd e e i e a m a ion be w e i a i n r s lsa xp rm nt l r s lsa e s w n. e u t r ho
基于DS18B20的数字温度监控系统的Proteus设计
基于DS18B20的数字温度监控系统的Proteus设计学院:电子信息与电气工程学院设计任务书题目基于DS18B20的数字温度监控系统Proteus设计一、设计的目的1.将理论知识运用于实践当中,掌握模拟电路设计的基本方法、基本步骤以及基本要求。
在实践中了解电子器件的功能与作用。
2.学会信号发生器的设计方法,完成要求的性能和指标。
3.锻炼、提高在电子设计中发现问题、分析问题、解决问题的能力。
二、设计的内容及要求1. 测量温度值精度为±1℃;2. 系统允许的误差范围为1℃以内;3. 系统可由用户预设温度值,测温范围为-55℃~+125℃;4. 通过DS18B20传感器和系统连接,能实时准确检测到现场温度;5. 把现场实时检测到的温度通过LCD1602液晶显示出来;6. 报警温度设定和报警:根据需要可以设置报警温度,并且当达到报警温度时会发出报警提示;三、指导教师评语四、成绩指导教师(签章)年月日目录摘要..................................................... - 3 - 1.绪论................................................... - 4 -1.1 课题研究背景....................................... - 4 -1.2 课题内容及要求..................................... - 5 -2.温度测控方案论证........................................ - 6 -2.1 热敏电阻测温...................................... - 6 -2.2 数字温度传感器测温................................ - 6 -3.系统方案概述............................................ - 7 -4.硬件部分................................................ - 8 -4.1 单片机最小系统设计................................ - 8 -4.1.1 AT89C52单片机简介........................... - 8 -4.1.2 晶振电路.................................... - 13 -4.1.3 复位电路.................................... - 14 -4.1.4 排阻电路.................................... - 14 -4.2 DS18B20温度传感器................................ - 15 -4.2.1 DS18B20简介................................ - 15 -4.2.2 DS18B20内部结构............................ - 17 -4.2.3 DS18B20电路................................ - 21 -4.3 LCD1602液晶显示电路.............................. - 22 -4.4按键模块.......................................... - 24 -4.5报警模块.......................................... - 26 -4.5.1蜂鸣器报警模块.............................. - 26 -4.5.2 LED报警模块................................ - 27 -5.软件部分............................................... - 28 -5.1 软件开发平台..................................... - 28 -5.2 主程序设计....................................... - 28 -5.3 DS18B20程序设计.................................. - 29 -5.3.1 初始化...................................... - 29 -5.3.2 ROM操作命令................................ - 30 -5.3.3 数据处理.................................... - 30 -5.3.4 程序流程图.................................. - 32 -5.4 LCD1602程序流程图设计............................ - 32 -5.5 报警模块程序设计................................. - 33 -6.仿真与测试............................................. - 34 -6.1 仿真设计平台..................................... - 34 -6.2 仿真结果分析..................................... - 35 - 结论.................................................... - 36 - 致谢.................................................... - 37 -摘要在日常生活及工业生产过程中,经常要用到温度的检测及控制,温度是生产过程和科学实验中普遍而且重要的物理参数之一。
protues仿真DS18B20温度显示
电路图仿真图温控范围25到35度之间源程序#include<reg51.h> //包含单片机寄存器的头文件#include<intrins.h> //包含_nop_()函数定义的头文件#include <absacc.h>#include <math.h>sbit DQ=P1^1;sbit jdq=P1^0;sbit dot=P2^7;unsigned char codexiaoshu[]={0xc0,0xc0,0xf9,0xf9,0xa4,0xb0,0xb0,0x99,0x92,0x92,0x82,0xf8,0xf8,0x8 0,0x80,0x90};char duan[4]={0,0,0,0};unsigned char code weikong[]={0x01,0x02,0x04,0x08,0x10,0x20}; unsigned char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};int bai,shi,ge,flag=0,i;unsigned char temp;unsigned char TL; //储存暂存器的温度低位unsigned char TH; //储存暂存器的温度高位unsigned char TN; //储存温度的整数部分unsigned int TD; //储存温度的小数部分void delay1ms(){unsigned char i,j;for(i=0;i<10;i++)for(j=0;j<33;j++);}void delaynms(int n){unsigned char i;for(i=0;i<n;i++)delay1ms();}unsigned char time_DS18B20; //设置全局变量,专门用于严格延时bit Init_DS18B20(void){bit flag_DS18B20; //储存DS18B20是否存在的标志,flag=0,表示存在;flag=1,表示不存在DQ = 1; //先将数据线拉高for(time_DS18B20=0;time_DS18B20<2;time_DS18B20++) //略微延时约6微秒;DQ = 0; //再将数据线从高拉低,要求保持480~960usfor(time_DS18B20=0;time_DS18B20<200;time_DS18B20++) //略微延时约600微秒; //以向DS18B20发出一持续480~960us的低电平复位脉冲DQ = 1; //释放数据线(将数据线拉高)for(time_DS18B20=0;time_DS18B20<10;time_DS18B20++); //延时约30us(释放总线后需等待15~60us让DS18B20输出存在脉冲)flag_DS18B20=DQ; //让单片机检测是否输出了存在脉冲(DQ=0表示存在)for(time_DS18B20=0;time_DS18B20<200;time_DS18B20++) //延时足够长时间,等待存在脉冲输出完毕;return (flag_DS18B20); //返回检测成功标志}unsigned char ReadOneChar( ){unsigned char i=0;unsigned char dat; //储存读出的一个字节数据for (i=0;i<8;i++){DQ =1; // 先将数据线拉高_nop_(); //等待一个机器周期DQ = 0; //单片机从DS18B20读书据时,将数据线从高拉低即启动读时序dat>>=1;_nop_(); //等待一个机器周期DQ = 1; //将数据线"人为"拉高,为单片机检测DS18B20的输出电平作准备for(time_DS18B20=0;time_DS18B20<3;time_DS18B20++); //延时约6us,使主机在15us内采样if(DQ==1)dat|=0x80; //如果读到的数据是1,则将1存入datelsedat|=0x00;//如果读到的数据是0,则将0存入dat//将单片机检测到的电平信号DQ存入r[i]for(time_DS18B20=0;time_DS18B20<8;time_DS18B20++); //延时3us,两个读时序之间必须有大于1us的恢复期 }return(dat); //返回读出的十进制数据}WriteOneChar(unsigned char dat){unsigned char i=0;for (i=0; i<8; i++){DQ =1; // 先将数据线拉高_nop_(); //等待一个机器周期DQ=0; //将数据线从高拉低时即启动写时序DQ=dat&0x01; //利用与运算取出要写的某位二进制数据,//并将其送到数据线上等待DS18B20采样for(time_DS18B20=0;time_DS18B20<10;time_DS18B20++);//延时约30us,DS18B20在拉低后的约15~60us期间从数据线上采样DQ=1; //释放数据线for(time_DS18B20=0;time_DS18B20<1;time_DS18B20++);//延时3us,两个写时序间至少需要1us的恢复期dat>>=1; //将dat中的各二进制位数据右移1位}for(time_DS18B20=0;time_DS18B20<4;time_DS18B20++); //稍作延时,给硬件一点反应时间}void ReadyReadTemp(void){Init_DS18B20(); //将DS18B20初始化WriteOneChar(0xCC); // 跳过读序号列号的操作WriteOneChar(0x44); // 启动温度转换for(time_DS18B20=0;time_DS18B20<100;time_DS18B20++); //温度转换需要一点时间Init_DS18B20(); //将DS18B20初始化WriteOneChar(0xCC); //跳过读序号列号的操作WriteOneChar(0xBE); //读取温度寄存器,前两个分别是温度的低位和高位TL=ReadOneChar(); //先读的是温度值低位TH=ReadOneChar(); //接着读的是温度值高位}void display(){if(TH>=8){TH=~TH; //当温度为负数时求负数的补码TL=~TL;TL=TL+1;flag=1; //当温度为负值时标志置1if(TL==0)TH+=1;}duan[0]=TL&0X0f; //保存小数部分的值temp=(((TH<<4)&0x70)|(TL>>4)); //将高8位的低3位和低8位的高4位合并构成温度的整数部分duan[3]=temp/100; //取百位duan[2]=temp%100/10; //取十位duan[1]=temp%10; //取个位P2=xiaoshu[duan[0]];//显示小数部分P3=0x01;delaynms(3);P3=0;if(duan[3]) //显示百位{P3=weikong[3];P2=table[duan[3]];delaynms(3);P3=0;}if(duan[3]){//显示十位P3=weikong[2];P2=table[duan[2]];delaynms(3);P3=0;}else{if(duan[2]) //显示十位{P3=weikong[2];P2=table[duan[2]];delaynms(3);P3=0;}}P3=weikong[1]; //显示个位P2=table[duan[1]];dot=0; //显示小数点delaynms(3);P3=0;if(flag) //当温度为负数时显示符号位{P2=0xbf;if(!duan[3]){P3=0x08;if(!duan[2])P3=0x04;}else{P3=0x10;}delaynms(1);P3=0;flag=0;}delaynms(25); //延时一段时间}void main(void){while(1) //不断检测并显示温度{ReadyReadTemp(); //读温度准备display();if((temp<25)||(temp>35)) //如果温度超出范围继电器工作控制温度{jdq=1;}else{jdq=0;}}}。
单片机 ds18b20温度测量 proteus仿真
#include<reg51.h>sbit DQ=P3^0;unsigned int temp;unsigned char dis[4]={0,0,0,0};unsigned charled[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0xff,0xbf};//分别为0-9,不显示,负号Unsigned charled1[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//带小数点显示void delay(unsigned int i) //如果i是unsigend char类型,则会出现错误结果{while(i--);}void Init(void)//初始化{//unsigned char flag=0;DQ = 0; //单片机将DQ拉低delay(100); //精确延时大于480us小于960usDQ = 1; //拉高总线delay(30);//flag=DQ; //稍做延时后如果flag=0则初始化成功flag=1则初始化失败//delay(20);}unsigned char Read(void)//读字节{unsigned char i=0;unsigned char dat = 0;for (i=8;i>0;i--){DQ = 0; // 给脉冲信号dat>>=1;DQ = 1; // 给脉冲信号if(DQ)dat|=0x80;delay(5);}return(dat);}void Write(unsigned char dat)//写字节{unsigned char i=0;for (i=8; i>0; i--){DQ = 0;DQ = dat&0x01;delay(5);DQ = 1;dat>>=1;}}void Display(unsigned int temp) //显示程序{if(temp<=0x0800){ temp>>=4; //右移4位,相当于乘0.0625,将温度化为十进制temp*=10; //扩大10倍,显示一位小数dis[0]=temp/1000; //千位dis[1]=temp%1000/100; //百位dis[2]=temp%1000%100/10; //十位dis[3]=temp%1000%100%10; //个位}else{temp=~temp;temp+=1;temp>>=4;dis[0]=0x0c; //负数dis[1]=temp%100/10; //百位dis[2]=temp%100%10; //十位dis[3]=0; //个位}P2=0x01; //先片选,在段选,反过来就不能正常显示P0=led[dis[0]];delay(200);delay(200);P2=0x02;P0=led[dis[1]];delay(200);delay(200);P2=0x04;P0=led1[dis[2]];delay(200);delay(200);P2=0x08;P0=led[dis[3]];delay(200);delay(200);}main(){unsigned char tl=0,th=0;while(1){Init();Write(0xCC); // 跳过读序号列号的操作Write(0x44); // 启动温度转换delay(100);Init();Write(0xCC); //跳过读序号列号的操作Write(0xBE); //读取温度寄存器等delay(100);tl=Read(); //读取温度值低位th=Read(); //读取温度值高位temp=th<<8;temp|=tl;Display(temp);}}。
DS18B20原理及应用实例(源程序+原理图+Proteus仿真)
2 / 13
2012 年 8 月 13 日星期一
举例如下:
4ቤተ መጻሕፍቲ ባይዱDS18B20 的初始化:
根据 DS18B20 的通讯协议,主机(单片机)控制 DS18B20 完成温度转换必须经过三个 步骤:每一次读写之前都要对 DS18B20 进行复位操作,复位成功后发送一条 ROM 指令, 最后发送 RAM 指令,这样才能对 DS18B20 进行预定的操作。复位要求主 CPU 将数据线下 拉 500 微秒,然后释放,当 DS18B20 收到信号后等待 16~60 微秒左右,后发出 60~240 微秒的存在低脉冲,主 CPU 收到此信号表示复位成功。 (1) 先将数据线 DQ 置高电平“1”。 (2) 延时(该时间要求的不是很严格,但是尽可能的短一点) (3) 数据线拉到低电平“0”。 (4) 延时 750 微秒(该时间的时间范围可以从 480 到 960 微秒) 。 (5) 数据线拉到高电平“1”。 (6) 延时等待(如果初始化成功则在 15 到 60 微妙时间之内产生一个由 DS18B20 所返回 的低电平“0”。据该状态可以来确定它的存在,但是应注意不能无限的进行等待,不然会使 程序进入死循环,所以要进行超时控制) 。 (7) 若 CPU 读到了数据线上的低电平“0”后,还要做延时,其延时的时间从发出的高电平 算起(第(5)步的时间算起)最少要 480 微秒。 (8) 将数据线再次拉高到高电平“1”后结束。 初始化程序如下: uchar Init_DS18B20() { uchar status; //status 为 DS18B20 返回的状态 DQ = 1; Delay(8); DQ = 0; Delay(90); DQ = 1;
8、DS18B20 应用举例(一)
如下图所示:DQ 通过 4.7K 上拉电阻外接正电源(由于单总线为开漏所以需要外接一 个 4.7K 的上拉电阻),并连接单片机 P3.3 口。 本例中,1602LCD 显示 DS18B20 所测量的外部温度,调节 DS18B20 模拟改变外界 温度时,新的温度将刷新显示在 LCD 上。
DS18B20_proteus仿真(BCD数码管显示测试)
TEMP_ZH EQU 24H ;实测温度值存放单元TEMPL EQU 25HTEMPH EQU 26HTEMP_TH EQU 27H ;高温报警值存放单元TEMP_TL EQU 28H ;低温报警值存放单元TEMPHC EQU 29H ;正、负温度值标记TEMPLC EQU 2AHTEMPFC EQU 2BHFLAG1 EQU 20H.0 ;DS18B20是否存在标志DQ EQU P3.3 ;DS18B20数据信号ORG 0000H;*************************** 主程序开始 ******************************;*************************** 主循环开始 ****************************** START: LCALL RST ;调用DS18B20复位子程序JNB FLAG1,START ;DS18B20不存在MOV A,#0CCH ;跳过ROM匹配命令LCALL WRITEMOV A,#44H ;温度转换命令LCALL WRITELCALL RSTMOV A,#0CCH ;跳过ROM匹配LCALL WRITEMOV A,#0BEH ;读温度命令LCALL WRITELCALL READ ;调用DS18B20数据读取操作子程序LCALL CONVTEMP ;调用温度数据BCD 码处理子程序;MOV P1,70H ;小数位;MOV P1,71H ;个位;MOV P1,72H ;十位;MOV P1,73H ;百位(正温度大于或等于100=1,小于100=A,负温度=B)MOV P2,TEMPLC ;个位+小数位MOV P1,TEMPHC ;百位+十位SJMP START ;循环;*************************** 主循环结束 ******************************;****************************DS18B20复位子程序 ***************************** RST: SETB DQNOPCLR DQMOV R0,#6BH ;主机发出延时复位低脉冲MOV R1,#04HTSR1: DJNZ R0,$MOV R0,#6BHDJNZ R1,TSR1SETB DQ ;拉高数据线NOPNOPNOPMOV R0,#32HTSR2: JNB DQ,TSR3 ;等待DS18B20回应DJNZ R0,TSR2JMP TSR4 ; 延时TSR3: SETB FLAG1 ; 置1标志位,表示DS1820存在JMP TSR5TSR4: CLR FLAG1 ; 清0标志位,表示DS1820不存在JMP TSR7TSR5: MOV R0,#06BHTSR6: DJNZ R0,$ ; 时序要求延时一段时间;************************ DS18B20暂存器操作子程序 *************************** RE_18B20:JB FLAG1,RE_18B20ARETRE_18B20A:LCALL RSTMOV A,#0CCH ;跳过ROM匹配LCALL WRITEWR_SCRAPD:MOV A,#4EH ;写暂器LCALL WRITEMOV A,TEMP_TH ;TH(报警上限)LCALL WRITEMOV A,TEMP_TL ;TL(报警下限)LCALL WRITEMOV A,#7FH ;12位精度LCALL WRITERET;*********************** DS18B20数据写入操作子程序 ************************ WRITE: MOV R2,#8 ;一共8位数据CLR CWR1: CLR DQ ;开始写入DS18B20总线要处于复位(低)状态MOV R3,#07DJNZ R3,$ ;总线复位保持16微妙以上RRC A ;把一个字节DATA 分成8个BIT环移给CMOV DQ,C ;写入一位MOV R3,#3CHDJNZ R3,$ ;等待100微妙SETB DQ ;重新释放总线NOPDJNZ R2,WR1 ;写入下一位SETB DQRET;********************** DS18B20数据读取操作子程序 ************************** READ: MOV R4,#4 ;将温度低位、高位、TH、TL从DS18B20中读出MOV R1,#TEMPL ;存入25H、26H、27H、28H单元RE00: MOV R2,#8RE01: CLR CYSETB DQNOPNOPCLR DQ ;读前总线保持为低NOPNOPNOPSETB DQ ;开始读总线释放MOV R3,#09 ;延时18微妙DJNZ R3,$MOV C,DQ ;从DS18B20总线读得一位MOV R3,#3CHDJNZ R3,$ ;等待100微妙RRC A ;把读得的位值环移给ADJNZ R2,RE01 ;读下一位MOV @R1,AINC R1DJNZ R4,RE00RET;************************ 温度值 BCD 码处理子程序 ************************* CONVTEMP: MOV A,TEMPH ;判温度是否零下ANL A,#08HJZ TEMPC1 ;温度零上转CLR CMOV A,TEMPL ;二进制数求补(双字节)CPL A ;取反加1ADD A,#01HMOV TEMPL,AMOV A,TEMPHCPL AADDC A,#00HMOV TEMPH,AMOV TEMPHC,#0BH ;负温度标志MOV TEMPFC,#0BHSJMP TEMPC11TEMPC1: MOV TEMPHC,#0AH ;正温度标志MOV TEMPFC,#0AHTEMPC11: MOV A,TEMPHCSWAP AMOV TEMPHC,AMOV A,TEMPLANL A,#0FH ;乘0.0625MOV DPTR,#TEMPDOTTABMOVC A,@A+DPTRMOV TEMPLC,A ;TEMPLC LOW=小数部分 BCDMOV A,TEMPL ;整数部分ANL A,#0F0H ;取出高四位SWAP AMOV TEMPL,AMOV A,TEMPH ;取出低四位ANL A,#0FHSWAP AORL A,TEMPL ;重新组合MOV TEMP_ZH,ALCALL HEX2BCD1MOV TEMPL,AANL A,#0F0HSWAP AORL A,TEMPHC ;TEMPHC LOW = 十位数 BCDMOV TEMPHC,AMOV A,TEMPLANL A,#0FHSWAP A ;TEMPLC HI = 个位数 BCDORL A,TEMPLCMOV TEMPLC,AMOV A,R4JZ TEMPC12ANL A,#0FHSWAP AMOV R4,AMOV A,TEMPHC ;TEMPHC HI = 百位数 BCDANL A,#0FHORL A,R4MOV TEMPHC,ATEMPC12: RET;************************ 二-十进制转换子程序 ***************************** HEX2BCD1: MOV B,#064HDIV ABMOV R4,AMOV A,#0AHXCH A,BDIV AB;************************ 显示区 BCD 码温度值刷新子程序 ********************** DISPBCD: MOV A,TEMPLCANL A,#0FHMOV 70H,A ;小数位MOV A,TEMPLCSWAP AANL A,#0FHMOV 71H,A ;个位MOV A,TEMPHCANL A,#0FHMOV 72H,A ;十位MOV A,TEMPHCSWAP AANL A,#0FHMOV 73H,A ;百位RETEND。
多路DS18B20温度传感器-protues仿真
//编程:武汉理工大学XP//时间2012/5/25//版本:V1.0//DS18B20设置为12位精度//#include"reg51.h"unsigned char code table1[]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09};//不带小数点断码unsigned char code table2[]={0x02,0x9e,0x24,0x0c,0x98,0x48,0x40,0x1e,0x00,0x08}; //带小数点断码unsigned char code string[]="temperature";unsigned char code numtable[]="0123456789ABCDEF"; //液晶显示的字符unsigned char code txttable[]="-. "; //液晶显示的符号,负号,小数点,以及空格unsigned char code ROM_1[]={0x28,0x30,0xc5,0xb8,0x00,0x00,0x00,0x8e}; //U1 ROM值unsigned char code ROM_2[]={0x28,0x31,0xc5,0xb8,0x00,0x00,0x00,0xb9}; //U2 ROM值unsigned char code ROM_3[]={0x28,0x32,0xc5,0xb8,0x00,0x00,0x00,0xe0}; //U3 ROM值unsigned char code ROM_4[]={0x28,0x33,0xc5,0xb8,0x00,0x00,0x00,0xd7}; //U4 ROM值unsigned char ROM[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; //初始化的ROM值,//用于装载读取的DS18B20的ROM值sbit ds=P3^0; //总线//定义的数码管接口sbit qian=P2^0; //数码管千位sbit bai=P2^1; //数码管百位sbit shi=P2^2; //数码管十位sbit ge=P2^3; //数码管个位sbit E=P2^4; //液晶使能端口sbit CONTROL_DA TE=P2^5; //液晶写数据与写控制命令控制端int temp,shuju[5]={0}; //存放温度和温度数据处理后得到的液晶要显示的数int flag=1; //温度正负标志位//延时函数//void Delay(int z){ int x;for(;z>0;z--)for(x=110;x>0;x--);}//写入对液晶的控制命令//void Lcd_write_control(char date){CONTROL_DA TE=0;P1=date;Delay(50);E=1;Delay(50);E=0;}//写入要显示的数据//void Lcd_write_date(char date){CONTROL_DA TE=1;P1=date;Delay(10);E=1;Delay(10);E=0;}//液晶初始化//void LCD_INIT(void){E=0;Lcd_write_control(0x38); //设置16*2显示,5*7点阵,8为数据接口Lcd_write_control(0x0c); //设置开显示,不显示光标Lcd_write_control(0x06); //写一个字符后地址指针加一Lcd_write_control(0x01); //显示清零,数据指针清零}//DS18B20初始化//void DS_rest(void){int i;ds=0;i=103;while(i>0) i--;ds=1;i=4;while(i>0) i--;}//读一位数据//bit Temp_read_bit(void){int i;bit dat;ds=0;i++;ds=1;i++;i++;dat=ds;i=8;while(i>0)i--;return dat;}//读取一个字节的温度数据// unsigned char Temp_read(void){unsigned char i,j,dat;dat=0;for(i=1;i<=8;i++){j=Temp_read_bit();dat=(j<<7)|(dat>>1);}return dat;}//向DS18B20写入一位数据//void DS_writebyte(unsigned char dat) {int i;unsigned char j;bit testb;for(j=1;j<=8;j++){testb=dat&0x01;dat=dat>>1;if(testb){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++;}}}//匹配DS18B20的ROM//void MATCH_ROM(unsigned char *ROM_X) { int i;DS_rest();Delay(1);DS_writebyte(0x55);for(i=0;i<8;i++){DS_writebyte(*(ROM_X+i));}}//开始温度转换//void Temp_change(void){DS_rest();Delay(1);DS_writebyte(0xcc);//MATCH_ROM();DS_writebyte(0x44);}//获取温度数据//int Get_temp(){unsigned char a,b;static int i=1;DS_rest();Delay(1);//tempwritebyte(0xcc);//MATCH_ROM(ROM_1);switch(i){case 1: MA TCH_ROM(ROM_1); i++; break;case 2: MA TCH_ROM(ROM_2); i++; break;case 3: MA TCH_ROM(ROM_3); i++; break;case 4: MA TCH_ROM(ROM_4); i=1; break;}DS_writebyte(0xbe);a=Temp_read();b=Temp_read();if(b>=90){temp=~(a+b*256+1); flag=0;}else{temp=a+b*256; flag=1;}temp=temp*6.25;return temp;}//液晶显示//void Lcd_display(int t){int n=1,weishu1=0;static weishu2=0;Lcd_write_control(0x80+0x40);while(t>0){shuju[n++]=t%10;t/=10;}weishu1=n-1;if(flag==0)Lcd_write_date(txttable[0]);if(weishu1<=2)Lcd_write_date('0');for(n=weishu1;n>2;n--)Lcd_write_date(numtable[shuju[n]]);Lcd_write_date(txttable[1]);while(n>0){Lcd_write_date(numtable[shuju[n]]);n--;}if(weishu1<weishu2)Lcd_write_date(txttable[2]);weishu2=weishu1;}//读取DS18B20的ROM数据//void READ_ROM(void){ int i=0;DS_rest();Delay(1);DS_writebyte(0x33);for(i=0;i<8;i++)ROM[i]=Temp_read();}//显示DS18B20的ROM数据//void DISPLAY_ROM(void){int i;unsigned char t;Lcd_write_control(0x80);for(i=0;i<4;i++){ t=ROM[i];Lcd_write_date(numtable[t/16]);Lcd_write_date(numtable[ROM[i]%16]);Lcd_write_date(0x20);}Lcd_write_control(0x80+0x40);for(;i<8;i++){ t=ROM[i];Lcd_write_date(numtable[t/16]);Lcd_write_date(numtable[ROM[i]%16]);Lcd_write_date(0x20);}}main(){ int t,i;LCD_INIT();Lcd_write_control(0x80);for(i=0;i<11;i++)Lcd_write_date(string[i]);//循环显示温度while(1){Temp_change();t=Get_temp();Lcd_display(t);Delay(1000);}//显示DS18B20的ROM值//首先要用这个函数读取DS18B20的ROM值//然后将ROM值写到ROM[]数组中//最后注释掉ROM[]的显示,改为显示循环显示温度/* while(1){READ_ROM();DISPLAY_ROM();} */}。
18B20的程序附protues原理图
#include<reg51.h>#define uint unsigned int#define uchar unsigned charsbit DQ=P2^4;//18B20数据线引脚unsigned char flag;//负数标志//行扫描数组uchar code scan[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//row0--row7//数码管显示的段码表uchar code table[13]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x39,0x00};//小数部分显示查询表uchar code ditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};uchar dispbuf[8];//显示缓冲区uchar temper[2];//存放温度的数组//*********************************************************////延时函数void delay(unsigned int us){while(us--);}//**********************************************************////DS18B20复位函数/////////////////////////////////////////////////////////void reset(void){uchar x=0;DQ=1;delay(8);//88DQ=0;delay(80);//736DQ=1;delay(14);//142x=DQ;delay(20);//192}///////////////////////////////////////////////////////ds18b20中读一个字节uchar readbyte(void){uchar i=0;uchar dat=0;for(i=8;i>0;i--){DQ=0;dat>>=1;//4usDQ=1;if(DQ)// 为1就与0x80或dat|=0x80; //5usdelay(4); //延时40 }return(dat);}/////////////////////////////////////////////////向ds18b20中写一个字节void writebyte(unsigned char dat){uchar i=0;for(i=8;i>0;i--){DQ=0;DQ=dat&0x01;delay(5);//67DQ=1;dat>>=1;}delay(4);}////////////////////////////////////////DS18B20中读取实时温度值void readtemp(void){uchar a=0,b=0;reset();writebyte(0xcc);//跳过序列号writebyte(0x44);//启动温度转换reset();writebyte(0xcc);writebyte(0xbe);//读9个寄存器,前两个为温度a=readbyte(); //低位b=readbyte(); //高位if(b>0x0f){a=~a+1;if(a==0)b=~b+1; //负数温度应该先取反加1,在乘以0.0625是不带符号的温度else b=~b;flag=10;}else flag=12;temper[0]=a&0x0f;//不懂为何这样和数据a=a>>4;temper[1]=b<<4;temper[1]=temper[1]|a;}/////////////////////////////////////////////////动态扫描显示函数void scandisp(){unsigned char i,value;for(i=0;i<8;i++){P3=0xff;value=table[dispbuf[i]];if(i==3)value|=0x80;P0=value;P3=scan[i];delay(50);}}///////////////////////////////////////////////主函数void main(){uchar temp,temp1;while(1){scandisp();readtemp();temp1=temper[0];temp=temper[1];dispbuf[4]=ditab[temp1];dispbuf[1]=temp/100;dispbuf[3]=temp%10;temp=temp/10;dispbuf[2]=temp%10;dispbuf[0]=flag;dispbuf[5]=11;}}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
DS18B20测温显示,proteus仿真。
Written by jinsongliang具体程序如下:#include<>#include""#include""#include""void main (void){unsigned char disp[5]={10,0,0,14,2};signed char temp=0;while(1){/*1、读取温度值*/temp=Get_Temputer();//2、显示前处理*/if(temp<0){disp[0]=13;temp=-temp;disp[1]=temp/10;disp[2]=temp%10;}else{disp[0]=temp/100;disp[1]=temp/10-disp[0]*10;disp[2]=temp%10;if(!disp[0]) //百位数不为0则显示,若要显示0,可将其注释掉disp[0]=10;}//3、显示*/Seg_Display(disp);}}void Delay_Nus (unsigned char n) {while(n--);//for (;n>0;n--);}:/******************************************************************时序很重要,移植时注意延时函数******************************************************************/#define B20_PORT P1 //此处可以设置I/O口#define B20_CHANNEL 0#define R_B20_CHANNEL() B20_PORT&(1<<B20_CHANNEL)#define W_B20_CHANNEL_1() B20_PORT|=(1<<B20_CHANNEL)#define W_B20_CHANNEL_0() B20_PORT&=~(1<<B20_CHANNEL)#define SKIP_ROM 0xCC#define TEMPUTER_CONVERT 0x44#define READ_ROM 0xBE//one/*初始化函数,失败会返回1,初始化过程见注释若单片机读到了数据线上的低电平“0”后,还要做延时,其延时的时间从单片机发出的高电平算起最少要480微秒。
之后单片机将数据线再次拉高到高电平“1”后结束。
*/static unsigned char Init_18b20 (void){unsigned char x=0;W_B20_CHANNEL_1(); //1、从单片机拉高数据线开始Delay_Nus(8); //6*n usecondsW_B20_CHANNEL_0();Delay_Nus(81);W_B20_CHANNEL_1(); //2、单片机拉低数据线480us以上,拉高数据线,释放 Delay_Nus(14); //3、之后ds18b20,15~60us以后反应,拉高数据线x=R_B20_CHANNEL(); //4、单片机读取数据线if(x)return x;Delay_Nus(20);return x; //x=0代表复位成功}//twostatic void Write_18b20(unsigned char w_data){unsigned char i;unsigned char temp;for(i=0;i<8;i++){W_B20_CHANNEL_1();temp=w_data&(1<<0);W_B20_CHANNEL_0(); //单片机从高到低,拉低1us以上,并在15us内产生写间隙B20_PORT=temp<<B20_CHANNEL; //写数据,(先写低位)Delay_Nus(7); //15~60us内18B20采样w_data>>=1;}W_B20_CHANNEL_1();Delay_Nus(4);}//threestatic unsigned char Read_18b20(void){unsigned char i;unsigned char temp;unsigned char r_data=0x00;for(i=0;i<8;i++){r_data>>=1;W_B20_CHANNEL_1();W_B20_CHANNEL_0(); //从高到低15us内,再到高,产生读间隙Delay_Nus(1);W_B20_CHANNEL_1();temp=B20_PORT<<(7-B20_CHANNEL); //读数据,从低位开始temp&=(1<<7);r_data+=temp;Delay_Nus(8); //整个读一位过程在60~120us }W_B20_CHANNEL_1();return r_data;}//four/*若要读出当前的温度数据我们需要执行两次工作周期,第一个周期为复位、跳过ROM指令、执行温度转换存储器操作指令、等待500uS温度转换时间。
紧接着执行第二个周期为复位、跳过ROM指令、执行读RAM的存储器操作指令、读数据(最多为9个字节,中途可停止,只读简单温度值则读前2个字节即可)*/signed char Get_Temputer (void)//读取温度值,返回的带符号字符型-55到+127;128无法显示,初始化失败会显示{unsigned char tem_h,tem_l;signed char temp;if(Init_18b20()==0) //复位18b20{Write_18b20(SKIP_ROM); //跳过ROMWrite_18b20(TEMPUTER_CONVERT); //温度变换}elsereturn temp=0;//Delay_Nus(100);if(Init_18b20()==0) //复位18b20{Write_18b20(SKIP_ROM); //跳过ROMWrite_18b20(READ_ROM); //读暂存存储器}elsereturn temp=0;tem_l=Read_18b20(); //读数据tem_h=Read_18b20();/*只要高字符的低四位和低字符的高四位,温度范围0~99,temp为补码,直接由unsigned char 赋值给 signed char 内容不变,代表的值改变*/temp=(tem_h<<4)+(tem_l>>4);return temp;}:#define COMMON_ANODIC 0 //共阳数码管#define COMMON_CATHODAL 1 //共阴数码管#define SEG_CATEGORY 0 //选择共阳数码管#define SEG8_A ~(1<<0) //段A亮时为0,属共阳数码管#define SEG8_B ~(1<<1)#define SEG8_C ~(1<<2)#define SEG8_D ~(1<<3)#define SEG8_E ~(1<<4)#define SEG8_F ~(1<<5)#define SEG8_G ~(1<<6)#define SEG8_DP ~(1<<7)#define SEG8_CHAR_0 ~(SEG8_G&SEG8_DP)#define SEG8_CHAR_1 ~(SEG8_A&SEG8_D&SEG8_E&SEG8_F&SEG8_G&SEG8_DP)#define SEG8_CHAR_2 ~(SEG8_C&SEG8_F&SEG8_DP)#define SEG8_CHAR_3 ~(SEG8_E&SEG8_F&SEG8_DP)#define SEG8_CHAR_4 ~(SEG8_A&SEG8_D&SEG8_E&SEG8_DP)#define SEG8_CHAR_5 ~(SEG8_B&SEG8_E&SEG8_DP)#define SEG8_CHAR_6 ~(SEG8_B&SEG8_DP)#define SEG8_CHAR_7 ~(SEG8_D&SEG8_E&SEG8_F&SEG8_G&SEG8_DP)#define SEG8_CHAR_8 ~SEG8_DP#define SEG8_CHAR_9 ~(SEG8_E&SEG8_DP)#define SEG8_CHAR_ ~0#define SEG8_CHAR_E ~(SEG8_B&SEG8_C&SEG8_DP)#define SEG8_CHAR_R ~(SEG8_A&SEG8_B&SEG8_C&SEG8_D&SEG8_F&SEG8_DP)#define SEG8_CHAR_SUB ~(SEG8_A&SEG8_B&SEG8_C&SEG8_D&SEG8_E&SEG8_F&SEG8_DP) //#define SEG8_CHAR_A//#define SEG8_CHAR_B#define SEG8_CHAR_C ~(SEG8_B&SEG8_C&SEG8_G&SEG8_DP)//#define SEG8_CHAR_D//#define SEG8_CHAR_F//#define SEG8_CHAR_H#if SEG_CATEGORY==COMMON_ANODICstatic const unsigned char SEG8_CODE[]={SEG8_CHAR_0,SEG8_CHAR_1,SEG8_CHAR_2,SEG8_CHAR_3,SEG8_CHAR_4,SEG8_CHAR_5,SEG8_CHAR_6,SEG8_CHAR_7,SEG8_CHAR_8,SEG8_CHAR_9,SEG8_CHAR_, //SEG8_CODE[10]SEG8_CHAR_E, //SEG8_CODE[11]SEG8_CHAR_R, //SEG8_CODE[12]SEG8_CHAR_SUB, //SEG8_CODE[13]SEG8_CHAR_C //SEG8_CODE[14]};#elsestatic const unsigned char SEG8_CODE[]={~SEG8_CHAR_0,~SEG8_CHAR_1,~SEG8_CHAR_2,~SEG8_CHAR_3,~SEG8_CHAR_4,~SEG8_CHAR_5,~SEG8_CHAR_6,~SEG8_CHAR_7,~SEG8_CHAR_8,~SEG8_CHAR_9,~SEG8_CHAR_, //SEG8_CODE[10]~SEG8_CHAR_E, //SEG8_CODE[11]~SEG8_CHAR_R, //SEG8_CODE[12]~SEG8_CHAR_SUB, //SEG8_CODE[13]~SEG8_CHAR_C //SEG8_CODE[14]};#endif#define SEG8_SLECT_PORT P3 //此处可以设置I/O口#define BIT0 0#define BIT1 1#define BIT2 2#define BIT3 3#define SEG8_BIT0_ON() SEG8_SLECT_PORT|=(1<<BIT0)#define SEG8_BIT0_OFF() SEG8_SLECT_PORT&=~(1<<BIT0)#define SEG8_BIT1_ON() SEG8_SLECT_PORT|=(1<<BIT1)#define SEG8_BIT1_OFF() SEG8_SLECT_PORT&=~(1<<BIT1)#define SEG8_BIT2_ON() SEG8_SLECT_PORT|=(1<<BIT2)#define SEG8_BIT2_OFF() SEG8_SLECT_PORT&=~(1<<BIT2)#define SEG8_BIT3_ON() SEG8_SLECT_PORT|=(1<<BIT3)#define SEG8_BIT3_OFF() SEG8_SLECT_PORT&=~(1<<BIT3)#define SEG8_CODE_PORT P2 //此处可以设置I/O口void Seg_Display (char *p){unsigned char temp[4];temp[0]=SEG8_CODE[*p++];temp[1]=SEG8_CODE[*p++];temp[2]=SEG8_CODE[*p++];temp[3]=SEG8_CODE[*p++];if(*p<4)#if SEG_CATEGORY==COMMON_ANODICtemp[*p]&=SEG8_DP;#elsetemp[*p]|=~SEG8_DP;#endif{unsigned char i;for(i=0;i<150;i++){SEG8_CODE_PORT = temp[0];SEG8_BIT0_ON();Delay_Nus(6); //SEG8_BIT0_OFF();SEG8_CODE_PORT = temp[1];SEG8_BIT1_ON();Delay_Nus(6);SEG8_BIT1_OFF();SEG8_CODE_PORT = temp[2];SEG8_BIT2_ON();Delay_Nus(6);SEG8_BIT2_OFF();SEG8_CODE_PORT = temp[3];SEG8_BIT3_ON();Delay_Nus(6);SEG8_BIT3_OFF();}}}。