单片机 温度计DS18B20

发布时间:2024-11-17

单片机89C52 ,液晶LCD12864,ADC0809,温度传感器DS18B20

单片机课程设计论文

单片机89C52 ,液晶LCD12864,ADC0809,温度传感器DS18B20

基于18B20温度检测系统设计

一、引言

温度是工农业生产中最常见的参数之一,与产品的质量、生产效率、安全

生产等密切相关,因此在生产过程中需对温度进行检测和监控。然而,传统的测温系统多以二极管、Pt100 及AD590 作为温度检测单元, 通过信号处理电路将待测温度的变化转换为电信号的变化,从而实现温度的测量。伴随着微电子技术的发展,利用单线总线实现信号双向传输的数字温度传感器的出现,改变了传统测量温度的方法。

该设计系统主要由STC89C52 单片机、数字温度传感器DS18B20 及液晶显示器12864三大部分组成。在此系统中,DS18B20 是美国生产的低功耗、高性能、抗干扰能力强的单总线数字温度传感器芯片,具有可编程的温度转换分辨率,可根据应用需要在9 ~12bit 之间选取,且测温范围为:-55~125℃。作为温度采集单元的DS18B20,采用外部电源供电方式,与STC89C2单片机进行双向通信,无需A/D ,就可以直接将被测温度转换为数字信号供单片机进行处理, 最终将换算得到的测量温度值显示在液晶显示器上。

二、实验器材

电源+5V、万用表、电烙铁

三、电路设计分析

(一)、硬件电路

单片机89C52 ,液晶LCD12864,ADC0809,温度传感器DS18B20

1、数字温度传感器18b20与单片机硬件连线

4039383736353433323130292827262524232221

VDD接外部电源,

DQ(

I/O)口与单片机P1.1串口连接,同时接4.7K上拉电阻接电源,GND接地。

下图为所用DS18B20的封装,它是独特的单线接口方式,在与89c52连接时仅需要一条口线即可实现双向通讯,无需外部元件 。

电压范围为3.0 V至5.5 V ,无需备用电源, 测量温度范围为-55℃至+125 ℃。温度传感器可编程的分辨率为9~12位, 温度转换为12位数字格式,最大值为750毫秒 。DS18B20内部结构主要由四部分组成:64位光刻ROM,温度报警触发器,温度传感器以及高速缓存器。此外,DS18B20内部还包括寄生电源、电源检测、存储控制逻辑、8位循环冗余码生成器(CRC)等部分。内部结构为:

单片机89C52 ,液晶LCD12864,ADC0809,温度传感器DS18B20

若是要使采集的数据分辨率越高,则所需要的温度数据转换时间越长。因此,在实际应用中要将分辨率和转换时间权衡考虑。

DS18B20的测温原理如下图所示:

2、LCD12864与单片机的硬件连线

RXX

LCD16824液晶1脚VSS接地,2脚VDD接电源,3脚V0接10K滑动变阻器调节对比度,4脚RS接单片机P1.4口,5脚RW脚接单片机P1.3口,6脚EN接单片机P1.2口,7~14脚DB口接单片机P2口,15脚PSB接高电平,默认为并行串口方式,16~18脚NC\RST\VOUT悬空默认低电平,19脚A默认高电平,接高电

单片机89C52 ,液晶LCD12864,ADC0809,温度传感器DS18B20

平,液晶背景光为亮,20脚K接地。

带中文字库的12864是一种具有4位/8位并行、2线或3线串行多种接口方式,内部含有国标一级、二级简体中文字库的点阵图形液晶显示模块;其显示分辨率为128×64, 内置8192个16*16点汉字,和128个16*8点ASCII字符集.利用该模块灵活的接口方式和简单、方便的操作指令,可构成全中文人机交互图形界面。它每屏最多可实现4行*8=32个中文字符或64个ASCII码字符的显示,内部提供128×2字节的字符显示RAM缓冲区(DDRAM),字符显示是通过将字符显示编码写入该字符显示RAM实现的。根据写入内容的不同,可分别在液晶屏上显示CGROM(中文字库)、HCGROM(ASCII码字库)及CGRAM(自定义字形)的内容。同时它可以先设垂直地址再设水平地址方式显示图形,功能比1602更好。

