课程设计报告温度计.docx
- 文档编号:3503239
- 上传时间:2022-11-23
- 格式:DOCX
- 页数:20
- 大小:473.82KB
课程设计报告温度计.docx
《课程设计报告温度计.docx》由会员分享,可在线阅读,更多相关《课程设计报告温度计.docx(20页珍藏版)》请在冰豆网上搜索。
课程设计报告温度计
合肥工业大学计算机学院
创新设计报告
设计题目:
温度计
专业:
电子信息科学与技术
班级:
10-01班
组长:
副组长:
组员:
2012年6月18日—2012年7月15日
摘要:
单片机系统使用数码管及矩阵键盘,通过DS18B20温度传感器采集到的温度数据,通过单片机的处理,再把它存储到存储器中,通过数码管来显示。
DS18B20是美国Dallas公司生产的单总线数字输出型集成温度传感器,能够直接读出被测温度值,并且可根据实际要求通过编程实现9~12位的数字量输出,将温度值转化为9位数字量所需时间为93.75ms,转化为12位数字量所需时间为750ms。
测试温度范围为-55~+125,精度可达0.0675℃。
关键字:
DS18B20温度传感器、数码管及矩阵键盘。
设计题目及要求:
1:
能够实时显示环境温度。
2:
能够保存使用时间内的最大值和最小值,能够查阅。
3:
有温度报警功能,能够设置报警温度。
用绿灯表示正常温度,红灯表示报警同时发声。
4:
自由发挥其他功能.
5:
要求有单片机硬件系统框图,电路原理图,软件流程图。
一、系统方案:
1、方案:
1)采集部分:
通过温度传感器将采集到的温度传输到单片机里处理
2)显示部分:
采用八位共阴数码管的动态扫描方式,将采集所得的结果显示在数码管上面。
3)控制部分:
通过矩阵键盘来控制各项功能,能够显示最大最小温度,并且能够报警
2、总体方案:
DS18B20传感器
二、单元电路:
1、单片机电路
2.传感器采集电路
3.数码管显示运算值的电路:
4、矩阵键盘电路:
三、算法原理:
1.主程序
主程序的主要功能是负责温度的实时显示、读出并处理DS18B20的测量的当前温度值。
2.温度检测程序
/********读温度***********/
uintread_wendu()
{
uchara,b;
uintt;
init_ds18b20();
write_byte(0xcc);//写跳过ROM指令
write_byte(0x44);//启动温度测量
delay_us(300);
init_ds18b20();
write_byte(0xcc);
write_byte(0xbe);//读取温度指令
a=read_byte();//读低8位
b=read_byte();//读高8位
t=b;
t<<=8;
t|=a;
returnt;
}
/*********温度处理***********/
voiddeal_wendu(uintt)
{
zf=(t>>12)&0x0f;//zf为正负标志位
if(zf==0x0f)//=0x0f时为负温度
{
t=(~t)+1;//补码转换,取反加一
}
xs=((t&0x0f)*625+5)/10;//小数:
精度0.0625加5为四舍五入保留3位小数误差正负0.001
zs=(t>>4)&0x007f;//整数;
}
3、键盘扫描:
采用行列检测法,先检测第一行,判断P1口是否等于0xf0,若检测到不等于0xf0,则有按键按下,反之,则无按键按下。
接着依次对P1口分别赋0xfe,0xfd,0xfb,0xf7,并加入消抖功能,逐行扫描,检测按键值变化,返回相对应的值,从而实现对4行4列按键的检测
4、数码管显示:
将所有位数码管的段选线并联在一起,由位选线控制是哪一位数码管有效。
选亮数码管采用动态扫描显示,即轮流向各位数码管送出字形码和相应的位选,利用发光管的余辉和人眼视觉暂留作用,使人的感觉好像各位数码管同时都在显示。
利用数码管动态显示原理,分别通过单片机控制数码管的段选和位选,从而实现控制数码管显示不同的数字。
四、软件控制程序流程
五、测试方案及测试结果:
1、测量结果能正确显示,且精确到1位小数。
2、能够实时显示环境温度。
3、能够保存使用时间内的最大值和最小值,能够查阅。
4、有温度报警功能,能够设置报警温度。
用绿灯表示正常温度,红灯表示报警同时发声。
附录:
1.参考文献:
[1]郭天祥视频《十天学会单片机》
[2] 李朝青.单片机原理及接口技术(简明修订版).杭州:
北京航空航天大学出版社,1998
[3] 李广弟.单片机基础[M].北京:
北京航空航天大学出版社,1994
[4] 阎石.数字电子技术基础(第三版).北京:
高等教育出版社,1989
[5] 廖常初.现场总线概述[J].电工技术,1999.
2.总电路图:
图硬件整体电路图
3.程序代码
/************************温度计******************************
功能说明:
1:
能够实时显示环境温度。
2:
能够保存使用时间内的最大值和最小值,能够查阅。
3:
有温度报警功能,能够设置报警温度。
用绿灯表示正常温度,红灯表示报警同时发声。
接线说明:
P3^0为DS18B20接口,P3^1控制红灯,P3^2控制绿灯,P2控制位选,P0控制段选,P1控制键盘
使用说明:
键盘输入“1”显示最大值,输入“2”显示最小值
****************************************************************/
#include
#include
voidhitemper();
#defineucharunsignedchar
#defineuintunsignedint
sbitDQ=P3^0;//数据口
sbitRED=P3^1;
sbitGREEN=P3^2;
sbitbuzz=P3^3;
uinttemp,temp1,temp2,flag,flag1,wei=1,count,tem,max=0,min=99,num=11,m,n,max1=55,min1,k,j=0,highttem=0,hight=40;
ucharcodetable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};//共阴数码管
unsignedcharcodeweixuan[]={0xEF,0xDF,0xBF,0x7F};//位选
unsignedchartemp3[4]={0,0,0,0,};
/*************精确延时函数*****************/
voiddelay(unsignedchari)
{
while(--i);
}
//-----------------------温度过高报警--------------//
voidbuzzer(uinti)
{
while(i--)
{
buzz=!
buzz;
k=0;
delay(100);
}
}
/*****************DS18B20初始化******************/
voidInit_Ds18b20(void)//DS18B20初始化sendresetandinitializationcommand
{
DQ=1;//DQ复位
delay
(1);//稍做延时
DQ=0;//单片机拉低总线
delay(250);//精确延时,维持至少480us
DQ=1;//释放总线,即拉高了总线
delay(100);//此处延时有足够,确保能让DS18B20发出存在脉冲。
}
/*****************读取一个字节******************/
ucharRead_One_Byte()//读数据时,数据以字节的最低有效位先从总线移出
{
uchari=0;
uchardat=0;
for(i=8;i>0;i--)
{
DQ=0;//将总线拉低,要在1us之后释放总线
//单片机要在此下降沿后的15us内读数据才会有效。
_nop_();//至少维持了1us,表示读时序开始
dat>>=1;//让从总线上读到的位数据,依次从高位移动到低位。
DQ=1;//释放总线,此后DS18B20会控制总线,把数据传输到总线上
delay
(1);
if(DQ)//控制器进行采样
{
dat|=0x80;//若总线为1,即DQ为1,那就把dat的最高位置1;若为0,则不进行处理,保持为0
}
delay(30);//此延时不能少,确保读时序的长度60us。
}
return(dat);
}
/*****************写入一个字节******************/
voidWrite_One_Byte(uchardat)
{
uchari=0;
for(i=8;i>0;i--)
{
DQ=0;//拉低总线
_nop_();//至少维持了1us,表示写时序(包括写0时序或写1时序)开始
DQ=dat&0x01;//从字节的最低位开始传输
//指令dat的最低位赋予给总线,必须在拉低总线后的15us内,
//因为15us后DS18B20会对总线采样。
delay(30);//必须让写时序持续至少60us
DQ=1;//写完后,必须释放总线,
dat>>=1;
delay
(1);
}
}
//-------------------获取温度---------------------//
uintGet_Tmp()//获取温度getthetemperature
{
floattt;
uchara,b;
Init_Ds18b20();//初始化
Write_One_Byte(0xcc);//跳过读序号列号的操作
Write_One_Byte(0x44);//温度转换指令
Init_Ds18b20();//初始化
Write_One_Byte(0xcc);//跳过读序号列号的操作
Write_One_Byte(0xbe);//读取温度寄存器等(共可读9个寄存器)前两个就是温度
a=Read_One_Byte();//读取到的第一个字节为温度LSB
b=Read_One_Byte();//读取到的第一个字节为温度MSB
temp=b;//先把高八位有效数据赋于temp
temp<<=8;//把以上8位数据从temp低八位移到高八位
temp=temp|a;//两字节合成一个整型变量
if(temp&0x8000)//负温度
{
flag=1;
tt=(~temp)+1;
tt=tt*0.0625;
if(max1>=tt)
max1=tt;//最大值
if(min1<=tt)
min1=tt;//最小值
if(num==1&&n!
=11)
tt=max1;
if(num==1&&n==11)//最大值
{
tt=max;
flag=0;
}
if(num==2)//最小值
{
tt=min1;
m=1;
}
temp1=tt*10+0.5;//负温度时,取反加1再乘以0.0625得实际温度,乘10+0.5显示小数点一位,且四舍五入
}
else
{
flag=0;
tt=temp*0.0625;//得到真实十进制温度值
//因为DS18B20可以精确到0.0625度
//所以读回数据的最低位代表的是0.0625度
if(tt>=hight)
{
RED=0;
GREEN=1;
buzzer(5);
}
else
{
RED=1;
GREEN=0;
}
if(max<=tt)
max=tt;//最大值
n++;
if(n<=10)
max=0;
else
n=11;
if(min>=tt)
min=tt;//最小值
if(num==1)//最大值
tt=max;
if(num==2)//最小值
tt=min;
if(num==2&&m==1)
{
tt=min1;
flag=1;
}
temp1=tt*10+0.5;//放大十倍
//这样做的目的将小数点后第一位也转换为可显示数字
//同时进行一个四舍五入操作。
}
returntemp1;
}
//------------------键盘扫描----------------//
voidkeyscan()
{
P1=0xfe;//检测第一行
temp2=P1;
temp2=temp2&0xf0;
while(temp2!
=0xf0)
{
delay(5);//消抖
temp2=P1;
temp2=temp2&0xf0;
while(temp2!
=0xf0)//确认按键按下
{
temp2=P1;
switch(temp2)
{
case0xee:
num=7;
break;
case0xde:
num=8;
break;
case0xbe:
num=9;
break;
case0x7e:
break;
}
while(temp2!
=0xf0)//检验按键释放
{
temp2=P1;
temp2=temp2&0xf0;
}
}
}
P1=0xfd;//检测第二行
temp2=P1;
temp2=temp2&0xf0;
while(temp2!
=0xf0)
{
delay(5);
temp2=P1;
temp2=temp2&0xf0;
if(temp2!
=0xf0)
{
temp2=P1;
switch(temp2)
{
case0xed:
num=4;
break;
case0xdd:
num=5;
break;
case0xbd:
num=6;
break;
case0x7d:
break;
}
if(temp2!
=0xf0)
{
temp2=P1;
temp2=temp&0xf0;
}
}
}
P1=0xfb;//检验第三行
temp2=P1;
temp2=temp2&0xf0;
while(temp2!
=0xf0)
{
delay(5);
temp2=P1;
temp2=temp&0xf0;
while(temp2!
=0xf0)
{
temp2=P1;
switch(temp2)
{
case0xeb:
num=1;//显示最大值
break;
case0xdb:
num=2;//显示最小值
break;
case0xbb:
num=3;
break;
case0x7b:
break;
}
while(temp2!
=0xf0)
{
temp2=P1;
temp2=temp2&0xf0;
}
}
}
P1=0xf7;//检验第四行
temp2=P1;
temp2=temp2&0xf0;
while(temp2!
=0xf0)
{
delay(5);
temp2=P1;
temp2=temp2&0xf0;
while(temp2!
=0xf0)
{
temp2=P1;
switch(temp2)
{
case0xe7:
{num=13;j=1;highttem=0;}//ON/C,设置报警温度
break;
case0xd7:
num=0;
break;
case0xb7:
num=14;//退出设置报警温度
break;
case0x77:
break;
}
while(temp2!
=0xf0)
{
temp2=P1;
temp2=temp2&0xf0;
}
}
}
}
//--------------------设置报警温度---------------//
voidhitemper()
{
if(j==1)
if(num<10)
{
highttem=highttem*10+num;
num=11;
}
if(num==14)
{
j=0;hight=highttem;
//num=11;
}
}
/****************数码码动态显示函数**************/
voidDisplay()//显示程序
{
temp3[1]=tem/100;//百位
temp3[2]=tem%100/10;//十位
temp3[3]=tem%10;//个位
if(flag==1)
{
P2=weixuan[0];
P0=0x40;
delay(500);
P2=~0x00;
}
P2=weixuan[wei];//位选
if(wei<2|wei==3)
P0=table[temp3[wei]];//段选
else
P0=table[temp3[wei]]|0x80;//段选
wei++;
if(wei>3)
wei=1;
}
voidinital()
{
TMOD=0x11;//T0、T1使用方式1
TH1=(65535-1000)/256;
TL1=(65535-1000)%256;
ET1=1;//允许T1中断
TR1=1;//开启T1
EA=1;//开启总中断
}
voidmain()
{
inital();
while
(1)
{
hitemper();
}
}
//------------中断函数-------------------//
voidt1()interrupt3
{
keyscan();
count++;
if(count>=100)
{
tem=Get_Tmp();
count=0;
}
Display();//数码管显示
TH1=(65535-1000)/256;
TL1=(65535-1000)%256;
}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 课程设计 报告 温度计