基于DSB的温测控.doc

上传人:doc321 文档编号:12771888 上传时间:2021-12-06 格式:DOC 页数:29 大小:1.17MB
返回 下载 相关 举报
基于DSB的温测控.doc_第1页
第1页 / 共29页
基于DSB的温测控.doc_第2页
第2页 / 共29页
基于DSB的温测控.doc_第3页
第3页 / 共29页
基于DSB的温测控.doc_第4页
第4页 / 共29页
基于DSB的温测控.doc_第5页
第5页 / 共29页
点击查看更多>>
资源描述

《基于DSB的温测控.doc》由会员分享,可在线阅读,更多相关《基于DSB的温测控.doc(29页珍藏版)》请在三一文库上搜索。

1、基于DSB的温测控 作者: 日期:2 个人收集整理 勿做商业用途 电子系统设计实验报告 -基于DS18B20的温度测控 2009.6基于DS18B20温度测控报告一、系统设计目的,用途,功能1、 目的通过基于AT89S51芯片和DS18B20温度传感器控制温度,熟悉芯片的使用,温度传感器的功能,实验电路板的焊接,LCD显示的使用,C51语言的设计。2、 用途 温度是工业控制中主要的被控参数之一.随着电子技术和微型计算机的迅速发展,微机测量和控制技术得到了迅速的发展和广泛的应用。单片机具有处理能强、运行速度快、功耗低等优点,应用在温度测量与控制方面,控制简单方便,测量范围广,精度较高.3、 功能

2、DS18b20温度传感器温度的精确度高达0。1度,在许多工业控制中已经足够。可以满足从-55摄氏度到+125摄氏度测量范围,在一秒内把温度转化成数字,测得的温度值的存储在两个八位的RAM中,单片机直接从中读出数据转换成十进制就是温度,使用方便。二、硬件设计思想和电路原理图2。1、整体模块设计AT89S51芯片LCD显示DS18B20温度传感器 蜂鸣器DS1302数字钟硬件连接框架图按键键盘电源部分2.2、各模块电路图 三、软件设计流程图各个设备初始化18B20,1302进行温度,时间数据采集对芯片返回值进行转换LCD显示时间和温度当温度超过设定温度时,发出警报重复调用芯片值四、软件仿真五、硬件

3、连接图 图1(正面) 图2(背面)六、系统测试过程及测试数据: (1) 时间:09年6月20 日13:10地点:22号楼104宿舍测试对象:室内温度设定警报温度:33时间13:2013:2513:3013:3513:40温度32。332.432。332.332。3(2)时间:08年6月20日22:20 地点:22号楼104宿舍 测试对象:室内温度 设定警报温度:31时间22;2022:2522:3022:3522:40温度30。530。535。630.530.5七、实验总结 本次实验最大困难在于程序的编写,由于以前做实验都是用汇编语言,很少用C语言编写程序,所以在编写各个模块的驱动程序时,碰到

4、比较多的问题,后来就在网络上找了一些例子来研究,然后根据自己需要进行修改,编写出适合自己本次实验的代码。经过一个的时间研究和实践,终于做出了这个项目。在制作的过程中,我们感到了自己的动手能力上有不足,但我们增强了自己的动手能力,通过本次实验,使自己学到很多在课堂上学不到的知识.通过自己动手实践,在实践中发现问题,分析问题,最后达到解决问题的目的。在实验过程中碰到这样一个问题,一开始,按照下图1焊接蜂鸣器报警模块,发现单片机输出高电平时,蜂鸣器有响起来,但是声音很小声,用万用表测得三级管基极电压为3。32V,发射极电压为2.75V,而没有接蜂鸣器时,单片机管脚输出电压为4。85V,可能是单片机输

5、出电压被负载下拉为3。32V,导致三极管的发射极电压为2.75V,这样就不够带动后面的蜂鸣器,所以我就把1K的限流电阻改为4.7K的上拉电阻,增大其带负载能力,如图2所示,经过这样改动后,蜂鸣器可以正常报警. 图1 图2其实,在实验之前本来想加入串口模块,这样就可以和计算机进行通信,可以通过计算机来控制整个系统,原理图如下,可是在硬件焊接过程中发现,加入串口模块后,整个电路板的布线变得很复杂,所以最后放弃串口模块。 七、附录(实验程序)/*/*/#include <REG52。H#include <intrins.h>#define uint unsigned intdefi

