数字温度计设计报告.docx

上传人:b****7 文档编号:9939143 上传时间:2023-02-07 格式:DOCX 页数:25 大小:370.83KB
下载 相关 举报
数字温度计设计报告.docx_第1页
第1页 / 共25页
数字温度计设计报告.docx_第2页
第2页 / 共25页
数字温度计设计报告.docx_第3页
第3页 / 共25页
数字温度计设计报告.docx_第4页
第4页 / 共25页
数字温度计设计报告.docx_第5页
第5页 / 共25页
点击查看更多>>
下载资源
资源描述

数字温度计设计报告.docx

《数字温度计设计报告.docx》由会员分享,可在线阅读,更多相关《数字温度计设计报告.docx(25页珍藏版)》请在冰豆网上搜索。

数字温度计设计报告.docx

数字温度计设计报告

数字温度计实验报告

一,实验目的

1.学习80C52单片机的部的定时器及各接口的功能及应用。

2.设计任务及要求利用实验平台上LED数码管和蜂鸣器设计具有最低、最高温度查询,实时显示和报警功能的数字温度器。

二,实验要求

基本要求:

1:

能够实时显示环境温度。

2:

能够保存使用时间的最大值和最小值,能够查阅。

3:

有温度报警功能,能够设置报警温度。

用绿灯表示正常温度,红灯表示报警同时发声。

扩展功能:

查询最低和最高温度时,指示灯蓝灯和黄灯分别表示当前先显示的是高温还是低温。

三,实验基本原理

利用单片机定时器完成报警检测功能。

每隔一段时间定时器0对当前温度值进行检测,当超过设定温度30度时红灯亮并发生报警。

为了将时间在LED数码管上显示当前温度,采用动态显示法,由于静态显示法需要译码器,数据锁存器等较多硬件,可采用动态显示法实现LED显示,通过对每位数码管的依次扫描,使对应数码管亮,同时向该数码管送对应的字码,使其显示数字。

由于数码管扫描周期很短,由于人眼的视觉暂留效应,使数码管看起来总是亮的,从而实现了各种显示。

该设计采用四按键输入,当按键1

(2)按下,可分别查看当前最低(最高)温度。

四,实验设计分析

针对要实现的功能,采用AT89S52单片机和ds18b20温度传感器进行设计,AT89S52单片机是一款低功耗,高性能CMOS8位单片机,它有以下特点:

1、拥有灵巧的8位CPU和在系统可编程Flash

2、晶片部具时钟振荡器(传统最高工作频率可至12MHz)

3、部程序存储器(ROM)为8KB

4、部数据存储器(RAM)为256字节

5、32个可编程I/O口线

6、8个中断向量源

7、三个16位定时器/计数器

8、三级加密程序存储器

9、全双工UART串行通道

Ds18b20管脚图为:

ds18b20管脚图

DS18B20的引脚功能:

