单片机课程设计报告数字温度计.docx
- 文档编号:27817253
- 上传时间:2023-07-05
- 格式:DOCX
- 页数:17
- 大小:56.76KB
单片机课程设计报告数字温度计.docx
《单片机课程设计报告数字温度计.docx》由会员分享,可在线阅读,更多相关《单片机课程设计报告数字温度计.docx(17页珍藏版)》请在冰豆网上搜索。
单片机课程设计报告数字温度计
惠州学院
HUIZHOUUNIVERSITY
单片机课程设计
设计题目
系别
专业
班级
学号
学生姓名
指导教师
完成时间年月
一.课题设计任务与要求。
--------------------------------------------------------
二.对于课题的总体构想。
--------------------------------------------------------
三.DS18B20温度传感器简介。
--------------------------------------------------------
四.系统总仿真电路。
--------------------------------------------------------
五.总程序。
--------------------------------------------------------
六.心得体会。
--------------------------------------------------------
七.参考文献。
---------------------------------------------------
一、设计任务与要求
设计任务:
利用数字温度传感器DS18B20与单片机结合来测量温度。
设计要求:
利用数字温度传感器DS18B20测量温度信号,计算后在LED数码管上显示相应的温度值。
其温度测量范围为-55~125℃,精确到0.5℃。
本温度计属于多功能温度计,可以设置上下报警温度,当温度不在设置范围内时,可以报警。
数字温度计所测量的温度采用数字显示,控制器使用单片机89C51,测温传感器使用DS18B20,用3位共阳极LED数码管以串口传送数据,实现温度显示。
从温度传感器DS18B20可以很容易直接读取被测温度值,进行转换即满足设计要求。
DS18B20温度传感器是美国DALLAS半导体公司最新推出的一种改进型智能温度传感器,与传统的热敏电阻等测温元件相比,它能直接读出被测温度,并且可根据实际要求通过简单的编程实现9~12位的数字读数方式。
二.对课题的总体构想
采用数字温度芯片DS18B20测量温度,输出信号全数字化,利用1602液晶显示屏实时显示温度。
其中DS18B20的最大特点之一采用了单总线的数据传输,由数字温度计DS18B20和微控制器STC89C52构成的温度测量装置,它直接输出温度的数字信号,可直接与计算机连接。
采用51单片机控制,软件编程的自由度大,可通过编程实现各种各样的算术算法和逻辑控制,而且体积小,硬件实现简单,安装方便。
既可以单独对多DS18B20控制工作,还可以与PC机通信上传数据,另外STC89C52在工业控制上也有着广泛的应用,编程技术及外围功能电路的配合使用都很成熟。
三、DS18B20简介
DS18B20的性能如下:
独特的单线接口仅需要一个端口引脚进行通信。
多个DS18B20可以并联在串行传输的数据线上,实现多点组网功能。
无须外部器件。
可通过数据线供电,电压范围为3.0~5.5V。
零待机功耗。
温度以9或12位的数字读数方式。
用户可定义报警设置。
报警搜索命令识别并标志超过程序限定温度(温度报警条件)的器件。
负电压特性,电源极性接反时,温度计不会因发热而烧毁,但不能正常工作。
DS18B20采用3引脚PR-35封装或8引脚SOIC封装。
四、系统仿真电路图(Proteus)
六、总程序
/*********************************/
#include
#include
//#include"1602LCD_Module.h"
#include"18B20.h"
#defineuintunsignedint
#defineucharunsignedchar
#definedelayNOP(){_nop_();_nop_();_nop_();_nop_();}
sbitlight=P1^0;
sbitDQ=P3^7;//7
voidDisplayStr(charline,location,charcode*str);
ucharcodeTemp_Disp_Title[]={"CurrentTemp:
"};
ucharCurrent_Temp_Display_Buffer[]={"TEMP:
"};
intxiaxian=20;
intshangxian=35;
ucharcodeTemperature_Char[8]=
{
0x0c,0x12,0x12,0x0c,0x00,0x00,0x00,0x00
};
//温度小数对照表
ucharcodedf_Table[]=
{
0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9
};
ucharCurrentT=0;
ucharTemp_Value[]={0x00,0x00};
ucharDisplay_Digit[]={0,0,0,0};
bitDS18B20_IS_OK=1;
//=====================================================================================================================
//=====================================================================================================================
#defineucharunsignedchar
#defineuintunsignedint
sbitRS=P2^5;
sbitRW=P2^6;//读写控制
sbitE=P2^7;//使能
sbitBF=P0^7;//D7为LCD忙/闲标口,BF为标志位,BF=1为忙,BAF=0为闲
voidDelayms(uintms)
{
uchari;
while(ms--)
{
for(i=0;i<120;i++);
}
}
//使用voidLCDCheckV1()会死循环,导致proteus仿真失败
/*voidLCDCheckV1()//忙检查函数
{
E=0;//禁止读写功能
do
{
BF=1;//设置BF为输入
RS=0;RW=1;//读取指令
E=1;//使能(读取BF和AC地址计数器)
}while(BF==1);//BF=1,忙
}*/
ucharLCDCheckV2()
{
ucharLCD_Status;
RS=0;
RW=1;
E=1;
Delayms(6);//这个延时必须要有!
如果是STC89或STC90系列单片机,延时Delayms
(1)即可;如果是STC12系列单片机,延时要不小于Delayms(5);
LCD_Status=BF;
E=0;
returnLCD_Status;
}
voidLCDWriteCmd(charcmd)//写指令函数
{
while(LCDCheckV2());
RS=0;//
RW=0;//写
E=1;//使能
P0=cmd;
E=0;
}
voidLCDWriteChar(charcharacter)//写数据函数
{
while(LCDCheckV2());
RS=1;
RW=0;//
E=1;
P0=character;
E=0;
//while(LCDCheckV2());
}
voidDisplayChar(charline,location,character)//将字符显示在特定位置
{
while(LCDCheckV2());
RS=0;RW=0;//写指令
E=1;
if(line==0)
{
P0=0x80+location;//在第0行显示第location列显示。
相当于LCDWriteCmd(0x80+location-1);0x08是第0列的地址
}
if(line==1)
{
P0=0x40|0xc0+location;//在第1行显示第location列显示。
相当于LCDWriteCmd(0x40|0xc0+location-1);0x40|0xc0是第0列的地址
//为什么第一列地址不是0x90?
与手册不符
}
E=0;
//while(LCDCheckV2());
LCDWriteChar(character);
}
//============================
//按指定位置显示一串字符
voidDisplayStr(charline,location,charcode*str)//将字符显示在特定位置
{
inti;
while(LCDCheckV2());
RS=0;RW=0;//写指令
E=1;
if(line==0)
{
P0=0x80+location;//在第0行显示第location列显示。
相当于LCDWriteCmd(0x80+location);0x08是第0列的地址
}
if(line==1)
{
P0=0x40|0xc0+location;//在第1行显示第location列显示。
相当于LCDWriteCmd(0x40|0xc0+location);0x40|0xc0是第0列的地址
//为什么第一列地址不是0x90?
与手册不符
}
E=0;
//while(LCDCheckV2());
for(i=0;i<16;i++)
{
LCDWriteChar(str[i]);
}
}
//========================================
voidLCDInit()//初始化LCD
{
LCDWriteCmd(0x30);
LCDWriteCmd(0x30);
//LCDWriteCmd(0x30);//加上这两行代码可以兼容中英文LCD模块
LCDWriteCmd(0x38);//设置两行模式
LCDWriteCmd(0x08);//显示关闭
LCDWriteCmd(0x01);//清屏
LCDWriteCmd(0x06);//字符后移
LCDWriteCmd(0x0c);//显示开,及光标设置
}
//=====================================================================================================================
//=====================================================================================================================
voidDelayXus(unsignedintx)
{
uchari;
while(x--)
{
for(i=0;i<200;i++);
}
}
voidDelay(unsignedintx)
{
while(--x);
}
ucharInit_DS18B20()//
{
ucharstatus;
DQ=1;Delay(8);
DQ=0;Delay(90);
DQ=1;Delay(8);
status=DQ;//
Delay(100);
DQ=1;
returnstatus;
}
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();//温度低8位
Temp_Value[1]=ReadOneByte();//温度高8位
DS18B20_IS_OK=1;//
}
}
voidDisplay_Temperature()
{
uchari;
uchart=150,ng=0;
if((Temp_Value[1]&0xf8)==0xf8)//高5位全为1(0XF8)则为负数,为负数时取反加一(得到补码),并设置负标识
{
Temp_Value[1]=~Temp_Value[1];
Temp_Value[0]=~Temp_Value[0]+1;
if(Temp_Value[0]==0x00)
Temp_Value[1]++;
ng=1;//负数标志位为1,说明温度是负数
}
Display_Digit[0]=df_Table[Temp_Value[0]&0x0f];//查表得到温度小数部分
CurrentT=((Temp_Value[0]&0xf0)>>4)|((Temp_Value[1]&0x07)<<4);//温度整数部分
//整数部分分解为3位待显示数字
Display_Digit[3]=CurrentT/100;
Display_Digit[2]=CurrentT%100/10;
Display_Digit[1]=CurrentT%10;
//刷新LCD显示缓冲
Current_Temp_Display_Buffer[11]=Display_Digit[0]+'0';
Current_Temp_Display_Buffer[10]='.';
Current_Temp_Display_Buffer[9]=Display_Digit[1]+'0';
Current_Temp_Display_Buffer[8]=Display_Digit[2]+'0';
Current_Temp_Display_Buffer[7]=Display_Digit[3]+'0';
if(Display_Digit[3]==0)//高位为0时不显示
Current_Temp_Display_Buffer[7]='';
if(Display_Digit[2]==0&&Display_Digit[3]==0)//高位且次位为0不显示
Current_Temp_Display_Buffer[8]='';
if(ng)//ng=1说明温度是负数,负数符号显示在恰当位置
{
if(Current_Temp_Display_Buffer[8]=='')
Current_Temp_Display_Buffer[8]='-';
elseif(Current_Temp_Display_Buffer[7]=='')
Current_Temp_Display_Buffer[7]='-';
else
Current_Temp_Display_Buffer[6]='-';
}
LCDWriteCmd(0x80);//在第一行显示
for(i=0;i<16;i++)
{
LCDWriteChar(Temp_Disp_Title[i]);
//delay(10);
}
LCDWriteCmd(0x40|0xc0);//在第二行显示,这里面的地址竟然不能是0x90!
为什么?
for(i=0;i<16;i++)
{
LCDWriteChar(Current_Temp_Display_Buffer[i]);
}
//LCDWriteCmd(0x40|0xc0+13);
//LCDWriteChar(0x00);
LCDWriteCmd(0x40|0xc0+14);
LCDWriteChar('C');
}
voidbaojing()
{
intwendu=Display_Digit[2]*10+Display_Digit[1];
intshangxian=30;
intxiaxian=15;
light=0;
if(wendu>shangxian)
light=1;
if(wendu light=1;} voidmain() { LCDInit(); Read_Temperature(); Delay(50000); Delay(50000); //DisplayStr(0,1,"abcd"); while (1) { Read_Temperature(); if(DS18B20_IS_OK) Display_Temperature(); DelayXus(100); baojing(); } } 六、心得体会 在此次课程设计中,我不仅仅加深了对单片机的理解,将理论知识应用到了实践中,同时也提升了动手能力和出现问题的排查能力。 在设计过程中我遇到了很多困难,包括一开始的程序及仿真,在此也感谢在过程中帮助我的同学。 完成仿真后开始制作实物,在这过程中同样遇到很多难题,不过最后都一个个解决了,也让我懂得了没有什么是一帆风顺,只有在失败中吸取经验才能取得最后的成功,正如山穷水尽疑无路,柳暗花明又一村,只有自己切身经历过才能体会其中的道理。 七、参考文献 单品微型计算机与接口技术(第四版)李群芳肖看张士军著
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 单片机 课程设计 报告 数字 温度计
![提示](https://static.bdocx.com/images/bang_tan.gif)