6、ne uchar unsigned charsbit DS1302_CLK = P20; /实时时钟时钟线引脚 sbit DS1302_IO = P21; /实时时钟数据线引脚 sbit DS1302_RST = P22; /实时时钟复位线引脚sbit wireless_1 = P34;sbit wireless_2 = P35;sbit wireless_3 = P36;sbit wireless_4 = P37;sbit ACC0 = ACC0;sbit ACC7 = ACC7;char hide_sec,hide_min,hide_hour,hide_day,hide_week,hide

7、_month,hide_year; /秒,分,时到日,月,年位闪的计数sbit Set = P30; /模式切换键sbit Up = P31; /加法按钮sbit Down = P32; /减法按钮sbit out = P33; /立刻跳出调整模式按钮sbit DQ = P23; /温度传送数据IO口char done,count,temp,flag,up_flag,down_flag;int temp_value; /温度值uchar TempBuffer5,week_value2;void show_time(); /液晶显示程序/*1602液晶显示部分子程序*/Port Definiti

8、ons*sbit LcdRs= P25;sbit LcdRw= P26;sbit LcdEn = P27;sfr DBPort = 0x80;/P0=0x80,P1=0x90,P2=0xA0,P3=0xB0。数据端口/内部等待函数*unsigned char LCD_Wait(void)LcdRs=0;LcdRw=1;_nop_();LcdEn=1;_nop_(); LcdEn=0;return DBPort;/向LCD写入命令或数据*#define LCD_COMMAND0 / Commanddefine LCD_DATA1 / Datadefine LCD_CLEAR_SCREEN0x01

9、 / 清屏#define LCD_HOMING 0x02 / 光标返回原点void LCD_Write(bit style, unsigned char input)LcdEn=0;LcdRs=style;LcdRw=0;_nop_();DBPort=input;_nop_();/注意顺序LcdEn=1;_nop_();/注意顺序LcdEn=0;_nop_();LCD_Wait();/设置显示模式*define LCD_SHOW0x04 /显示开define LCD_HIDE0x00 /显示关define LCD_CURSOR0x02 /显示光标define LCD_NO_CURSOR0x00

10、 /无光标 #define LCD_FLASH0x01 /光标闪动#define LCD_NO_FLASH0x00 /光标不闪动void LCD_SetDisplay(unsigned char DisplayMode)LCD_Write(LCD_COMMAND, 0x08DisplayMode);/设置输入模式*#define LCD_AC_UP0x02define LCD_AC_DOWN0x00 / default#define LCD_MOVE0x01 / 画面可平移#define LCD_NO_MOVE0x00 /defaultvoid LCD_SetInput(unsigned ch

11、ar InputMode)LCD_Write(LCD_COMMAND, 0x04InputMode);/初始化LCD*void LCD_Initial()LcdEn=0;LCD_Write(LCD_COMMAND,0x38); /8位数据端口,2行显示,5*7点阵LCD_Write(LCD_COMMAND,0x38);LCD_SetDisplay(LCD_SHOWLCD_NO_CURSOR); /开启显示, 无光标LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN); /清屏LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE); /AC递增, 画面不

