院 系:电气与信息工程学院
专 业:****
班 级:****
学生姓名:****
学 号:****
日 期:2012年11月11号
第一部分 设计要求:
采用ATC51单片机和LCD液晶显示器设计一个数字温度计,当外界温度变化时,显示屏上的温度值也随着变化。数字温度计的测温范围为-55°C到125°C之间。
第二部分 硬件原理框图:
ATC51单片机
LCD液晶显示电路
晶振振荡电路
复位电路
温度传感器采集电路
电 源 电 路
硬件部分主要分为晶振振荡电路、复位电路、LCD液晶显示电路、DS18B20温度传感器采集电路、电源电路等部分组成。
第三部分 硬件原理图:
硬件模块原理图:
1、晶振振荡电路
该电路是由两个电容和一个晶振组成,晶振产生基本的时钟信号它给单片机提供时钟信号。
2、复位电路
复位的主要作用是把特殊功能寄存器的数据刷新为默认数据,单片机在运算过程中由于干扰等外界原因造成寄存器中数据混乱不能使其正常继续执行程序或产生的结果不正确时均需要复位,以使程序重新开始运行。
3、LCD液晶显示电路
经过温度传感器,将采集到的温度信息传给单片机,单片机处理后又将信息发给P0口,P0口与LCD的数据口相连接,液晶屏上会显示采集到的温度值。
4、温度传感器采集电路
单线数字温度传感器DS18B20测量温度范围为 -55°C~+125°C,-10~+85°C范围内,精度为±0.5°C。DS1822的精度较差为± 2°C 。DS18B20的管脚排列如下: DQ为数字信号输入/输出端;GND为电源地;VDD为外接供电电源输入端(在寄生电源接线方式时接地)。根据DS18B20的通讯协议,主机控制DS18B20完成温度转换必须经过三个步骤:每一次读写之前都要对DS18B20进行复位,复位成功后发送一条ROM指令,最后发送RAM指令,这样才能对DS18B20进行预定的操作。复位要求主CPU将数据线下拉500微秒,然后释放,DS18B20收到信号后等待16~60微秒左右,后发出60~240微秒的存在低脉冲,主CPU收到此信号表示复位成功。
5、电源电路
设计中利用桥式整流和电容滤波以及7805集成稳压来输出+5V电压,以满足ATC51、LCD1602、DS18B20等器件的工作需求,原理如下:
第四部分 程序流程图
发温度转换开始命令
结束
图2 温度转换命令子程序流程图
N
图1 主程序流程图
第五部分 总结:
在本次设计的过程中,我查阅了许多文献资料,从中学到了很多有关系统开发和程序调试方面等的知识。在软件开发过程中掌握了一些技术难题的解决方法和技巧,巩固和加深了所学知识的理解,能够把所学的知识与实践相结合,培养了认真严谨的学习态度,为以后开发软件积累了大量的经验,提高了分析问题和解决问题的能力。但是由于认识上的片面和不足,各方面的条件影响也很多,本设计还有待进一步的完善和优化,这些在以后的学习中要注重积累。
第六部分 主要程序
#include #include #define uint unsigned int #define uchar unsigned char #definedelayNOP() {_nop_();_nop_();_nop_();_nop_();}//_nop_()为一个机器周期 sbit DQ = P3^3; sbit LCD_RS = P2^0; sbit LCD_RW = P2^1; sbit LCD_EN = P2^2; uchar code Temp_Disp_Title1[]="Now Temperature:";//液晶第一行显示的字符 uchar Temp_Display_Title2[]=" TEMP: ";//第二行前半部分显示的字符 uchar code Temperature_Char[8] = { 0x0c,0x12,0x12,0x0c,0x00,0x00,0x00,0x00 }; uchar code df_Table[]= { 0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9 }; uchar CurrentT = 0; uchar TL,TH; uchar Display_Digit[]={0,0,0,0}; bit DS18B20_IS_OK = 1; void DelayXus(uint x) { uchar i; while(x--) { for(i=0;i<200;i++); } } bit LCD_Busy_Check()//对LCD进行读写状态检测 { bit result; LCD_RS = 0; LCD_RW = 1; LCD_EN = 1; delayNOP(); result = (bit)(P0&0x80); LCD_EN=0; return result; } void Write_LCD_Command(uchar cmd)//LCD写指令函数 { while(LCD_Busy_Check());//当LCD_Busy_Check为1时 LCD_RS = 0; LCD_RW = 0; LCD_EN = 0; _nop_(); _nop_(); P0 = cmd; delayNOP(); LCD_EN = 1; delayNOP(); LCD_EN = 0; } void Write_LCD_Data(uchar dat)//LCD写数据函数 { while(LCD_Busy_Check()); LCD_RS = 1; LCD_RW = 0; LCD_EN = 0; P0 = dat; delayNOP(); LCD_EN = 1; delayNOP(); LCD_EN = 0; } void LCD_Initialise()//LCD初始化程序 { Write_LCD_Command(0x01);//显示清屏 DelayXus(5); Write_LCD_Command(0x38);//显示模式设置 DelayXus(5); Write_LCD_Command(0x0c);//不显示光标 DelayXus(5); Write_LCD_Command(0x06);//当写一个字符时整屏显示不移动 DelayXus(5); } void Set_LCD_POS(uchar pos)//设置LCD地址 { Write_LCD_Command(pos|0x80); } void Delay(uint x) { while(--x); } uchar Init_DS18B20()//初始化温度传感器,根据时序图操作命令 { uchar status; DQ = 1;//将数据线电平拉高 Delay(8);//延时约8us再将DQ拉低 DQ = 0; Delay(90);//延时360us DQ = 1;//释放数据线,将数据线拉高 Delay(8);//延时32us DQ=1; Delay(60); return status;//返回检测 } uchar ReadOneByte()//读时序 { uchar i; uchar dat=0;//存储读出的一个字节数据 DQ = 1;//先将数据线拉高 _nop_();//等待一个机器周期 for(i=0;i<8;i++)//一个字节8位 { DQ = 0; dat >>= 1; DQ = 1; _nop_(); _nop_(); if(DQ) dat |= 0X80; Delay(30); DQ = 1; } return dat; } void WriteOneByte(uchar dat)//写时序操作 { uchar i; for(i=0;i<8;i++) { DQ = 0; DQ = dat& 0x01; Delay(5); DQ = 1; dat >>= 1; } } void Read_Temperature()//读取温度函数 { if(Init_DS18B20()==1)//如果Init_DS18B20()==1,需要继续检测 DS18B20_IS_OK=0; else //如果Init_DS18B20()!=1时 { WriteOneByte(0xcc);//跳过读序列号操作 WriteOneByte(0x44);//启动温度装换 Init_DS18B20();//初始化DS18B20 WriteOneByte(0xcc);//跳过读序列号操作 WriteOneByte(0xbe);//读取温度寄存器,前两个分别是温度的高位和低位 TL = ReadOneByte(); TH= ReadOneByte(); DS18B20_IS_OK=1; } } void Display_Temperature()//显示温度函数 { uchar i; uchar t = 150, ng = 0; if((TH&0xf8)==0xf8)//符号位是5个1,此时为负温度 { TL = ~TL; TH= ~TH+1; if(TL==0x00) TH++; ng = 1; } Display_Digit[0] = df_Table[TL&0x0f]; CurrentT = ((TL&0xf0)>>4) | ((TH&0x07)<<4); Display_Digit[3] = CurrentT/100; Display_Digit[2] = CurrentT%100/10; Display_Digit[1] = CurrentT%10; Temp_Display_Title2[11] = Display_Digit[0] + '0'; Temp_Display_Title2[10] = '.'; Temp_Display_Title2[9] = Display_Digit[1] + '0'; Temp_Display_Title2[8] = Display_Digit[2] + '0'; Temp_Display_Title2[7] = Display_Digit[3] + '0'; if(Display_Digit[3] == 0) Temp_Display_Title2[7] = ' '; if(Display_Digit[2] == 0&&Display_Digit[3]==0) Temp_Display_Title2[8] = ' '; if(ng) { if(Temp_Display_Title2[8] == ' ') Temp_Display_Title2[8] = '-'; else if(Temp_Display_Title2[7] == ' ') Temp_Display_Title2[7] = '-'; else Temp_Display_Title2[6] = '-'; } Set_LCD_POS(0x00); for(i=0;i<16;i++) { Write_LCD_Data(Temp_Disp_Title1[i]); } Set_LCD_POS(0x40); for(i=0;i<16;i++) { Write_LCD_Data(Temp_Display_Title2[i]); } Set_LCD_POS(0x4d); Write_LCD_Data(0x00); Set_LCD_POS(0x4e); Write_LCD_Data('C'); }; void main() { LCD_Initialise(); Read_Temperature(); Delay(50000); Delay(50000); while(1) { Read_Temperature(); if(DS18B20_IS_OK) Display_Temperature(); DelayXus(100); } }下载本文