3、单片机复位和振荡电路连线

4039383736353433323130292827262524232221

A、复位是单片机的初始化操作,其主要功能是把PC初始化为0000H,使单片机从0000H单元开始执行程序。除了进入系统的正常初始化之外,当由于程序运行出错或操作错误使系统处于死锁状态时,为摆脱困境,也需按复位键重新启动。除PC之外,复位操作还对其他一些寄存器有影响,它们的复位状态如表一所示。

表一 一些寄存器的复位状态

寄存器

复位状态

寄存器

复位状态

单片机89C52 ,液晶LCD12864,ADC0809,温度传感器DS18B20

PC ACC PSW SP DPTR P0-P3 IP IE TMOD

0000H 00H 00H 07H 0000H FFH XX000000B 0X000000B

00H

TCON TL0 TH0 TL1 TH1 SCON SBUF PCON

00H 00H 00H 00H 00H 00H 不定 0XXX0000B

RST引脚是复位信号的输入端。复位信号是高电平有效,其有效时间应持续24个振荡周期(即二个机器周期)以上。

B、时钟电路相当于微机处理器的脉搏,单片机内部有一个高增益反相放大器,反相放大端输入为XTAL1,输出为XTAL2,在XTAL1和XTAL2两端跨接石英晶体及微调电容就构成了振荡器。我们用了11.0592M的晶振,则振荡周期为T0=1/11.0592us,时钟周期为2T0,机器周期为12T0. (二)、 软件设计

1、18b20驱动时序 #include<reg52.h> #include <intrins.h>

#define uchar unsigned char #define uint unsigned int sbit dq=P1^1; uint t,s;

uchar flag,count;

void delayus(uint z) //ds18b20内部延时 {

uchar i;

for(i=0;i<z;i++); }

////ds18b20复位,及存在检测// uchar ds18b20_reset() {

uchar k;

dq=1; //释放总线

单片机89C52 ,液晶LCD12864,ADC0809,温度传感器DS18B20

delayus(5); //延时5us dq=0; //拉低总线 delayus(30);

dq=1; //释放总线 delayus(3);

k=dq; // 对数据较采样 delayus(25);

return k; //根据K值判断da18b20是否损坏 }

////写数据到ds18b20//

void ds18b20_writedate(uchar date) {

uchar num;

for(num=0;num<8;num++) {

dq=0; // 拉低总线,产生写信号 delayus(4);

dq=date&0x01; //发送一位数据 date>>=1; // 准备下一位数据传送 delayus(4); //延时4us

dq=1; // 释放总线,等待总线恢复 }

delayus(4); }

///从ds18b20中读数据/// uchar ds18b20_readdate() {

uchar value,i;

for(i=0;i<8;i++)//读8位 {

dq=0; ///拉低总线,产生读信号 delayus(4);

value>>=1; // 准备读温度 delayus(4);

dq=1; //释放总线,准备读数据 if(dq) // 读数据 value|=0x80;

delayus(6); // 延时 }

return value; ///返回独到的数据 }

///ds18b20初始化以及数据处理// uint read_temp()

单片机89C52 ,液晶LCD12864,ADC0809,温度传感器DS18B20

{

uint g,d,m; uint c; m=1;

m=ds18b20_reset();//复位检测ds18b20正常工作,m=0 while(m); //等待复位完成

ds18b20_writedate(0xcc);//跳过rom

ds18b20_writedate(0x44);//启动温度测量,写暂存器 delayus(100);

m=ds18b20_reset();

while(m); //等待转化完成

ds18b20_writedate(0xcc);//跳过rom

ds18b20_writedate(0xbe);//读ds18b20温度暂存器命令 d=ds18b20_readdate();//读低8位数据 g=ds18b20_readdate(); //读高3位数据 g<<=4; //数据转换处理程序

g=g+(d>>4); //整数部分 g=g*100;

d=(d&0x0f)*0.0625*100; c=g+d;

return c; }

///温度转换显示子程序// void write_temp(uint temp) {

12864_writecom(0x88+3); //显示地址指针

12864_writedat(0x30+temp%10000/1000);//写数据最高位(十位) 12864_writedat(0x30+temp%1000/100); //写个位 12864_writedat('.'); //写小数点 12864_writedat(0x30+temp%100/10); //小数位 12864_writedat(0x30+temp%10); }

///中断初始化程序// void init() {

count=0;

TMOD=0x21; TH1=0xfd; TL1=0xfd;

TH0=(65536-50000)/256; //设定时器0初值 TL0=(65536-50000)%256;

单片机89C52 ,液晶LCD12864,ADC0809,温度传感器DS18B20

SM0=0; SM1=1; TR1=1; REN=1; TR0=1; ET0=1; ES=1;

EA=1; 开中断 }