12、动/液晶字符输入的位置*void GotoXY(unsigned char x, unsigned char y)if(y=0)LCD_Write(LCD_COMMAND,0x80|x);if(y=1)LCD_Write(LCD_COMMAND,0x80|(x-0x40);/将字符输出到液晶显示void Print(unsigned char str)while(*str!=0)LCD_Write(LCD_DATA,str);str+;/*DS1302时钟部分子程序*/typedef struct _SYSTEMTIME_unsigned char Second;unsigned char M

13、inute;unsigned char Hour;unsigned char Week;unsigned char Day;unsigned char Month;unsigned char Year;unsigned char DateString11;unsigned char TimeString9;SYSTEMTIME;/定义的时间类型SYSTEMTIME CurrentTime;define AM(X)Xdefine PM(X)(X+12) / 转成24小时制define DS1302_SECOND0x80 /时钟芯片的寄存器位置,存放时间define DS1302_MINUTE0x

14、82#define DS1302_HOUR0x84 define DS1302_WEEK0x8Adefine DS1302_DAY0x86#define DS1302_MONTH0x88#define DS1302_YEAR0x8C void DS1302InputByte(unsigned char d) /实时时钟写入一字节(内部函数) unsigned char i; ACC = d; for(i=8; i0; i-) DS1302_IO = ACC0; /相当于汇编中的 RRC DS1302_CLK = 1; DS1302_CLK = 0; ACC = ACC >> 1;

15、unsigned char DS1302OutputByte(void) /实时时钟读取一字节(内部函数) unsigned char i; for(i=8; i0; i) ACC = ACC 1; /相当于汇编中的 RRC ACC7 = DS1302_IO; DS1302_CLK = 1; DS1302_CLK = 0; return(ACC); void Write1302(unsigned char ucAddr, unsigned char ucDa)/ucAddr: DS1302地址, ucData: 要写的数据 DS1302_RST = 0; DS1302_CLK = 0; DS1

16、302_RST = 1; DS1302InputByte(ucAddr); / 地址,命令 DS1302InputByte(ucDa); / 写1Byte数据 DS1302_CLK = 1; DS1302_RST = 0; unsigned char Read1302(unsigned char ucAddr)/读取DS1302某地址的数据 unsigned char ucData; DS1302_RST = 0; DS1302_CLK = 0; DS1302_RST = 1; DS1302InputByte(ucAddr|0x01); / 地址,命令 ucData = DS1302Outpu

17、tByte(); / 读1Byte数据 DS1302_CLK = 1; DS1302_RST = 0; return(ucData);void DS1302_GetTime(SYSTEMTIME Time) /获取时钟芯片的时钟数据到自定义的结构型数组unsigned char ReadValue;ReadValue = Read1302(DS1302_SECOND);TimeSecond = (ReadValue0x70)>4)*10 + (ReadValue0x0F);ReadValue = Read1302(DS1302_MINUTE);Time>Minute = ((Rea

18、dValue&0x70)>>4)*10 + (ReadValue0x0F);ReadValue = Read1302(DS1302_HOUR);Time-Hour = ((ReadValue&0x70)4)*10 + (ReadValue0x0F);ReadValue = Read1302(DS1302_DAY);Time->Day = (ReadValue0x70)>>4)10 + (ReadValue0x0F);ReadValue = Read1302(DS1302_WEEK);Time->Week = (ReadValue&0x

19、70)>4)10 + (ReadValue&0x0F);ReadValue = Read1302(DS1302_MONTH);Time>Month = (ReadValue0x70)>4)*10 + (ReadValue0x0F);ReadValue = Read1302(DS1302_YEAR);TimeYear = (ReadValue0x70)>>4)*10 + (ReadValue0x0F);void DateToStr(SYSTEMTIME *Time) /将时间年,月,日,星期数据转换成液晶显示字符串,放到数组里DateString if(hi

20、de_year2) /这里的if,else语句都是判断位闪烁,2显示数据,2就不显示,输出字符串为 2007/07/22 Time-DateString0 = 2' Time-DateString1 = '0'; Time->DateString2 = TimeYear/10 + '0' TimeDateString3 = Time>Year%10 + 0' else Time>DateString0 = ; Time->DateString1 = ; Time>DateString2 = ' ; Time-

21、>DateString3 = ' 'Time>DateString4 = '/;if(hide_month2) Time->DateString5 = TimeMonth/10 + '0; Time-DateString6 = TimeMonth%10 + 0' else Time-DateString5 = ' ; Time>DateString6 = ' ' TimeDateString7 = /';if(hide_day<2) Time->DateString8 = Time>

22、;Day/10 + '0; TimeDateString9 = Time>Day10 + '0; else Time->DateString8 = ; TimeDateString9 = ' ; if(hide_week2) week_value0 = Time->Week10 + '0' /星期的数据另外放到 week_value数组里,跟年,月,日的分开存放,因为等一下要在最后显示 else week_value0 = ' ' week_value1 = 0';Time->DateString10 =

23、'0; /字符串末尾加 0 ,判断结束字符void TimeToStr(SYSTEMTIME *Time) /将时,分,秒数据转换成液晶显示字符放到数组 TimeString; if(hide_hour2) Time>TimeString0 = Time->Hour/10 + 0' Time->TimeString1 = TimeHour%10 + 0' else Time>TimeString0 = ' ; Time>TimeString1 = ;Time>TimeString2 = :'; if(hide_min&

24、lt;2) TimeTimeString3 = Time->Minute/10 + '0; TimeTimeString4 = Time>Minute%10 + 0'; else TimeTimeString3 = ' ' Time>TimeString4 = '; TimeTimeString5 = ':'; if(hide_sec<2) TimeTimeString6 = Time>Second/10 + 0; TimeTimeString7 = TimeSecond%10 + '0; else

25、Time->TimeString6 = ; Time-TimeString7 = ; TimeDateString8 = '0'void Initial_DS1302(void) /时钟芯片初始化 unsigned char Second=Read1302(DS1302_SECOND);if(Second&0x80) /判断时钟芯片是否关闭 Write1302(0x8e,0x00); /写入允许Write1302(0x8c,0x07); /以下写入初始化时间 日期:07/07/25。星期: 3。 时间: 23:59:55Write1302(0x88,0x07);W

