很简单,很基础的,共享给大家
完整的课程设计下载:
数字温度计的设计.doc
(525 KB, 下载次数: 190)
摘 要随着“信息时代”的到来,作为获取信息的手段——传感器技术得到了显著的进步,其应用领域越来越广泛,对其要求越来越高,需求越来越迫切。传感器技术已成为衡量一个国家科学技术发展水平的重要标志之一。因此,了解并掌握传感器的基本结构、工作原理及特性是非常重要的。在日常生活及工农业生产中,经常要用到温度的检测及控制,传统的测温元件有热电偶和热电阻。而热电偶和热电阻测出的一般都是电压,再转换成对应的温度,需要比较多的外部硬件支持, 其缺点如下:1. 硬件电路复杂;2. 软件调试复杂;3. 制作成本高。为了提高对传感器的认识和了解,尤其是对温度传感器的深入研究以及其用法与用途,基于实用、广泛和典型的原则而设计了本系统。本文利用单片机结合传感器技术开发设计,文中把传感器理论与单片机实际应用有机结合,详细地讲述了利用温度传感器DS18B20测量环境温度,同时51单片机在现代电子产品中广泛应用以及其技术已经非常成熟,DS18B20可以直接读出被测温度值,而且采用三线制与单片机相连,减少了外部的硬件电路,具有低成本和易使用的特点。 关键词: 信息时代 温度传感器 51单片机
目 录
摘 要 目 录 第一章 绪论 1.1 背景 1.2 设计目的 1.2.1掌握温度计,报警系统的设计、组装与调试方法。 1.2.2熟悉仿真软件(proteus)的使用。 1.2.3重点掌握单片机的使用及其各引脚的功能。 第二章 原理分析 2.1原理框图 2.2 原理分析 第三章 实现过程 3.1显示电路 3.2数码管驱动电路 3.3报警电路 3.4数字温度传感器 3.5单片机最小系统电路 3.6 按键电路 3.7数字温度计的实物图 3.8系统板上硬件连钱 3.9 系统调试与分析 3.10 元件清单及程序代码 心得体会
1.1 背景 在日常生活及工农业生产中,经常要用到温度的检测及控制,传统的测温元件有热电偶和热电阻。而热电偶和热电阻测出的一般都是电压,再转换成对应的温度,需要比较多的外部硬件支持, 其缺点如下:1. 硬件电路复杂;2. 软件调试复杂;3. 制作成本高。为了提高对传感器的认识和了解,尤其是对温度传感器的深入研究以及其用法与用途,基于实用、广泛和典型的原则而设计了本系统。 1.2 设计目的 1.2.1掌握温度计,报警系统的设计、组装与调试方法。 1.2.2熟悉仿真软件(proteus)的使用。 1.2.3重点掌握单片机的使用及其各引脚的功能。 第二章 原理分析 2.1原理框图 protues仿真图
Protues仿真图显示当前温度30℃ 2.2 原理分析 整个系统由单片机控制,温度传感器采用18B20。18b20采用单总线方式与单片机相连.把采集到得温度信息传给单片机。单片机采集到的温度输出到四个数码管上进行显示。当四位数码管显示的温度超过上限值时可以实现报警功能。 DS18B20原理与分析 DS18B20是美国DALLAS半导体公司继DS1820之后最新推出的一种改进型智能温度传感器。与传统的热敏电阻相比,他能够直接读出被测温度并且可根据实际要求通过简单的编程实现9~12位的数字值读数方式。可以分别在93.75 ms和750 ms内完成9位和12位的数字量,并且从DS18B20读出的信息或写入DS18B20的信息仅需要一根口线(单线接口)读写,温度变换功率来源于数据总线,总线本身也可以向所挂接的DS18B20供电,而无需额外电源。因而使用DS18B20可使系统结构更趋简单,可靠性更高。他在测温精度、转换时间、传输距离、分辨率等方面较DS1820有了很大的改进,给用户带来了更方便的使用和更令人满意的效果。 1.DS18B20简介 (1)独特的单线接口方式:DS18B20与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯。 (2)在使用中不需要任何外围元件。 (3)可用数据线供电,电压范围:+3.0~ +5.5 V。 (4)测温范围:-55 ~+125 ℃。固有测温分辨率为0.5 ℃。 (5)通过编程可实现9~12位的数字读数方式。 (6)用户可自设定非易失性的报警上下限值。 (7)支持多点组网功能,多个DS18B20可以并联在惟一的三线上,实现多点测温。 (8)负压特性,电源极性接反时,温度计不会因发热而烧毁,但不能正常工作。 DS18B20的测温原理 DS18B20的测温原理如图2所示,图中低温度系数晶振的振荡频率受温度的影响很小〔1〕,用于产生固定频率的脉冲信号送给减法计数器1,高温度系数晶振随温度变化其震荡频率明显改变,所产生的信号作为减法计数器2的脉冲输入,图中还隐含着计数门,当计数门打开时,DS18B20就对低温度系数振荡器产生的时钟脉冲后进行计数,进而完成温度测量。计数门的开启时间由高温度系数振荡器来决定,每次测量前,首先将-55 ℃所对应的基数分别置入减法计数器1和温度寄存器中,减法计数器1和温度寄存器被预置在 -55 ℃ 所对应的一个基数值。减法计数器1对低温度系数晶振产生的脉冲信号进行减法计数,当减法计数器1的预置值减到0时温度寄存器的值将加1,减法计数器1的预置将重新被装入,减法计数器1重新开始对低温度系数晶振产生的脉冲信号进行计数,如此循环直到减法计数器2计数到0时,停止温度寄存器值的累加,此时温度寄存器中的数值即为所测温度。图2中的斜率累加器用于补偿和修正测温过程中的非线性,其输出用于修正减法计数器的预置值,只要计数门仍未关闭就重复上述过程,直至温度寄存器值达到被测温度值,这就是DS18B20的测温原理。 第三章 实现过程 3.1显示电路 四位共阳LED数码管:用来显示温度的大小,可直接读取,温度精确到0.1℃。四位数码管如图所示,从左到右依次是百位,十位,个位,十分位。 图 1 数码管 3.2数码管驱动电路 三极管8050:来驱动四位数码管,如下图所示三极管Q1 、Q2 、Q3、Q4。 图 2 三极管8050 3.3报警电路 三极管8550驱动蜂鸣器:如下图所示三极管Q6来驱动蜂鸣器BUZ1。 图 3 三极管8550、蜂鸣器BUZ1 3.4数字温度传感器 数字温度传感器DS18B20:如下图所示 图 4 DS18B20 3.5单片机最小系统电路 单片机最小化系统:如下图所示系统工作时,最小化系统运行。
图 5 最小化系统 3.6 按键电路 按键:如图所示按键K1为进入/退出设置键;K2为增加键;K3为减少键。
图 6 按键
3.7数字温度计的实物图 数字温度计显示当前温度25.7℃ I
图7 数字温度计实物图 3.8系统板上硬件连钱 1). 把“单片机系统“区域中的P0.0-P0.7端口用8芯排线依次连接到数码管A-DP端口上; (2). 把“单片机系统”区域中的P3.0-P3.2端口用线连接到按键K1-K3的一端上,如图表7所示,其他所有连线按图表7连接即可。 (3)把单片机的P2.0端口接数码管的位选3,P2.1端口接数码管的位选2,P2.2端口接数码管的位选1,P2.3端口接数码管的位选4。 (4).电源可用外接电源(用手机充电器可做电源),但必须申明电源小于+5V当然也不能太小 3.9 系统调试与分析 在系统制作和调试过程中遇到了不少问题,下面是具体问题与解决方法。 检查之后发现原来是4个8550三极管管脚接错,改正之后该问题即解决了。 ②4个数码管亮度不一样 8550管脚改正过后,显示不一样了,但4个数码管亮度不一样。当某一个数码管显示的字段较少,比如“1”时,亮度较强,但是当显示的字段较多比如“8”时,亮度较暗。分析其原因是:共阴数码管限流电阻用在控制位选的共阴极的输入端,这样当显示“1”时,电流相对集中,显示“8”字段较多,电流分配后较小,因此“1”显示时比显示“8”时亮。 解决方法:减小这里的限流电阻,使其流入数码管的电流变的很大,这样在较大电流时,即使字段多的电流较小,也比原来大了。这样就减小了差距,虽然还是有差距但已不太明显。 3.10 元件清单及程序代码 元件清单: 单片机AT89C52:1个 40引脚底座:1个 DS18B20:1个 蜂鸣器:1个 三极管:8050 5个;8550 1个 电阻:1k 6个;10K 1个 电容:极性电容10uf 1个;瓷片电容10pf 2个 按键:3个 晶振:1个 四位共阳数码管:1个 程序代码: - #include
- #define uchar unsigned char
- #define uint unsigned int
- sbit d1=P2^2;
- sbit d2=P2^1;
- sbit d3=P2^0;
- sbit d4=P2^3;
- sbit key1=P3^0;
- sbit key2=P3^1;
- sbit key3=P3^2;
- sbit beep=P3^3;
- sbit DS=P1^2;
- sbit ACC_7=ACC^7;
- uint count=1000,alarm=300;
- uchar shu;
- uchar shi,fen,ri,yue,nian,xq,miao,ss;
- uint temp; // 温度变量
- uchar flag;
- uchar code tab[]=
- {0xc0,0xf9,0xa4,0xb0,
- 0x99,0x92,0x82,0xf8,
- 0x80,0x90
- };
- uchar code tab1[]=//小数点点亮
- {0x40,0x79,0x24,0x30,
- 0x19,0x12,0x02,0x78,0x00,0x10
- };
- void delay(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=120;y>0;y--);
- }
- void dsreset()//发复位
- {
- uint i;
- DS=0;
- i=103;
- while(i>0)i--;
- DS=1;
- i=4;
- while(i>0)i--;
- }
- uchar tmpread() //读取一字节
- {
- uchar j,k,dat;
- uint i;
- for(j=1;j<=8;j++)
- {
- DS=0;i++; //延时
- DS=1;i++;i++;
- k=DS;
- i=8;while(i>0)i--;
- dat=(k<<7)|(dat>>1);//读出的数据最低位在最前面存一个字节在DAT里
- }
- return(dat);
- }
- void tmpwritebyte(uchar dat) //写一个字节
- {
- uint i;
- uchar j;
- bit testb;
- for(j=1;j<=8;j++)
- {
- testb=dat&0x01;
- dat=dat>>1;
- if(testb) //写 1
- {
- DS=0;
- i++;i++;
- DS=1;
- i=8;while(i>0)i--;
- }
- else
- {
- DS=0; //写 0
- i=8;while(i>0)i--;
- DS=1;
- i++;i++;
- }
- }
- }
- void tmpchange() //DS18B20温度变换
- {
- dsreset();
- delay(1);
- tmpwritebyte(0xcc); //跳过读取内存rom
- tmpwritebyte(0x44); //开始转换
- }
- uint tmp() //读取温度
- {
- float tt;
- uchar a,b;
- dsreset();
- delay(1);
- tmpwritebyte(0xcc);
- tmpwritebyte(0xbe);
- a=tmpread(); //a为低字节8位
- b=tmpread(); //b为高字节8位
- temp=b; //temp为温度值UINT 16bit
- temp<<=8; //两个字节组合到一起
- temp=temp|a;
- if(b>127)
- {
- flag=1;
- ss=flag;
- temp=~temp+1;
- }
- tt=temp*0.0625; // temp/16 则是温度的真实值tt.7位整数,4位小数
- temp=tt*10+0.5; // 扩大十倍取出了第一位小数
- return(temp);
- }
- void displayTemp(uint temp) //显示温度程序
- {
- uchar ge,shi,bai,qian,ser;
- d1=0;
- d1=0;
- d3=0;
- d4=0;
- dsreset();
- ser=temp/10; //分离出三位要显示的数字
- SBUF=ser;
- qian=temp/1000;
- bai=temp/100%10; // 百位数字
- shi=temp/10%10; // 十位数字
- ge=temp%10; // 个位数字
- if(flag==1)
- {
- flag=0;
- P0=0xbf;
- d1=1;
- delay(2);
- d1=0;
- }
- if(qian!=0)
- {
- P0=tab[qian];
- d1=1;
- delay(2);
- d1=0;
- }
- else
- {
- P0=0xff;
- d1=1;
- delay(2);
- d1=0;
- }
- if(temp>99)
- {
- P0=tab[bai];
- d2=1;
- delay(2);
- d2=0;
- }
- P0=tab1[shi];
- d3=1;
- delay(2);
- d3=0;
- P0=tab[ge];
- d4=1;
- delay(2);
- d4=0;
- }
- uint keyscan()
- {
- if(key1==0)
- {
- delay(5);
- if(key1==0)
- {
- while(!key1);
- shu++;
- }
-
-
- }
- if(key2==0)
- {
- delay(5);
- if(key2==0)
- {
- while(!key2);
- count=count+10;
- if(shu==2)
- {
- alarm+=10;
- }
-
- }
- }
- if(key3==0)
- {
- delay(5);
- if(key3==0)
- {
- while(!key3);
- count=count-10;
- if(shu==2)
- {
- alarm-=10;
- }
- }
- }
- return(count);
-
- }
-
- void main()
- {
- beep=0;
- delay(10);
- while( 1 )
- {
- tmpchange();
- if(shu==0)
- {
- displayTemp(tmp( ));
- }
- keyscan();
- if(shu==1)
- {
- displayTemp(count);
- }
- if(shu==2)
- {
- displayTemp(alarm);
- }
- if(shu==3)
- {
- shu=0;
- }
- if(temp>count||(temp<alarm))
- {
- beep=0;
-
- }
- else
- beep=1;
-
- }
- }
-
-
复制代码
|