课程设计报告.docx
《课程设计报告.docx》由会员分享,可在线阅读,更多相关《课程设计报告.docx(16页珍藏版)》请在冰豆网上搜索。
课程设计报告
单片机原理及系统课程设计
评语:
考勤10分
守纪10分
过程30分
设计报告30分
答辩20分
总成绩(100分)
专业:
自动控制
班级:
控1104
姓名:
陈永杰
学号:
201109042
指导教师:
侯涛
兰州交通大学自动化与电气工程学院
2014年1月15日
基于单片机的数字温度计设计
1设计目的
随着人们生活水平的不断提高,单片机控制无疑是人们追求的目标之一,它所给人带来的方便是不可否定的,各种数字系统的应用也使人们的生活更加舒适。
数字化控制、智能控制为现代人的工作、生活、科研等方面带来方便。
其中数字温度计就是一个典型的例子。
数字温度计与传统的温度计相比,具有读数方便、测温范围广、测温精确、功能多样话等优点。
其主要用于对测温要求准确度比较高的场所,或科研实验室使用。
本设计主要介绍了一个基于AT89C51单片机的测温系统,详细描述了利用数字温度传感器DS18B20开发测温系统的过程,重点对传感器在单片机下的硬件连接,软件编程以及各模块系统流程进行了详尽分析,特别是数字温度传感器DS18B20的数据采集过程。
对各部分的电路也一一进行了介绍,该系统可以方便的实现温度采集和显示,并可根据需要任意设定上下限报警温度。
2设计方案及原理
2.1系统总体设计方案
数字温度计具有精度高、量程宽、灵敏度高、体积小、功耗低等优点,在生活中广泛应用。
本设计中用单片机AT89C51、温度传感器DS18B20和数码管组成数字温度计,实现了对温度的测量和报警的功能,结构简单,便于操作。
2.2温度计设计原理
温度计原理图如图1所示。
系统工作时,温度传感器将采集到的信号传送给单片机,单片机通过软件处理把数据传送到显示模块和报警模块,实现温度的显示和报警作用。
图1温度计原理图
3硬件设计
3.1系统原理电路图
本课题是以AT89C51单片机为核心的一种数字温度控制系统,系统整体硬件电路包括,传感器数据采集电路,上下限报警调整电路,温度显示电路,单片机主板电路等组成。
图2系统原理电路图
3.2晶体振荡电路
AT89C51芯片内部有一个高增益反相放大器,用于构成振荡器。
引线XTAL1和XTAL2分别为反向放大器的输入和输出,两端跨接石英晶体及两个电容就可构成稳定的自激振荡器。
这里,选用51单片机12MHZ的内部振荡方式,电容器C1、C2起稳定振荡频率,并对振荡频率有微调作用,C1和C2可在20~100pF之间取值,这里取22pF。
晶振电路图如图3所示。
图3晶振电路图
3.3报警电路
在报警电路中,我们可以在I/O口上直接接LED灯和蜂鸣器,由P1.4连接红色LED灯作为高温报警灯,P1.5连接黄色LED灯作低温报警灯;P3.7连接蜂鸣器。
当系统温度高于某值时,P1.4便会输出低电平,红灯闪烁;当系统温度低于某值时,P1.5便会输出低电平,黄灯闪烁;在这两种情况下P3.7都会输出高电平,是蜂鸣器报警。
在报警时,只要将按钮开关断开,就会解除蜂鸣器报警,当温度变化到某范围时,LED灯才会停止闪烁。
报警电路图如图5所示。
图4报警电路图
3.4温度显示电路
显示电路既可以选用液晶显示器,也可以选用数码管显示。
我们采用的是数码管显示电路。
用8位共阴数码管显示,LED是七段式显示器,内部有7个条形发光二极管和1个小圆点发光二极管组成,根据各管的亮暗组合成字符。
在用数码管显示时,我们有静态和动态两种选择,静态显示程序简单,显示稳定,但是占用端口比较多;动态显示所需端口比较少,可以节省单片机的I/O口。
74LS245是常用的芯片,用来驱动LED或者其他的设备,它是8路双向总线收发器,可双向传输数据。
74LS245还具有双向三态功能,既可以输出,也可以输入数据。
当AT89C51单片机的P0口总线负载达到或超过P0口最大负载能力时,必须接入74LS245等总线驱动器。
显示电路图如图6所示。
图5显示电路图
3.5DS18B20温度传感器
数字温度传感器DS18B20是一种新型的“一线器件”,温度测量范围为-55~+125摄氏度,可编程为9位~12位转换精度,测温分辨率可达0.0625摄氏度,分辨率设定参数以及用户设定的报警温度存储在EEPROM中,掉电后依然保存。
被测温度用符号扩展的16位数字量方式串行输出;其工作电源既可以在远端引入,也可以采用寄生电源方式产生;多个DS18B20可以并联到3根或2根线上,CPU只需一根端口线就能与诸多DS18B20通信。
DS18B20内部结构主要由四部分组成:
64位光刻ROM、温度传感器、非挥发的温度报警触发器TH和TL、配置寄存器。
由于DS18B20单线通信功能是分时完成的,有严格的时隙概念,因此读写时序很重要。
系统对DS18B20的各种操作必须按协议进行。
操作协议为:
初始化DS18B20(发复位脉冲)→发ROM功能命令→发存储器操作命令→处理数据。
图6DS18B20电路图
4软件设计
4.1程序流程图
本系统的软件部分主要可分为显示程序、定时计数中断程序、报警程序、延时程序。
利用Keil软件对程序调试,程序运行无误后生成了hex文件。
流程图如图7所示。
图7程序流程图
4.2主程序
程序见附录。
5系统仿真及总结
5.1仿真结果
本次课程设计中的系统仿真利用Proteus软件进行硬件电路连接,通过放置元器件,合理布线,确认电路连接后,将Keil软件已经生成的hex文件装入AT89C51单片机中进行仿真,最后仿真成功。
系统仿真结果图如图7所示。
图8系统仿真结果图
5.2总结
通过本次课程设计,使我深刻地认识到自己掌握的单片机方面的知识还很少,对学过的课本知识理解不透彻,而且不能熟练运用汇编和C语言编写程序,从而导致在设计方案初期出现了一些错误。
通过老师答疑和查阅书籍慢慢地理清了设计方案的思路和程序的编写,以及对仿真软件PROTEUS和KEIL的熟练运用。
本次课程设计使我加深了对单片机课程的全面认识,复习和掌握,在大学课堂学习了大量的专业知识,但没有太多的实践来检验自己的掌握程度,只有理论和实践相结合,才能更好地学好专业知识,这次的数字温度计的设计给我奠定了一个实践基础,我会在以后的学习生活中更好地将理论转化为实践,使自己的各方面能得到提高,同时在查找资料的过程中我也学到了许多新的知识,在和同学的互相讨论中,提高了自己的单片机知识水平。
参考文献
[1]王思明,苟军年.单片机原理及应用系统设计[M].北京:
科学出版社,2012:
176-189.
[2]谭浩强.C程序设计(第四版)[M].北京:
清华大学出版社,2010:
36-60.
[3]贺敬凯.单片机系统设计[M].西安:
电子科技大学出版社,2011:
86-102.
附录:
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitDQ=P3^6;
sbitBEEP=P3^7;
sbitHI_LED=P1^4;
sbitLO_LED=P1^5;
//共阴极数码管及空白显示
ucharcodeDSY_CODE[]=
{0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00};
//温度小数位对照表
ucharcodedf_Table[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};
//报警温度上下限
charAlarm_Temp_HL[2]={70,-20};
ucharCurrentT=0;//当前读取的温度整数部分
ucharTemp_Value[]={0x00,0x00};//从DS18B20读取的温度值
ucharDisplay_Digit[]={0,0,0,0};//待显示的各温度数位
bitHI_Alarm=0,LO_Alarm=0;//高低温报警标志
bitDS18B20_IS_OK=1;//传感器正常标志
uintTime0_Count=0;//定时器延时累加
//延时
voidDelay(uintx)
{
while(--x);
}
//初始化DS18B20
ucharInit_DS18B20()
{
ucharstatus;
DQ=1;Delay(8);
DQ=0;Delay(90);
DQ=1;Delay(8);
status=DQ;
Delay(100);
DQ=1;
returnstatus;//初始化成功时返回0
}
//读一字节
ucharReadOneByte()
{
uchari,dat=0;
DQ=1;_nop_();
for(i=0;i<8;i++)
{
DQ=0;dat>>=1;DQ=1;_nop_();_nop_();
if(DQ)dat|=0x80;Delay(30);DQ=1;
}
returndat;
}
//写一字节
voidWriteOneByte(uchardat)
{
uchari;
for(i=0;i<8;i++)
{
DQ=0;DQ=dat&0x01;Delay(5);DQ=1;dat>>=1;
}
}
//读取温度值
voidRead_Temperature()
{
if(Init_DS18B20()==1)//DS18B20故障
DS18B20_IS_OK=0;
else
{
WriteOneByte(0xCC);//跳过序列号
WriteOneByte(0x44);//启动温度转换
Init_DS18B20();
WriteOneByte(0xCC);//跳过序列号
WriteOneByte(0xBE);//读取温度寄存器
Temp_Value[0]=ReadOneByte();//温度低八位
Temp_Value[1]=ReadOneByte();//温度高八位
Alarm_Temp_HL[0]=ReadOneByte();//报警温度TH
Alarm_Temp_HL[1]=ReadOneByte();//报警温度TL
DS18B20_IS_OK=1;
}
}
//设置DS18B20温度报警值
voidSet_Alarm_Temp_Value()
{
Init_DS18B20();
WriteOneByte(0xCC);//跳过序列号
WriteOneByte(0x4E);//将设定的温度报警值写入DS18B20
WriteOneByte(Alarm_Temp_HL[0]);//写TH
WriteOneByte(Alarm_Temp_HL[1]);//写TL
WriteOneByte(0x7F);//12位精度
Init_DS18B20();
WriteOneByte(0xCC);//跳过序列号
WriteOneByte(0x48);//温度报警值存入DS18B20
}
//在数码管上显示温度
voidDisplay_Temperature()
{
uchari;
uchart=150;//延时值
ucharng=0,np=0;//负数标识及负号显示位置
charSigned_Current_Temp;
if((Temp_Value[1]&0xF8)==0xF8)
{
Temp_Value[1]=~Temp_Value[1];
Temp_Value[0]=~Temp_Value[0]+1;
if(Temp_Value[0]==0x00)Temp_Value[1]++;
ng=1;np=0xFD;
}
Display_Digit[0]=df_Table[Temp_Value[0]&0x0F];
CurrentT=((Temp_Value[0]&0xF0)>>4)|((Temp_Value[1]&0x07)<<4);
Signed_Current_Temp=ng?
-CurrentT:
CurrentT;
HI_Alarm=Signed_Current_Temp>=Alarm_Temp_HL[0]?
1:
0;
LO_Alarm=Signed_Current_Temp<=Alarm_Temp_HL[1]?
1:
0;
Display_Digit[3]=CurrentT/100;
Display_Digit[2]=CurrentT%100/10;
Display_Digit[1]=CurrentT%10;
if(Display_Digit[3]==0)
{
Display_Digit[3]=10;
np=0xFB;
if(Display_Digit[2]==0)
{
Display_Digit[2]=10;
np=0xF7;
}
}
//刷新显示若干时间
for(i=0;i<30;i++)
{
P0=0x39;P2=0x7F;Delay(t);P2=0xFF;
P0=0x63;P2=0xBF;Delay(t);P2=0xFF;
P0=DSY_CODE[Display_Digit[0]];//小数位
P2=0xDF;Delay(t);P2=0xFF;
P0=(DSY_CODE[Display_Digit[1]])|0x80;
P2=0xEF;Delay(t);P2=0xFF;
P0=DSY_CODE[Display_Digit[2]];
P2=0xF7;Delay(t);P2=0xFF;
P0=DSY_CODE[Display_Digit[3]];
P2=0xFB;Delay(t);P2=0xFF;
if(ng)//如果为负则在调整后的位置显示"-"
{
P0=0x40;P2=np;Delay(t);P2=0xFF;
}
}
}
voidT0_INT()interrupt1
{
TH0=-1000/256;
TL0=-1000%256;
BEEP=!
BEEP;
if(++Time0_Count==400)
{
Time0_Count=0;
if(HI_Alarm)HI_LED=~HI_LED;elseHI_LED=1;
if(LO_Alarm)LO_LED=~LO_LED;elseLO_LED=1;
}
}
//主程序
voidmain(void)
{
IE=0x82;
TMOD=0x01;
TH0=-1000/256;
TL0=-1000%256;
TR0=0;
HI_LED=1;
LO_LED=1;
Set_Alarm_Temp_Value();
Read_Temperature();
Delay(50000);
Delay(50000);
while
(1)
{
Read_Temperature();
if(DS18B20_IS_OK)
{
if(HI_Alarm==1||LO_Alarm==1)TR0=1;
elseTR0=0;
Display_Temperature();
}
else
{
P0=P2=0x00;
}
}
}