DQ为数字信号输入/输出端;GND为电源地;VDD为外接供电电源输入端(在寄生电源接线方式时接地。

它具有如下特点:

(1)独特的单线接口方式:

DS18B20与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯。

(2)在使用中不需要任何外围元件。

(3)可用数据线供电,电压围:

+3.0~+5.5V。

(4)测温围:

-55~+125℃。

固有测温分辨率为0.5℃。

(5)通过编程可实现9~12位的数字读数方式。

(6)用户可自设定非易失性的报警上下限值。

(7)支持多点组网功能,多个DS18B20可以并联在惟一的三线上,实现多点测温。

(8)负压特性,电源极性接反时,温度计不会因发热而烧毁,但不能正常工作。

在程序方面,采用分块设计的方法,这样既减小了编程难度、使程序易于理解,又能便于添加各项功能。

程序可分为温度获取程序,中断程序,显示程序,延时程序等。

运用这种方法,关键在于各模块的兼容和配合,若各模块不匹配会出现意想不到的错误。

首先,在编程之前必须了解硬件结构尤其是各引脚的用法,以及部寄存器、存储单元的用法,否则,编程无从下手,电路也无法设计。

这是前期准备工作。

第二部分是硬件部分:

依据想要的功能分块设计设计,比如输入需要开关电路,输出需要蜂鸣器,led灯和数码管电路等。

第三部分是软件部分:

先学习理解汇编语言的编程方法再根据设计的硬件电路进行分块的编程调试,最终完成程序设计。

第四部分是软件画图部分:

设计好电路后进行画图,包括电路图和仿真图的绘制。

第五部分是软件仿真部分:

软硬件设计好后将软件载入芯片中进行仿真,仿真无法完成时检查软件程序和硬件电路并进行修改直到仿真成功。

第六部分是硬件实现部分:

连接电路并导入程序检查电路,若与设计的完全一样一般能实现想要的功能。

最后进行功能扩展,在已经正确的设计基础上,添加额外的功能!

五,实验要求实现

A.电路设计

1.整体设计

此次设计主要是应用单片机来设计数字温度计,硬件部分主要分以下电路模块:

输出电路用8个共阴数码管、四个led灯和蜂鸣器显示,键盘进行温度设置报警温度。

电路的总体设计框架如下:

 

2.分块设计

模块电路主要分为:

输入部分、输出部分、及温度读取电路。

2.1输入部分

输入部分

外电路输入部分主要用于查询当前最低和最高温度。

KEY1\KEY2分别控制最低和最高温度的显示。

2.2输出部分

输出部分

本电路的输出信号为7段数码管的位选和段选信号,蜂鸣器信号,提示灯信号。

本实验的数码管是共阴的,为了防止段选信号不能驱动数码管,故在P1口连接上拉电阻后,再送段选信号,以提高驱动,位选信号直接从P2口接入。

程序将获得的温度实时地显示在数码管上;当温度超过设定的数值时,红灯亮,蜂鸣器响。

当查询最低温度时,蓝灯亮,最高温度时绿灯亮。

晶振与复位电路

本实验单片机时钟用部时钟,模块如下:

温度检测模块:

DQ接P1.0,用于单总线传送。

温度读取模块主程序如下:

sendChangeCmd();

tempValue1=getTmpValue();

temp=abs(tempValue1);

tempL=(tempL>temp?

temp:

tempL);

tempH=(tempH

temp:

tempH);

if(KEY1==0){temp=tempL;

test1=0;EA=0;

while(j--)display();

EA=1;

}

if(KEY2==0){

temp=tempH;

test2=0;EA=0;

while(j--)display();

EA=1;}

报警检测设定在中断定时器0中:

voidtimer0()interrupt1//中断,温度高于3000,就报警

{intk=30;

if(temp>3000){while(k--){beeping();

//beep=0;

led=0;}

}

else{led=1;beep=1;}

display();

TH0=th0;

TL0=tl0;

}

各模块拼接组合,电路总体设计图如下:

 

B.程序设计

B.1程序主要模块

中断服务程序

voidtimer0()interrupt1//中断,温度高于3000,就报警

{intk=30;

if(temp>3000){while(k--){beeping();

//beep=0;

led=0;}

}

else{led=1;beep=1;}

display();

TH0=th0;

TL0=tl0;}

B.2主程序

定时器初始化

温度转换启动

主循环(温度转换->温度处理—>报警检测)

voidmain()

{//dio=0;

Init_timer0();

/*dispbuf[5]=0xf;

dispbuf[4]=0xf;

dispbuf[3]=0xf;

dispbuf[2]=0;

dispbuf[1]=0;

dispbuf[0]=0;*/

sendChangeCmd();

tempValue1=getTmpValue();

temp=abs(tempValue1);

tempL=temp;

tempH=temp;

KEY5=0;

while

(1)

{uintj=200,k=1000;

//启动温度转换

sendChangeCmd();

tempValue1=getTmpValue();

temp=abs(tempValue1);

//if(temp>10000){while(k--)beeping();

//beep=0;

//led=0;

//}

//temp=getTmpValue();

tempL=(tempL>temp?

temp:

tempL);

tempH=(tempH

temp:

tempH);

if(KEY1==0){temp=tempL;

test1=0;EA=0;

while(j--)display();

EA=1;

}

if(KEY2==0){

temp=tempH;

test2=0;EA=0;

while(j--)display();

EA=1;}

}

}

B.3显示子程序

8个数码管轮流进行显示,分别显示1ms,依赖人的视觉暂留效应,给人以数码管持续高亮的错觉。

该段程序如下:

voiddisplay()

{uchartmp;

uchartmp1;

staticucharcount;

P3=0XFF;

tmp=dispbit[count];

tmp1=tmp;

P3&=tmp;

//we=0;/////////////////WEI操作

//du=1;//////////////////duan操做

tmp=dispbuf[5-count];

if(tmp1==0xf7)

{tmp=disptabwithdot[tmp];}

else

{tmp=disptab[tmp];}

P0=tmp;

count++;

if(count==6)

{count=0;}

//unsignedinttemp=abs(tempValue);

dispbuf[0]=temp/10000;

dispbuf[1]=temp%10000/1000;

dispbuf[2]=temp%1000/100;

dispbuf[3]=temp%100/10;

dispbuf[4]=temp%10;

//TH0=th0;

//TL0=tl0;

}

程序调试

本程序通过Keil单片机开发平台实现程序的编译,,生成HEX文件。

程序再编译过程中可以发现错位,并及时改正,在设计时非常重要,使错误被扼杀在摇篮中。

通过Keil和硬件仿真平台Proteus的联合,可以将设计效果仿真出来,根据效果,有目的的改变设计,优化程序。

c.利用Keil软件实验过程截图:

c.1汇编程序,并生成HEX文件

c.2利用下载线将文件调入电路板调试,运行结果如下:

下图为温度实时显示结果:

下图为温度报警结果:

D电路板连接实现

通过软,硬件设计和仿真,基本上实现了自己想要的功能,就可以真刀真枪的干一场了。

软件通过调试基本上是没问题的,但是硬件仿真过于泛泛,对电路的细节要求不是那么高,有些问题是不能发现的,最后的实现效果还是要用实物来验证的。

元器件的购买是个苦活,虽然中发市场那么大,但那些元件才是我要的那个它呢?

我们购买的量少,对于那些元器件厂家来说,根本不屑做我们的生意,根本不用说砍价了。

经过一番“跋涉”,终于搜刮齐了元器件。

根据以往经验,焊接电路的布线非常重要,首先要在电路板上将线的大致走向规划好,如何美观,精简是要领。

一下是本次试验的硬件电路实现

五.实验总结及感想

通过这几周的软、硬件设计,不仅加深了我们对理论知识的理解,培养了我们的实践动手能力,还锻炼了我们遇到问题解决问题的能力。

从开始接到任务时的无从下手,到小组成员各司其职,搜集资料,学习新知识,相互讨论,分析交流,解决好问题的这个过程本身就是对我们的锻炼。

此次设计课不同于一般理论课的地方就在于要求我们的并非只是单纯的懂得理论知识,更重要的是小组成员间的团结协作精神以及将理论知识用于实践的能力,由于在实际中,存在各种各样的因素,即使我们有着正确的原理图、软件程序等也不一定能得出正确的结果,正如调试时产生的问题一样,这就需要我们有耐心去分析各种可能存在因素以达到解决问题的最终目的,当然这其中肯定少不了老师的指导和帮助。

这次真得要感谢我们组组长和小组成员,几周以来,我们共同度过了很多困难的时光,也共同收获了很多。

通过这次课程设计我们学到了很多东西,培养了我们的自学能力,接受新事物的心态,以及遇到问题时戒骄戒躁的良好心态和虚心向同学、老师请教自己不会的问题,更重要的是小组成员间的团结协作,相互鼓励,做好分配给自己的任务,用心做每一件事而非应付过关的消极态度。

从最初的连线到最终程序的不断,排错,改进,大家的能力真得提高了不少。

总之,此次设计课使我们受益匪浅。

 

附:

总程序

#include

#include//要用到取绝对值函数abs()

#defineucharunsignedchar

#defineuintunsignedint

sbitKEY1=P2^4;

sbitKEY2=P2^5;

sbitKEY3=P2^6;

sbitKEY4=P2^7;

sbitKEY5=P2^3;

sbittest1=P3^6;

sbittest2=P3^7;

sbitbeep=P1^5;

sbitled=P1^2;

//sbitdu=P2^6;

//sbitdio=P2^5;

sbitds=P1^0;

//sbitds=P2^2;

inttempValue1;

unsignedinttemp;

unsignedinttempH;

unsignedinttempL;

ucharcodeth0=(65535-3000)/256;

ucharcodetl0=(65535-3000)%256;

uchardispbuf[6];

ucharcodedisptab[]={0x3f,0x6,0x5b,0x4f,0x66,

0x6d,0x7d,0x27,0x7f,0x6f,0x77,0x7c,0x39,0x5e,

0x79,0x71,0x0};

ucharcodedisptabwithdot[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0xa7,0xff,0xef,0xf7,

0xfc,0xb9,0xf9,0xf1};

ucharcodedispbit[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};

//11111110,11111101,11111011,11110111,11101111,11011111;

//延时函数,对于11.0592MHz时钟,例i=10,则大概延时10ms.

voiddisplay();

voidbeeping();

voiddelay(unsignedinti)

{

unsignedintj;

while(i--)

{

for(j=0;j<125;j++);

}

}

voiddsInit()

{

//对于11.0592MHz时钟,unsignedint型的i,作一个i++操作的时间大于1us

unsignedinti;

ds=0;

i=100;//拉低约800us,符合协议要求的480us以上

while(i>0)i--;

ds=1;//产生一个上升沿,进入等待应答状态

i=4;

while(i>0)i--;

}

voiddsWait()

{

unsignedinti;

while(ds);

while(~ds);//检测到应答脉冲

i=4;

while(i>0)i--;

}

//向DS18B20读取一位数据

//读一位,让DS18B20一小周期低电平,然后两小周期高电平,

//之后DS18B20则会输出持续一段时间的一位数据

bitreadBit()//读0时序

{

unsignedinti;

bitb;

ds=0;

i++;//延时约8us,符合协议要求至少保持1us

ds=1;

i++;i++;//延时约16us,符合协议要求的至少延时15us以上

b=ds;

i=8;

while(i>0)i--;//延时约64us,符合读时隙不低于60us要求

returnb;

}

//读取一字节数据,通过调用readBit()来实现

unsignedcharreadByte()

{

unsignedinti;

unsignedcharj,dat;

dat=0;

for(i=0;i<8;i++)

{

j=readBit();

//最先读出的是最低位数据

dat=(j<<7)|(dat>>1);//先把数据放在高位,然后再移到低位

}

returndat;

}

//向DS18B20写入一字节数据

voidwriteByte(unsignedchardat)

{

unsignedinti;

unsignedcharj;

bitb;

for(j=0;j<8;j++)

{

b=dat&0x01;

dat>>=1;

//写"1",将DQ拉低15us后,在15us~60us将DQ拉高,即完成写1

if(b)

{

ds=0;

i++;i++;//拉低约16us,符号要求15~60us

ds=1;

i=8;while(i>0)i--;//延时约64us,符合写时隙不低于60us要求

}

else//写"0",将DQ拉低60us~120us

ds=0;

i=8;while(i>0)i--;//拉低约64us,符号要求

ds=1;

i++;i++;//整个写0时隙过程已经超过60us,这里就不用像写1那样,再延时64us了

}

}

//向DS18B20发送温度转换命令

voidsendChangeCmd()

{

dsInit();//初始化DS18B20,无论什么命令,首先都要发起初始化

dsWait();//等待DS18B20应答

delay

(1);//延时1ms,因为DS18B20会拉低DQ60~240us作为应答信号

writeByte(0xcc);//写入跳过序列号命令字SkipRom

writeByte(0x44);//写入温度转换命令字ConvertT

}

//向DS18B20发送读取数据命令

voidsendReadCmd()

{EA=0;//关闭中断是因为进入显示中断会影响到DS18B20的读写时序

dsInit();

dsWait();

delay

(1);

writeByte(0xcc);//写入跳过序列号命令字SkipRom

writeByte(0xbe);//写入读取数据令字ReadScratchpad

EA=1;

}

//获取当前温度值

intgetTmpValue()

{

unsignedinttmpvalue;

intvalue;//存放温度数值

floatt;

unsignedcharlow,high;

EA=0;

sendReadCmd();

//连续读取两个字节数据

low=readByte();

high=readByte();

//将高低两个字节合成一个整形变量

//计算机中对于负数是利用补码来表示的

//若是负值,读取出来的数值是用补码表示的,可直接赋值给int型的value

tmpvalue=high;

tmpvalue<<=8;

tmpvalue|=low;

value=tmpvalue;

//使用DS18B20的默认分辨率12位,精确度为0.0625度,即读回数据的最低位代表0.0625度

t=value*0.0625;

//将它放大100倍,使显示时可显示小数点后两位,并对小数点后第三进行4舍5入

//如t=11.0625,进行计数后,得到value=1106,即11.06度

//如t=-11.0625,进行计数后,得到value=-1106,即-11.06度

value=t*100+(value>0?

0.5:

-0.5);//大于0加0.5,小于0减0.5

returnvalue;

EA=1;

}

 

voidInit_timer0()

{

TMOD=0x01;

TH0=th0;

TL0=tl0;

EA=1;

ET0=1;

TR0=1;

}

voidtimer0()interrupt1

{intk=30;

if(temp>3000){while(k--){beeping();

//beep=0;

led=0;}

}

else{led=1;beep=1;}

display();

TH0=th0;

TL0=tl0;

}

voiddisplay()

{

uchartmp;

uchartmp1;

staticucharcount;

P3=0XFF;

tmp=dispbit[count];

tmp1=tmp;

P3&=tmp;

//we=0;/////////////////WEI操作

//du=1;//////////////////duan操做

tmp=dispbuf[5-count];

if(tmp1==0xf7)

{

tmp=disptabwithdot[tmp];

}

else

{

tmp=disptab[tmp];

}

P0=tmp;

count++;

if(count==6)

{

count=0;

}

//unsignedinttemp=abs(tempValue);

dispbuf[0]=temp/10000;

dispbuf[1]=temp%10000/1000;

dispbuf[2]=temp%1000/100;

dispbuf[3]=temp%100/10;

dispbuf[4]=temp%10;

//TH0=th0;

//TL0=tl0;

}

voidbeeping()

{

beep=0;

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

//beep=1;

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1