//开定时器0中断1,在液晶上显示温度// void timer0() interrupt 1 {

TH0=(65536-50000)/256; TL0=(65536-50000)%256; count++;

if(count>=18) {

t=read_temp(); write_temp(t); count=0; } }

void ses() interrupt 4 {

TI=0; ET0=0;

if(flag==4) flag=0; switch(flag) {

case 0: SBUF=50; delay(5); break;

case 1: SBUF=t/100;delay(5); break; case 2: SBUF=t%100;delay(5); break; case 3: SBUF=40; delay(5); break; default: flag=0; }

flag++; delay(50); ET0=1; }

2、LCD12864的显示程序

#include<reg52.h> #include <intrins.h>

单片机89C52 ,液晶LCD12864,ADC0809,温度传感器DS18B20

#define uchar unsigned char #define uint unsigned int sbit lcd_en=P1^2; sbit lcd_rs=P1^4; sbit lcd_rw=P1^3; ///sbit lcd_psb=P3^6; void init_12864(void);

void 12864_writecom(uchar com); void 12864_writedat(uchar dat);

void write_12864com(uchar com)//写指令函数 {

lcd_rs=0; lcd_rw=0; lcd_en=0;

P2=com; //P2口传送数据 delay(5); lcd_en=1; delay(5); lcd_en=0; }

void write_12864dat(uchar date)//写数据函数 {

lcd_rs=1; lcd_rw=0; lcd_en=0; P2=date; delay(5); lcd_en=1; delay(5); lcd_en=0; }

void init_12864()//初始化液晶 {

//lcd_psb=1;

write_12864com(0x30); delay(5);

write_12864com(0x0c); delay(5);

write_12864com(0x01); delay(5); }

void write_temp(uint temp)//显示温度 {

单片机89C52 ,液晶LCD12864,ADC0809,温度传感器DS18B20

write_12864com(0x88+4);

write_12864dat(0x30+temp%10000/1000); write_12864dat(0x30+temp%1000/100); write_12864dat('.');

write_12864dat(0x30+temp%100/10); write_12864dat(0x30+temp%10); }

void main() //主函数 { uchar i; SBUF=0;

init_12864();///初始化液晶

12864_writecom(0x0c);//关显示显示游标地址加1 while(1)

{ 12864_writecom(0x80); //写数据入口地址,液晶第一行显示 for(i=0;i<16;i++) {

uchar table1[]="单片机课程设计 "; 12864_writedat(table1[i]); }

12864_writecom(0x90); //液晶第二行入口地址 for(i=0;i<16;i++) {

uchar table1[]="徐新丽 张燕"; 12864_writedat(table1[i]); }

12864_writecom(0x88); //液晶第三行入口地址 for(i=0;i<16;i++) {

uchar table1[]="温度: C"; 12864_writedat(table1[i]); }

init(); //中断初始化 }

四、 总结

