单片机原理与运用课程设计课题名称:专业班级:学生姓名:指导老师:完成时间:温度采集与显示系统2012年7月4号摘要随着信息技术的飞速发展,嵌入式智能电子技术已渗透到社会生产、工业控制以及人们日常生活的各个方面。
单片机又称为嵌入式微型控制器,在智能仪表、工业控制、智能终端、通信设备、医疗器械、汽车电器、导航系统和家用电器等很多领域都有着广泛的应用,已成为当今电子信息领域应用最广泛的技术之一。
本文主要介绍了一个基于STC89C52单片机的温度采集与显示系统,详细描述了利用液晶显示器件温度传感器DS18B20开发测温系统的原理,重点对传感器与单片机的硬件连接和软件编程进行了详细分析。
主要地介绍了数字温度传感器DS18B20的数据采集过程,进而对各部分硬件电路的工作原理进行了介绍。
温度传感器DS18B20与STC89C52结合构成了最简温度检测系统,该系统可以方便的实现温度采集和显示,它使用起来相当方便,具有精度高、量程宽、灵敏度高、体积小、功耗低等优点,适合我们日常生活和工、农业生产中的温度测量,也可以当作温度处理模块嵌入其它系统中,作为其他主系统的辅助扩展。
单片机综合实验的目的是训练单片机应用系统的编程及调试能力,通过对一个单片机应用系统进行系统的编程和调试,掌握单片机应用系统开发环境和仿真调试工具及仪器仪表的实用,掌握单片机应用程序代码的编写和编译,掌握利用单片机硬件仿真调试工具进行单片机程序的跟踪调试和排错方法,掌握示波器和万用表等杆塔工具在单片机系统调试中应用。
关键词:单片机STC89C52、DS18B20温度传感器、液晶显示器LCD1602、AT24C02数据存储芯片目录一、绪论------------------------------------------41.1 、温度检测系统的介绍------------------------------41.2、温度检测的实际意义------------------------------41.3、设计内容及功能要求------------------------------4二、系统硬件部分---------------------------------52.1、单片机最小系统----------------------------------52.2、温度采集电路-----------------------------------52.3、LCD1602显示电路-------------------------------62.4、数据存储电路-----------------------------------72.5、报警电路--------------------------------------72.6、按键中断电路-----------------------------------8三、总电路图(仿真)----------------------------8四、系统软件部分---------------------------------94.1、程序流程图:-----------------------------------94.2、主程序(main.c)-------------------------------104.3、24c02.c-------------------------------------144.4、ds18b20.c-----------------------------------154.5、lcd.c---------------------------------------194.6、I2C.c---------------------------------------214.7、function.c-----------------------------------24五、元器件清单----------------------------------25六、安装与调试----------------------------------276.1、电路参数的选取与安装---------------------------276.2调试-----------------------------------------27七、总结-----------------------------------------28一、绪论1.1 、温度检测系统的介绍温度检测在各领域应用的非常广泛,可以说渗透到了社会的每一个领域。
人们的生活与温度检测息息相关,在工业生产过程中需要实时测量温度,在农业生产中也离不开温度的测量,因此研究温度的测量方法和装置具有重要的意义。
通过DS18B20采集温度数据,经I/O口传给单片机,单片机对接收到的数据进行实时在lcd上显示,并十秒采集通过I2C总线送到24c02进行储存,当按键按下时进入外部中断,并在外部中断中进行读取24c02所保存的值并在lcd上显示;拓展功能部分:在lcd的第二行显示时钟,并配有按键进行调时;温度报警电路,当温度上升到一定值时给蜂鸣器低信号,使其响起。
1.2、温度检测的实际意义在工业生产和实践研究中,像电力、化工、石油、冶金、航空航天、机械制造、粮食存储、酒类生产等领域,温度常常是表征对象和过程状态的重要参数之一。
比如,发电厂锅炉的温度必须控制在一定的范围之内;许多化学反应的工艺过程必须在适当的温度下才能正常进行;炼油过程中,原油必须在不同的温度和压力条件下进行分馏才能得到汽油、柴油、煤油等产品。
没有合适的温度环境,许多电子设备就不能正常工作,粮仓的储粮就会变质霉烂,酒类的品质就没有保障。
由此可见,温度的检测对日常生活很重要。
1.3、设计内容及功能要求利用STC89C52、DS18B20、LCD1602、AT24C02等元器件设计温度采集与显示系统。
系统具有以下功能:1、能正确检测温度;2、在1602上实时显示温度;3、每隔10秒采集一次温度数据并保存到AT24C024、按键按下后,可逐个显示之前采集到的数据;5、其他功能可根据系统上的资源自行设定。
扩展功能:温度超过设定值,蜂鸣器报警;时间日期的显示;按键按下,重新开始采集温度等等。
二、系统硬件部分2.1、单片机最小系统单片机是指一个集成在一块芯片上的完整计算机系统。
它具有一个完整计算机所需要的大部分部件:CPU、内存、内部和外部总线系统。
同时集成诸如通讯接口、定时器,实时时钟等外围设备。
在内部ROM中载入程序既可以实现对其的操作控制。
我们使用了AT89S52这款单片机,它具有内部ROM空间大,工作速度快等优点,便于以后的升级扩展。
现在主流的MCS-51单片机要想正常工作必须配备复位和时钟电路,复位脚必需在振荡器起振后至少保持两个机器周期复位电平。
也就是说,复位脚(RST)复位电平保持时间应包含VCC的建立时间、振荡器起振时间和至少两个机器周期时间。
本次设计采用最基本的上电复位电路。
另外的时钟电路则为整个系统提供了系统的时基,主要有一个晶振来起振,另外两个电容可以增强时钟电路的稳定性。
图2.1为单片机最小系统电路:图2.1:单片机最小系统电路2.2、温度采集电路温度传感器的种类众多,在高精度、高可靠性的应用场合时DALLAS(达拉斯)公司生产的DS18B20温度传感器比较理想。
它体积小,硬件开消低,抗干扰能力强,精度高,附加功能强。
与传统的热敏电阻等测温元件相比,它能直接读出被测温度,并且可根据实际要求通过简单的编程实现9~12位的数字值读数方式。
它具有独特的单线接口仅需要一个端口引脚进行通信,并可通过数据线供电,电压范围为3.0~5.5V。
采用单总线数字温度传感器DS18B20测量温度。
因为它直接输出数字信号,便于单片机进行处理及控制,同时也节省了硬件电路。
该芯片的物理化学性质很稳定,元件线形性能好。
当温度在0—100摄氏度范围内变化时,最大线形偏差小于1摄氏度。
图2.2为温度采集电路:图2.2:温度采集电路2.3、LCD1602显示电路采用液晶显示器件。
液晶显示具有平稳、省电、美观等优点,更容易满足题目要求。
而且对后续的工艺兼容性高,只需将修改软件中程序设计即可,可操作性强,也易于读数。
LCD1602液晶显示器具有两行十六个字符的显示,能同时显示其它的信息如日期、时间、星期、温度。
图2.3为LCD1602显示电路:图2.3:LCD1602显示电路2.4、数据存储电路AT24C02支持I2C,总线数据传送协议I2C,总线协议规定任何将数据传送到总线的器件作为发送器。
任何从总线接收数据的器件为接收器。
数据传送是由产生串行时钟和所有起始停止信号的主器件控制的。
主器件和从器件都可以作为发送器或接收器,但由主器件控制传送数据(发送或接收)的模式,由于A0、A1和A2可以组成000~111八种情况,即通过器件地址输入端A0、A1和A2可以实现将最多8个AT24C02器件连接到总线上,通过进行不同的配置进行选择器件。
选用这样的数据存储器件是比较合适的。
图2.4为数据存储电路图:图2.4:数据存储电路2.5、报警电路报警电路较为简单,只要由蜂鸣器组成,主要器件也是蜂鸣器。
蜂鸣器有正负端口,我在设计电路的时候将蜂鸣器的正端接+5V 的电源,另一端接到单片机的p1.0口,只要单片机在这个口输出低电平,则蜂鸣器接通后产生蜂鸣。
图2.5为报警电路图:图2.5:蜂鸣器报警电路2.6、按键中断电路在本次设计中我选用四个按键来控制温度显示中的一些步骤。
首先,采用一个中断来控制对AT24C02的锁存储数据的读取,然后显示在LCD1602上。
每按一次第一个按键所读取的温度不同。
其他三个按键为时间调整按键,可以通过这三个按键对液晶屏里面的时钟进行时间调整。
图 2.6为按键中断电路图:图2.6:按键中断电路三、总电路图(仿真)四、系统软件部分4.1、程序流程图:图4.1温度采集程序图图4.2按键中断程序图4.2、主程序(main.c)#include<reg52.h>#include<function.h>#define warn_35 350#define warn_11 110char miao,shi,fen,flag;uint s1num;ucharcount,m,n;uintsu,tt,mm;//uchar buff[4];unsigned char pDat[7],pDat1[7];sbit s1=P3^4;sbit s2=P3^5;sbit s3=P3^6;sbit beep=P1^0;//蜂鸣器void deal(uint tem){if((tem>warn_35)||(tem<warn_11)){beep=0;}else beep=1;}void main(){m=0;n=0;init();EX0=1;//init_com(); //包含了对定时器0的设定while(1){tempchange();tt=get_temp();if(flag==1){EA=0;flag=0;IRcvStr(0xa0,n,&pDat1[0],8);mm=pDat1[0]*100+pDat1[1]*10+pDat1[2];//pDat1[7]=0;n=n+0x08;if(n==0xf8)n=0;EA=1;}deal(tt);write_sfm(12,miao);write_sfm(9,fen);// write_sfm(6,shi);dis_temp1(mm);delay(5);dis_temp(tt);keyscan();}}void int_0() interrupt 0{flag=1;}void keyscan(){if(s1==0){delay(5);if(s1==0){ s1num++;while(!s1);if(s1num==1){TR0=0;write_com(0x80+0x40+12);//write_com(0x0f);}}if(s1num==2){write_com(0x80+0x40+9);}if(s1num==3){write_com(0x80+0x40+6);}if(s1num==4){s1num=0;write_com(0x0c);TR0=1;}}if(s1num!=0){if(s2==0){delay(5);if(s2==0){while(!s2);if(s1num==1){miao++;if(miao==60)miao=0;write_sfm(12,miao);write_com(0x80+0x40+12);//指针回原位}if(s1num==2){fen++;if(fen==60)fen=0;write_sfm(9,fen);write_com(0x80+0x40+9);//指针回原位}if(s1num==3){shi++;if(shi==24)shi=0;write_sfm(6,shi);write_com(0x80+0x40+6);//指针回原位}}}if(s3==0){delay(5);if(s3==0){while(!s3);if(s1num==1){/* if(miao==0){miao=59;write_sfm(10,miao);write_com(0x80+0x40+10);}*/miao--;if(miao==-1)miao=59;write_sfm(12,miao);write_com(0x80+0x40+12);}if(s1num==2){fen--;if(fen==-1)fen=59;write_sfm(9,fen);write_com(0x80+0x40+9);}if(s1num==3){shi--;if(shi==-1)shi=23;write_sfm(6,shi);write_com(0x80+0x40+6);}}}}}void timer0() interrupt 1{TH0=(65536-50000)/256;TL0=(65536-50000)%256;su++;if(su==100){su=0;pDat[0]=tt/100;pDat[1]=(tt%100)/10;pDat[2]=tt%10;ISendStr(0xa0,m,&pDat[0],8); //存温度// pDat[7]=0;m=m+0x08;if(m==0xf8)m=0;}count++;if(count==20){count=0;miao++;if(miao==60){miao=0;fen++;if(fen==60){fen=0;shi++;if(shi==24){shi=0;}// write_sfm(4,shi);}//write_sfm(7,fen);}//write_sfm(10,miao);}}4.3、24c02.c#include<Function.h>bit ISendStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no){unsigned char i;Start_I2c(); /*启动总线*/SendByte(sla); /*发送器件地址*/if(ack==0) return(0);SendByte(suba); /*发送器件子地址*/if(ack==0)return(0);for(i=0;i<no;i++){SendByte(*s); /*发送数据*/if(ack==0)return(0);s++;}Stop_I2c(); /*结束总线*/return(1);}bit IRcvStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no){unsigned char i;Start_I2c(); /*启动总线*/ SendByte(sla); /*发送器件地址*/if(ack==0)return(0);SendByte(suba); /*发送器件子地址*/ if(ack==0)return(0);Start_I2c(); /*重新启动总线*/ SendByte(sla+1);if(ack==0)return(0);for(i=0;i<no-1;i++){*s=RcvByte(); /*发送数据*/Ack_I2c(0); /*发送就答位*/s++;}*s=RcvByte();Ack_I2c(1); /*发送非应位*/Stop_I2c(); /*结束总线*/return(1);}4.4、ds18b20.c#include <reg52.h>#include <stdio.h>#include<function.h>sbit ds=P1^1; //温度传感器信号线//sbit beep=P2^3; //蜂鸣器uint temp;float f_temp;void dsreset(void) //18B20复位,初始化函数{uinti;ds=0;i=103;while(i>0)i--;ds=1;i=4;while(i>0)i--;}bit tempreadbit(void) //读1位函数{uinti;bit dat;ds=0;i++; //i++ 起延时作用ds=1;i++;i++;dat=ds;i=8;while(i>0)i--;return (dat);}uchartempread(void) //读1个字节{uchari,j,dat;dat=0;for(i=1;i<=8;i++){j=tempreadbit();dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里}return(dat);}void tempwritebyte(uchardat) //向18B20写一个字节数据{uinti;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; //写 0i=8;while(i>0)i--;ds=1;i++;i++;}}}void tempchange(void) //DS18B20 开始获取温度并转换{dsreset();delay(1);tempwritebyte(0xcc); // 写跳过读ROM指令tempwritebyte(0x44); // 写温度转换指令}uintget_temp() //读取寄存器中存储的温度数据{uchara,b;dsreset();delay(1);tempwritebyte(0xcc);tempwritebyte(0xbe);a=tempread(); //读低8位b=tempread(); //读高8位temp=b;temp<<=8; //两个字节组合为1个字temp=temp|a;f_temp=temp*0.0625; //温度在寄存器中为12位分辨率位0.0625°temp=f_temp*10+0.5; //乘以10表示小数点后面只取1位,加0.5是四舍五入f_temp=f_temp+0.05;return temp; //temp是整型}////////////////////显示程序调用lcd中的write_sfm1 十位地址写4 个位为5 小数为7//////////////////////////void dis_temp(uint t){uinti;i=t/100;write_sfm1(0,i);i=(t%100)/10;write_sfm1(1,i);i=t%10;write_sfm1(3,i);}void dis_temp1(uint t) //显示储存的温度{uinti;i=t/100;write_sfm1(11,i);i=(t%100)/10;write_sfm1(12,i);i=t%10;write_sfm1(14,i);}/*void init_com(void){TMOD = 0x20;PCON = 0x00;SCON = 0x50;TH1 = 0xFd;TL1 = 0xFd;TR1 = 1;}void comm(char *parr){do{SBUF = *parr++; //发送数据 while(!TI); //等待发送完成标志为1TI =0; //标志清零}while(*parr); //保持循环直到字符为'\0'}*////////////////////////////////////////////////*void warn(uints,uchar led) //蜂鸣器报警声音 ,s控制音调{uchari;i=s;beep=0;P1=~(led);while(i--){dis_temp(get_temp());}beep=1;P1=0XFF;i=s;while(i--){dis_temp(get_temp());}}void deal(uint t){uchari;if((t>warn_l2)&&(t<=warn_l1)) //大于25度小于27度{warn(40,0x01);}else if(t<=warn_l2) //小于25度{warn(10,0x03);}else if((t<warn_h2)&&(t>=warn_h1)) //小于32度大于30度 {warn(40,0x04);}else if(t>=warn_h2) //大于32度{warn(10,0x0c);}else{i=40;while(i--){dis_temp(get_temp());}}}4.5、lcd.c#include <reg52.h>#include<function.h>sbitrs=P2^6;sbitlcden=P2^7;//sbitrw=P2^5;uchar code tablenum[]= "0123456789";uchar code table[]= "00.0C Temp:00.0C";uchar code table1[]="Time: 00:00:00";uchar code table2[]=" MADE BY";uchar code table3[]=" CaiGuo Sen";void delay(uint z){uintx,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void write_com(uchar com){rs=0;lcden=0;P0=com;delay(5);lcden=1;delay(5);lcden=0;}void write_date(uchardat){rs=1;lcden=0;P0=dat;delay(5);lcden=1;delay(5);lcden=0;}void init(){ucharnum;lcden=0;//rw=0;// fen=59;// miao=53;// shi=23;write_com(0x38);write_com(0x0c);write_com(0x06);write_com(0x01);write_com(0x80);for(num=0;num<12;num++){write_date(table2[num]);delay(5);}write_com(0x80+0x40);for(num=0;num<13;num++){write_date(table3[num]);delay(5);}delay(2000);write_com(0x80);for(num=0;num<16;num++){write_date(table[num]);delay(5);}write_com(0x80+0x40);for(num=0;num<12;num++){write_date(table1[num]);delay(5);}TMOD=0x01;TH0=(65536-50000)/256;TL0=(65536-50000)%256;EA=1;ET0=1;TR0=1;}void write_sfm(ucharadd,uchardat)//写地址和自动显示两位数时间{uchars,g;s=dat/10;g=dat%10;write_com(0x80+0x40+add);write_date(tablenum[s]);write_date(tablenum[g]);}void write_sfm1(ucharadd,uchardat) //写温度值十位地址写4 个位为5 小数为7{write_com(0x80+add);write_date(tablenum[dat]);}4.6、I2C.c#include<reg52.h>#include <intrins.h>#include<Function.h>#define NOP() _nop_() /* 定义空指令 */#define _Nop() _nop_() /*定义空指令*/sbit SCL=P2^1; //I2C 时钟sbit SDA=P2^0; //I2C 数据bit ack; /*应答标志位*/void Start_I2c(){SDA=1; /*发送起始条件的数据信号*/_Nop();SCL=1;_Nop(); /*起始条件建立时间大于4.7us,延时*/_Nop();_Nop();_Nop();_Nop();SDA=0; /*发送起始信号*/_Nop(); /* 起始条件锁定时间大于4μs*/_Nop();_Nop();_Nop();SCL=0; /*钳住I2C总线,准备发送或接收数据 */_Nop();_Nop();}void Stop_I2c(){SDA=0; /*发送结束条件的数据信号*/_Nop(); /*发送结束条件的时钟信号*/SCL=1; /*结束条件建立时间大于4μs*/_Nop();_Nop();_Nop();_Nop();_Nop();SDA=1; /*发送I2C总线结束信号*/_Nop();_Nop();_Nop();_Nop();}void SendByte(unsigned char c) {unsigned char BitCnt;for(BitCnt=0;BitCnt<8;BitCnt++) /*要传送的数据长度为8位*/ {if((c<<BitCnt)&0x80)SDA=1; /*判断发送位*/elseSDA=0;_Nop();SCL=1; /*置时钟线为高,通知被控器开始接收数据位*/ _Nop();_Nop(); /*保证时钟高电平周期大于4μs*/_Nop();_Nop();_Nop();SCL=0;}_Nop();_Nop();SDA=1; /*8位发送完后释放数据线,准备接收应答位*/_Nop();_Nop();SCL=1;_Nop();_Nop();if(SDA==1)ack=0;else ack=1; /*判断是否接收到应答信号*/SCL=0;_Nop();_Nop();}unsigned char RcvByte(){unsigned char retc;unsigned char BitCnt;retc=0;SDA=1; /*置数据线为输入方式*/for(BitCnt=0;BitCnt<8;BitCnt++){_Nop();SCL=0; /*置时钟线为低,准备接收数据位*/_Nop();_Nop(); /*时钟低电平周期大于4.7μs*/_Nop();_Nop();_Nop();SCL=1; /*置时钟线为高使数据线上数据有效*/_Nop();_Nop();retc=retc<<1;if(SDA==1)retc=retc+1; /*读数据位,接收的数据位放入retc中 */ _Nop();_Nop();}SCL=0;_Nop();_Nop();return(retc);}void Ack_I2c(bit a){if(a==0)SDA=0; /*在此发出应答或非应答信号 */ elseSDA=1;_Nop();_Nop();_Nop();SCL=1;_Nop();_Nop(); /*时钟低电平周期大于4μs*/_Nop();_Nop();_Nop();SCL=0; /*清时钟线,钳住I2C总线以便继续接收*/_Nop();_Nop();}4.7、function.c#define uchar unsigned char#define uint unsigned intextern void write_sfm(ucharadd,uchardat);extern void delay(uint z);extern void dsreset(void); //18B20复位,初始化函数extern bit tempreadbit(void); //读1位函数extern uchartempread(void); //读1个字节extern void tempwritebyte(uchardat); //向18B20写一个字节数据extern void tempchange(void); //DS18B20 开始获取温度并转换extern uintget_temp(); //读取寄存器中存储的温度数据extern void dis_temp(uint t);//显示程序extern void dis_temp1(uint t);//extern void warn(uints,uchar led); //蜂鸣器报警声音 ,s控制音调//extern void deal(uint t);//extern void init_com(void);//extern void comm(char *parr);extern void write_com(uchar com);extern void write_date(uchardat);extern void init();extern void write_sfm(ucharadd,uchardat);//写地址和自动显示两位数时间extern void write_sfm1(ucharadd,uchardat); //写温度值十位地址写4 个位为5 小数为7extern void keyscan();/****h函数声明部分***********/extern bit ack;//起动总线函数extern void Start_I2c();//结束总线函数extern void Stop_I2c();//应答子函数extern void Ack_I2c(bit a);//字节数据发送函数extern void SendByte(unsigned char c);//有子地址发送多字节数据函数extern bit ISendStr(unsigned char sla,unsigned char suba,unsigned char*s,unsigned char no) ;//无子地址发送多字节数据函数extern bit ISendStrExt(unsigned char sla,unsigned char *s,unsigned char no); //无子地址读字节数据函数extern unsigned char RcvByte();//有子地址读取多字节数据函数extern bit IRcvStr(unsigned char sla,unsigned char suba,unsigned char*s,unsigned char no);五、元器件清单六、安装与调试6.1、电路参数的选取与安装在确定了电路主要的器件之后,我们可以查阅参考文献确定具体的电路参数,具体如下:单片机选择AT89S52一片,单片机的复位电路需要22uf电容和1K电阻各一,时钟电路需要12M晶振一个60pf电容两个,测温电路只需要一个DS18B20和一个10K的电阻即可,显示电路只要一块LCD1602就可以完成显示任务。