26、rite1302(0x86,0x25);Write1302(0x8a,0x07);Write1302(0x84,0x23);Write1302(0x82,0x59);Write1302(0x80,0x55);Write1302(0x8e,0x80); /禁止写入/*ds18b20子程序*/*ds18b20延迟子函数(晶振12MHz )*/ void delay_18B20(unsigned int i)while(i-);/*ds18b20初始化函数*/void Init_DS18B20(void) unsigned char x=0; DQ = 1; /DQ复位 delay_18B20(8)

27、; /稍做延时 DQ = 0; /单片机将DQ拉低 delay_18B20(80); /精确延时 大于 480us DQ = 1; /拉高总线 delay_18B20(14); x=DQ; /稍做延时后 如果x=0则初始化成功 x=1则初始化失败 delay_18B20(20);/*ds18b20读一个字节*/ unsigned char ReadOneChar(void)uchar i=0;uchar dat = 0;for (i=8;i>0;i-) DQ = 0; / 给脉冲信号 dat>=1; DQ = 1; / 给脉冲信号 if(DQ) dat=0x80; delay_18

28、B20(4); return(dat);/*ds18b20写一个字节*/ void WriteOneChar(uchar dat) unsigned char i=0; for (i=8; i0; i) DQ = 0; DQ = dat&0x01; delay_18B20(5); DQ = 1; dat>=1; /*读取ds18b20当前温度*/void ReadTemp(void)unsigned char a=0;unsigned char b=0;unsigned char t=0;Init_DS18B20();WriteOneChar(0xCC); / 跳过读序号列号的操

29、作WriteOneChar(0x44); / 启动温度转换delay_18B20(100); / this message is wery importantInit_DS18B20();WriteOneChar(0xCC); /跳过读序号列号的操作WriteOneChar(0xBE); /读取温度寄存器等(共可读9个寄存器) 前两个就是温度delay_18B20(100);a=ReadOneChar(); /读取温度值低位b=ReadOneChar(); /读取温度值高位temp_value=b<4;temp_value+=(a&0xf0)4; void temp_to_str

30、() /温度数据转换成液晶字符显示 TempBuffer0=temp_value/10+0'; /十位 TempBuffer1=temp_value%10+0'; /个位 TempBuffer2=0xdf; /温度符号 TempBuffer3=C; TempBuffer4=0;void Delay1ms(unsigned int count)unsigned int i,j;for(i=0;i<count;i+)for(j=0;j<120;j+);/延时子程序*/void mdelay(uint delay)uint i; for(;delay0;delay-) f

31、or(i=0;i62;i+) /1ms延时。 ; void outkey() /跳出调整模式,返回默认显示 uchar Second; if(out=0wireless_1=1) mdelay(8); count=0;hide_sec=0,hide_min=0,hide_hour=0,hide_day=0,hide_week=0,hide_month=0,hide_year=0;Second=Read1302(DS1302_SECOND); Write1302(0x8e,0x00); /写入允许Write1302(0x80,Second0x7f);Write1302(0x8E,0x80); /

32、禁止写入done=0; while(out=0);while(wireless_1=1); /void Upkey()/升序按键 Up=1;if(Up=0|wireless_2=1) mdelay(8); switch(count) case 1: temp=Read1302(DS1302_SECOND); /读取秒数 temp=temp+1; /秒数加1 up_flag=1; /数据调整后更新标志 if(temp&0x7f)>0x59) /超过59秒,清零 temp=0; break; case 2: temp=Read1302(DS1302_MINUTE); /读取分数 te

33、mp=temp+1; /分数加1 up_flag=1; if(temp>0x59) /超过59分,清零 temp=0; break; case 3: temp=Read1302(DS1302_HOUR); /读取小时数 temp=temp+1; /小时数加1 up_flag=1; if(temp>0x23) /超过23小时,清零 temp=0; break; case 4: temp=Read1302(DS1302_WEEK); /读取星期数 temp=temp+1; /星期数加1 up_flag=1; if(temp0x7) temp=1; break; case 5: temp

34、=Read1302(DS1302_DAY); /读取日数 temp=temp+1; /日数加1 up_flag=1; if(temp0x31) temp=1; break; case 6: temp=Read1302(DS1302_MONTH); /读取月数 temp=temp+1; /月数加1 up_flag=1; if(temp0x12) temp=1; break; case 7: temp=Read1302(DS1302_YEAR); /读取年数 temp=temp+1; /年数加1 up_flag=1; if(temp>0x85) temp=0; break; default:break; while(Up=0); while(wireless_2=1); /

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

当前位置:首页 > 社会民生


经营许可证编号:宁ICP备18001539号-1