1、复位开关焊接前需要测试一下使用的两端是否有效,否则会导致电源与地短路,烧坏电路。焊接时,因为没有仔细检查,后上电前用万用表查出焊错了,还好没有导致严重后果,改正之后可正常使用。

2、焊接前需要对照ds18b20的三个引脚标号,电源与地不能接反。检查电路时查出接反,改正之后能正常工作。

单片机89C52 ,液晶LCD12864,ADC0809,温度传感器DS18B20

3、编程序时需要查看DS18B20以及LCD12864的数据手册,对照手册上的内容进行编程。初始化以及写数据读数据的程序一般为固定模式,对照数据手册以及系统功能,初始化系统;显示数据时要先对读进的数据进行数据处理,否则不能直接得到温度值。

4、在LCD12864上显示中文字时,每个汉字占两位,所以在设置中文时要注意空格的位数,否则会出现乱码,不显示汉字。调试程序时就遇到了这个问题;编程前最好在网上搜查这两个器件的一些注意点,少走歪路。 5、调试成功后,在液晶上显示“单片机课程设计” 成员姓名“..........” 当前温度显示 “温度: **** ” 实物如下图所示。

正面:

反面:

单片机89C52 ,液晶LCD12864,ADC0809,温度传感器DS18B20

五、致谢

本设计历时两星期,通过前期的收集、查阅资料,了解DS18B20的一些特性以及基本用法,确定单片机型号STC89C52;设计电路,用PROTEL画电路原理图,购买器件,同时编写程序并调试;焊接电路,查看电路;最后用单片机驱动显示并调试。这里感谢....同学,显示出错时,及时帮助我们找出程序错误并改正,使液晶能够按照我们的想法与要求显示。同时感谢小组成员张燕同学,与她共同完成这些工作,相互学习,收获很多。

单片机89C52 ,液晶LCD12864,ADC0809,温度传感器DS18B20

附件1、

电路图:

单片机89C52 ,液晶LCD12864,ADC0809,温度传感器DS18B20

附件2:

#include<reg52.h> #include <intrins.h>

#define uchar unsigned char #define uint unsigned int

sbit lcd_en=P1^2; sbit lcd_rs=P1^4; sbit lcd_rw=P1^3; ///sbit lcd_psb=P3^6;

sbit dq=P1^1; uint t,s;

//void init(); ///////////////// uchar flag,count;

void delayus(uint z); void delay(uint z); void init_12864(void);

void write_12864com(uchar com); void write_12864dat(uchar dat);

void write_12864com(uchar com)//写指令函数 {

lcd_rs=0; lcd_rw=0; lcd_en=0; P2=com; delay(5); lcd_en=1; delay(5); lcd_en=0; }

void write_12864dat(uchar date)//写数据函数 {

lcd_rs=1;

单片机89C52 ,液晶LCD12864,ADC0809,温度传感器DS18B20

lcd_rw=0; lcd_en=0; P2=date; delay(5); lcd_en=1; delay(5); lcd_en=0; }

void init_12864()//初始化液晶 {

//lcd_psb=1;

write_12864com(0x30); delay(5);

write_12864com(0x0c); delay(5);

write_12864com(0x01); delay(5); }

void write_temp(uint temp) {

write_12864com(0x88+4);

write_12864dat(0x30+temp%10000/1000); write_12864dat(0x30+temp%1000/100); write_12864dat('.');

write_12864dat(0x30+temp%100/10); write_12864dat(0x30+temp%10); }

void delay(uint z) {

uint x,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--); }

void delayus(uint z) {

uchar i;

for(i=0;i<z;i++); }

uchar clean_ds18b20() {

uchar k; dq=1;

单片机 温度计DS18B20.doc 将本文的Word文档下载到电脑

    精彩图片

    热门精选

    大家正在看

    × 游客快捷下载通道(下载后可以自由复制和排版)

    限时特价:7 元/份 原价:20元

    支付方式:

    开通VIP包月会员 特价:29元/月

    注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
    微信:fanwen365 QQ:370150219