|
wujinlin(VIP会员)
头衔:社区公民
帮派:无帮无派
帖数:26
金钱:380
积分:112
注册时间:2020/12/30
|
基于51单片机控制的DS18B20数字温度系统 本文主要介绍了一个基于 AT89C51单片机的测温系统,详细描述了利用数字温度传感器 DS18B20 开发测温系统的过程。对采集的信息都希望用最直接的方式显示出来,但是传感器所采集的信息是模拟的信号,并且信号是非常微小的,需要用放大器进行放大。模拟信号不能直接用数字仪器直接显示,通过模数转换之后就可以将模拟量转变成数字量,在通过数码管进行显示。有些可以直接与单片机链接。数码管有共阳极与共阴极两类,本次设计采用的是共阴极的七段数码管。 设计要求:利用数字温度传感器 DS18B20 与单片机结合来测量温度。利用数字 温度传感器 DS18B20 测量温度信号,计算后在 LED 数码管上显示 相应的温度值。其温度测量范围为−55℃~125℃,精确到 0.5℃;实 现超限报警 DS18B20 数字温度计是 DALLAS 公司生产的 1-Wire ,即单总线器件,具有线路简单、体积小的特点。因此用它来组成一个测温系统,线路简单,在一根通信线上,可以挂很多这样的数字温度计,十分方便。 DS18B20 是美国DALLAS 公司新推出的一种可组网数字式温度传感器,与 DS1820 相似,DS18B20 也能够直接读取被测物体的温度值。但是与 DS1820 相比, DS18B20 的功能更强大些。它体积小,电压适用范围宽( 3--5V ),用户还可以通过编程实现 9--12 位精度的温度读数,即具有可调的温度分辨率,因此它的实用性和可靠性比同类产品更高。 总原理图: C程序源代码: #include<reg51.h> #include<intrins.h> sbit DQ=P1^7; //定义DS18B20的接受端口 sbit p0_7=P0^7; sbit p3_0=P3^0; //以下五个端口为按钮 sbit p3_1=P3^1; sbit p3_2=P3^2; sbit p3_3=P3^3; sbit p3_4=P3^4; sbit p1_0=P1^0; #define uchar unsigned char #define uint unsigned int void yanshi(int ); //普通延时函数 void jinyan(int ); // 精确延时 void yan_us (uchar); // us级延时 bit chushi(void); // DS18B20通信初始化 void xie(uchar ); // 向DS18B20写数据 uint du(void); // 读取DS18B20的数据 float chuli(uint); // 处理DS18B20返回的数据 void xianshi(float); // 数码管显示函数 uchar biao[12]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x39,0x71};// 数码管0-9 的显示数据 bit huan=1; void main(void){ uint ab=0; float ac=0; char shang=50; char xia =10; int bian=0; DQ=1; p3_0=1; p3_1=1; p3_2=1; p3_3=1; p3_4=1; TMOD=0x01; EA=0; ET0=0; while(1){ if((ab==1)&&chushi()){ // 向DS18B20发送转换温度指令 yan_us(100); xie(0xcc); xie(0x44); } if((DQ==1)&&(ab==500)&&chushi()){ //接受DS18B20的数据 yan_us(100); xie(0xcc); xie(0xbe); ac=chuli(du()); ab=0; } ab++; xianshi(ac); // 显示DS18B20的温度数据 if(p3_4==0){ // 切换温度显示方式C F huan=~huan; while(!p3_4); } if(p3_0==0){ //调整上限增加 bian=0; while(!p3_0){ if(bian==200){ shang++; bian=0; } bian++; xianshi(shang); } } if(p3_1==0){ // 调整上限减少 bian=0; while(!p3_1){ if(bian==200){ shang--; bian=0; } bian++; xianshi(shang); } } if(p3_2==0){ // 调整下限增加 bian=0; while(!p3_2){ if(bian==200){ xia++; bian=0; } bian++; xianshi(xia); } } if(p3_3==0){ // 调整下限减少 bian=0; while(!p3_3){ if(bian==200){ xia--; bian=0; } bian++; xianshi(xia); } } if(ac<xia||ac>shang) // 判断温度示数是否超上下限 p1_0=1; else p1_0=0; } } void yanshi(int a){ int b; while(a--){ for(b=0;b<110;b++); } } void jinyan(int a){ TH0=(65536-a)/256; TL0=(65536-a)%256; TR0=1; while(!TF0); TF0=0; TR0=0; } void yan_us(uchar a){ while(a--); } bit chushi(void){ uchar a=0; DQ=0; yan_us(100); DQ=1; while(DQ){ if(a==200) return 0; a++; } a=0; while(!DQ){ if(DQ==250) return 0; a++; } return 1; } void xie(uchar a){ char b; bit c; for(b=0;b<8;b++){ c=a&0x01; if(c){ DQ=0; _nop_(); _nop_(); DQ=1; yan_us(13); } else { DQ=0; yan_us(13); DQ=1; } a=a>>1; } } uint du(void){ uint a=0,b=0; bit c=0; char d; for(d=0;d<16;d++){ DQ=0; _nop_(); _nop_(); DQ=1; _nop_(); _nop_(); _nop_(); c=DQ; b=c; b=b<<d; a=a|b; b=0; yan_us(9); } DQ=0; yanshi(2); DQ=1; return a; } float chuli(uint a){ float b; if(a>=32768){ a=~a; a++; b=(float)a; b=b/(-16); } else { b=(float)a; b=b/16; } return b; } void xianshi(float a){ uint b,c; if(!huan) a=32+a*1.8; if(a<0){ a=a*(-1); b=(uint)a; a=(a-b)*10; c=(uint)a; P2=0x00; P0=0x40; P0=0x00; } else{ b=(uint)a; a=(a-b)*10; c=(uint)a; } P2=0x01; P0=biao[b/100]; P0=0x00; P2=0x02; P0=biao[(b/10)%10]; P0=0x00; P2=0x03; P0=biao[b%10]; p0_7=1; P0=0x00; P2=0x04; P0=biao[c]; P0=0x00; P2=0x05; if(huan) P0=biao[10]; else P0=biao[11]; P0=0x00; } 仿真图: 「该帖子被 wujinlin 在 2021/1/4 12:48:01 编辑过」 这家伙很懒,什么也没有留下! |
等级: |
2021/1/4 12:04:17
|