多通道温度巡检系统设计课程设计说明书
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
摘要
设计一个八路温度巡检系统,用八路DS18B20温度传感器分别检测外界八个不同地点的温度信息,通过AT89C51单片机接收八路温度传感器所返回的信息,经过单片机处理后将温度值和通道数等信息传输到LCD液晶显示器进行显示。
文中详细论述了温度传感器DS18B20的工作原理、温度信息处理过程、温度显示过程、系统的硬件设计方案以及软件程序设计。
关键词:八路温度巡检;DS18B20;AT89C51;LCD
目录
摘要I
1绪论 1
1.1 设计任务及意义 (1)
1.2 DS18B20温度检测原理 (1)
2 系统总体方案设计 (5)
2.1 系统总体方案框图 (5)
2.2 各模块的功能 (5)
3 硬件电路的设计 (6)
3.1 温度检测电路 (6)
3.2 液晶显示电路 (6)
3.2.1 LM016L介绍 (6)
3.2.2 LM01与51单片机的连接 (7)
3.3 晶振电路 (8)
3.4 复位电路 (8)
3.5 电源电路 (9)
4 系统软件设计 (10)
4.1 系统软件流程图 (10)
4.2 程序设计 (10)
4.2.1 DS18B20的程序设计 (10)
4.2.2 LM017L液晶的程序设计 (11)
4.2.3 主程序设计 (12)
5 系统仿真 (13)
5.1 仿真电路的设计 (13)
5.2 仿真结果 (13)
总结 (15)
参考文献 (16)
致谢 (17)
附录B 程序清单 (19)
八路温度巡检系统设计
1绪论
1.1 设计任务及意义
本设计实现八路温度检测,要求检测温度范围为-55~125摄氏度,用LCD液晶显示器同时显示测量温度值和通道编号,每3秒钟显示一路温度信息。
以摄氏度为单位,要求能够实现小数的显示。
温度检测在现实生活、生产当中应用比较普遍,而且起着相当大的作用,特别是一些工业的应用当中,温度的检测更是重要的环节,温度的检测和控制直接和安全生产、产品质量、生产效率、节约能源等重大技术指标相联系。
而多路温度的检测在一些范围比较大的施工场地或者监控现场的应用更是广泛,为应用者提供了现场多点的实时环境温度信息。
1.2 DS18B20温度检测原理
DS18B20是DALLAS公司生产的单总线式数字温度传感器,它具有
微型化、低功耗、高性能、抗干扰能力强、易配处理器等优点,特别
适用于构成多点温度测控系统,可直接将温度转化成串行数字信号
(提供9位二进制数字)给单片机处理,且在同一总线上可以挂接多
个传感器芯片。
它具有3引脚TO-92小体积封装形式(如图1.1),测
温范围为-55℃~+125℃,可编程为9位~12位A/D转换精度,测温分
辨率可达0.0625℃,被测温度用符号扩展的16位数字量方式串行输
出,其工作电源既可在远端引入,也可采用寄生电源方式产生,多个
DS18B20可以并联到3根或2根线上,CPU只需一根端口线就能与多个
DS18B20通信,占用微处理器的端口较少,可节省大量的引线和逻辑
电路。
DS18B20的内部结构:
(1)ROM
在DS18B20内部光刻了一个长度为64-bit的ROM,这个是编码器件
的身份识别标志,如下图所示:图1.1 DS18B20
图1.2 DS18B20的ROM
西华大学课程设计
64-bit光刻ROM的排列顺序是:开始(最低)8位是产品类型标号,对于DS18B20来说就是(28H);接着的48位是器件自身的序列号;最后8位是前面56位的循环冗余校验码(CRC=X8+X5+X4+1).光刻ROM的作用是使每个DS18B20都不相同,这样可以实现一根总线上挂接多个DS18B20的目的。
对ROM操作的几种指令:
(2)RAM
高速暂存存储器由9个字节组成,包含了8个连续字节,前面两个字节是测得的温度信息,第一个字节的内容是温度的低8位,第二个字节是温度的高8位。
第三个和第四个字节是温度高限TH和温度底限TL的暂存区,第五个字节是配置寄存器暂存区,第6、7、8、9字节是系统保留用,相当于DS18B20的运算内存,第9个字节是冗余校验字节。
RAM 内部字节分布如下表所示:
八路温度巡检系统设计
表1-1 DS18B20 RAM字节分布
对RAM操作的几种指令:
西华大学课程设计
(3)E2PROM
EEPROM只有三个字节,和RAM的第2、3、4字节的内容相对应,它的作用就是存储RAM 第2、3、4字节的内容,以使这些数据在掉电后不丢失。
可能通过几条命令将RAM的该3个字节内容复制到EEPROM或从EEPROM将该3个字节内容复制到RAM的第2、3、4字节去。
因为我们从外部想改写报警值和器件的设置都是只对RAM进行操作的。
要保存这些设置后的数据就还要用相应的命令将RAM的数据复制到EEPROM去。
DS18B20是单总线器件,通讯协议包括几种单线信号类型:复位脉冲、存在脉冲、写0、写1、读0、读1。
所有这些信号,除存在脉冲外,其余都是由总线控制器(单片机)发出的。
根据DS18B20的通讯协议,主机(单片机)控制DS18B20完成一次操作经过三个步骤:
①要对DS18B20进行复位操作;
②复位成功后发送一条ROM指令;
③最后发送RAM指令,这样才能对DS18B20进行预定的操作。
八路温度巡检系统设计
2 系统总体方案设计
系统采用一片AT89C51芯片、八个DS18B20温度传感器和一个LCD液晶显示器,将八个DS18B20并联在单片机的同一个I/O口上,这样可以达到节约I/O的目的,至于单片机怎样分别去读取每一个温度传感器的温度信息,则由软件部分考虑。
2.1 系统总体方案框图
八路温度巡检系统的总体设计框图如图2.1所示:
图2.1八路温度巡检系统框图
2.2 各模块的功能
温度传感器DS18B20可实施对外界温度的检测,检测到的温度会保存在自身的ROM 里。
而对DS18B20的读写控制操作都是通过一根DQ信号线来完成的,对它的操作要严格按照时序进行,这使得对它的编程增加了难度。
而同时正是DS18B20的一线性,使它可以轻松地在AT89C51的控制下组成八路检测系统。
AT89C51检测到温度信息后对其进行处理,还原其真实温度,并将其显示在LCD上。
LCD液晶显示器主要负责显示从单片机处所传来的温度值和通道数等信息,并且将八路的信息进行循环显示。
西华大学课程设计
3 硬件电路的设计
3.1 温度检测电路
八个DS18B20与51单片机的电路连接入图3.1所示:
图3.1 温度检测电路连线图
八个DS18B20的DQ口都同时并联在单片机的P1.0口上。
3.2 液晶显示电路
3.2.1 LM017L介绍
字符型LM017L是一款能显示两行且每行能显示32个字符的液晶显示屏。
通常采用日立公司生产的控制器HD44780作为LCD的控制芯片。
凡是是基于HD44780液晶芯片的,控制原理是完全相同的,因此HD44780写的控制程序可以方便地应用于市面上大部分的字符型液晶。
LM017的外形如图3.2所示:
八路温度巡检系统设计
图3.2 LM017L
LM017L的引脚功能如下表所示:
表3-1 LM017L的引脚功能表
3.2.2 LM017L与51单片机的连接
LM017L与51单片机的接口原理图如图3.3所示:
西华大学课程设计
图3.3 LM017L与单片机的连接图
3.3 晶振电路
晶振是给单片机提供工作信号脉冲的,这个脉冲就是单片机的工作速度,比如12M 晶振,单片机工作速度就是每秒12M,和电脑的CPU概念一样。
当然,单片机的工作频率是有范围的,不能太大,一般不能超过24M,不然就会不稳定了。
51系列单片机的时钟信号通常有两种电路形式:内部振荡方式和外部震荡方式。
在引脚X1和X2外接晶体振荡器,就构成了内部振荡电路,如图3.4所示。
晶振与单片机的脚X1和脚X2构成的振荡电路中会产生偕波,这个波对电路的影响不大,但会降低电路的时钟振荡器的稳定性。
为了电路的稳定性起见,ATMEL公司建议在晶振的两引脚处接入两个10pF~50pF的瓷片电容接地来削减偕波对电路的稳定性的影响,所以晶振所配的电容在10Pf~50pF之间都可以的,没有什么计算公式。
这两个电容除了稳定振荡频率,还可以起到快速起振的作用。
晶振常选用频率为6MHz、12MHz或24MHz的,采用串口时常使用频率为11.0592MHz的晶振。
内部振荡方式所得到的时钟信号比较稳定,应用较多。
图3.4 晶振电路
3.4 复位电路
单片机在启动时都需要复位,以使CPU及系统各部件处于确定的初始状态,并从初态开始工作。
89系列单片机的复位信号是从RST引脚输入到芯片内的施密特触发器中的。
当系统处于正常工作状态时,且振荡器稳定后,如果RST引脚上有一个高电平并维持2个机器周期(24个振荡周期)以上,则CPU就可以响应并将系统复位。
单片机系统的复位方式有:手动按钮复位和上电复位,本设计中采用的是手动按钮复位方式。
手动按钮复位需要人为在复位输入端RESET上加入高电平。
一般采用的办法是在RESET端和正电源Vcc之间接一个按钮。
当人为按下按钮时,则Vcc的+5V电平就会直接加到RESET端,也可以直接在另一端接一个+5V电源。
手动按钮复位的电路如3.5所示。
由于人的动作再快也会使按钮保持接通达数十毫秒,所以,完全能够满足复位的时间要求。
图3.5 复位电路
3.5 电源电路
在本系统中,有很多芯片都需要电源,所以需要设计一个电源模块。
电源电路原理图如图3.6所示。
220V的交流电经变压器T1降压后,得到+9V的交流电,再经过桥式整流和电容滤波的作用,最终得到+5V的直流电,为系统提供电源。
三端稳压器7805在电路中起稳压作用,交流电经整流滤波后,由三端稳压器稳压后,输出稳定的直流电。
图3.6 电源电路
4 系统软件设计
本次设计采用的编程语言是C51语言,开发工具是Keil μVision4版本。
4.1系统软件流程图
系统的软件流程图如下图所示:
图4.1 系统软件流程图
4.2程序设计
4.2.1DS18B20的程序设计
DS18B20的程序中主要包含以下函数:
extern void ds18b20_init(void); //初始化
extern unsigned char ds18b20_readdata(void); //读DS18b20的温度数据extern void ds18b20_writecommand(unsigned char command);//向DS18B20写命令字extern void temperature_process(unsigned char,unsigned char); //数值处理,把读回的温度分解成整数和小数部分,并转换成ASIC码
//存放在xiaoshu_temp[5],zhen_temp[4];
extern unsigned char *read_rom(void); //读DS18b20中ROM
extern bit match_rom(unsigned char *rom); //匹配ROM
具体程序内容见附录B中。
4.2.2LM017L液晶的程序设计
LM017L的程序中主要包含以下函数:
/**************************************************************
**功能:写LCD函数**
**************************************************************/
void Lcd_Write(bit style,unsigned char input);
/****************************************************************
**功能:LCD初始化*
****************************************************************/
void Lcd_Init(void);
/****************************************************************
**功能:显示位置设置**
**参数:x-行;y-列**
****************************************************************/
void GotoXY(unsigned char x,unsigned char y);
/****************************************************************
**功能:LCD显示函数**
**参数:str-要显示的字符串指针**
****************************************************************/
void Print(unsigned char *str);
void print_char(uchar );
/****************************************************************
**功能:LCD清屏函数
void ClrScreen(void);
具体程序内容见附录B中。
4.2.3主程序设计
在主程序中,实现了对温度的巡检,并把实时测到的温度显示在液晶显示屏上,在很多领域还是比较实用的。
每一片DS18B20都有各自的固定的序列号,在仿真中,事先设定好各个DS18B20的序列号,将其写进程序中,依次进行匹配,从而实现巡检。
主程序具体内容见附录B中。
5 系统仿真
5.1 仿真电路的设计
用Proteus软件设计的方针电路图如下图所示:
图5.1 Proteus仿真电路
5.2仿真结果
在Keil中编译程序直至通过,生成HEX文件,将该HEX文件载入Proteus中的AT89C51芯片中,设置晶振为12MHz,运行仿真,结果如下图所示:
图5.2 Proteus仿真结果
总结
(1)本次设计完成了要求的基本的功能,实现了八路温度传感器的实时巡检,但在软件的设计方面存在占用内存空间较大,程序的冗余度较大的问题。
这是由于作者对C语言的程序设计不够熟练,在设计时,没有能够采用一些更为灵活的方法使程序简化所致。
随着以后的学习,相信在这一方面可以有一个较大的长进,实现本设计的程序优化。
(2)由于作者没有相关的软硬件联合设计方面的经验,致使在本设计进行过程中,产生以软件设计为主,而忽略硬件的思维,在设计时浪费了不少时间。
后来随着相关知识的深入,慢慢调整了设计理念,开始以硬件为先,软件为硬件服务的方法设计。
这使得设计的进展加快了,同时使得硬件的设计更为简化,更易懂。
(3)在此次设计用一个I/O同时并联8个DS18B20,这样一来,导致软件程序的编写更加复杂,耗费了较多的时间和精力。
参考文献
[1] 黄惟公、邓成中、王燕,单片机原理与应用技术,西安电子科技大学出版社,2007
[2] 黄惟公、邓成中,单片机原理与接口技术(C51版),西华大学机械工程与自动化学院,2011
[3]戴蓉、游凤荷、周景霞,由单片机和多片DS1820组成的多点温度测控系统,国外电子元器件,2001
[4] 赵建领,Protel电路设计与制版宝典,电子工业出版社,2007
[5] 郭伟、潘巍,基于单片机八路温度巡检系统设计,实践与探索,2011
[6] 周四清、罗雪峰、何献华,基于DS18B20 的八路温度巡检仪的设计与应用,科技创新导报,2008 [8] 李玉峰、倪虹霞,MCS-51系列单片机原理与接口技术,人民邮电出版社,2004
致谢
在这次课程设计的过程中,我获益匪浅,学到了很多以前不知道的新知识。
首先我要感谢我的指导老师在此次课程设计上给予我的指导、让我能够很快的完成这次的设计,少走了很多的弯路,这是我能顺利完成这次设计并撰写好说明书的主要原因,更重要的是老师帮我解决了许多技术上的难题,让我能把系统做得更加完善,但由于我的能力水平有限,在这次的设计中还存在许多的不足,希望老师能够帮我指出来。
在此期间,我不仅让曾经学过的专业知识得到了实践,还学到了许多新的知识,而且也开阔了视野,提高了自己的设计能力。
其次,我要感谢和我同实验室的师兄,以及那些帮助过我的同学,他们也为我解决了不少我不太明白的设计上的难题。
同时也感谢学院为我提供良好的做设计的环境,此次的亲身设计经历让我永生难忘。
最后再一次感谢所有在设计中曾经帮助过我的良师益友和同学!
附录A 八路温度巡检系统电路原理图
附录B 程序清单
主程序如下:
#include "lcd1602.h"
#include "ds18b20.h"
unsigned char temp[5];
uchar ds18b20_num1[8]={0xfd,0x00,0x00,0x00,0xb8,0xc5,0x45,0x28};//第1路温度序列号uchar ds18b20_num2[8]={0x8e,0x00,0x00,0x00,0xb8,0xc5,0x30,0x28};//第2路温度序列号uchar ds18b20_num3[8]={0xb9,0x00,0x00,0x00,0xb8,0xc5,0x31,0x28};//第3路温度序列号uchar ds18b20_num4[8]={0xe0,0x00,0x00,0x00,0xb8,0xc5,0x32,0x28};//第4路温度序列号uchar ds18b20_num5[8]={0xd7,0x00,0x00,0x00,0xb8,0xc5,0x33,0x28}//第5路温度序列号; uchar ds18b20_num6[8]={0x52,0x00,0x00,0x00,0xb8,0xc5,0x34,0x28};//第6路温度序列号uchar ds18b20_num7[8]={0x65,0x00,0x00,0x00,0xb8,0xc5,0x35,0x28};//第7路温度序列号uchar ds18b20_num8[8]={0x3c,0x00,0x00,0x00,0xb8,0xc5,0x36,0x28};//第8路温度序列号void delay(unsigned int time)
{
unsigned int i,j;
for(i=0;i<time;i++)
for(j=0;j<200;j++);
}
void main(void)
{
uchar i;unsigned char a[3]={0xdf,'C','\0'};
char *str1="1:";
char *str2="2:";
char *str3="3:";
char *str4="4:";
Lcd_Init();
ClrScreen();
dot_dis=1;
while(1)
{
/*The first page...........................................*/ ClrScreen();
ds18b20_init();
ds18b20_writecommand(0xcc);
ds18b20_writecommand(0x44);
delay(500);
match_rom(ds18b20_num1); //匹配第一路ds18b20_writecommand(0xbe);
for(i=0;i<2;i++)
{
temp[i]=ds18b20_readdata();
}
temperature_process(temp[0],temp[1]); GotoXY(12,0);
Print(a);
GotoXY(29,0);
Print(a);
GotoXY(12,1);
Print(a);
GotoXY(29,1);
Print(a);
GotoXY(2,0);
Print(str1);
if(!flag) //正
{
Print(zhen_temp);
if(dot_dis)
Print(".");
Print(xiaoshu_temp);
}
else //负
{
Print("-");
Print(zhen_temp);
if(dot_dis)
Print(".");
Print(xiaoshu_temp);
}
ds18b20_init();
ds18b20_writecommand(0xcc);
ds18b20_writecommand(0x44);
delay(500);
match_rom(ds18b20_num2); //匹配第二路ds18b20_writecommand(0xbe);
for(i=0;i<2;i++)
{
temp[i]=ds18b20_readdata();
}
temperature_process(temp[0],temp[1]); GotoXY(19,0);
Print(str2);
if(!flag) //正
{
Print(zhen_temp);
if(dot_dis)
Print(".");
Print(xiaoshu_temp);
}
else //负
{
Print("-");
Print(zhen_temp);
if(dot_dis)
Print(".");
Print(xiaoshu_temp);
}
ds18b20_init();
ds18b20_writecommand(0xcc);
ds18b20_writecommand(0x44);
delay(500);
match_rom(ds18b20_num3); //匹配第三路ds18b20_writecommand(0xbe);
for(i=0;i<2;i++)
{
temp[i]=ds18b20_readdata();
}
temperature_process(temp[0],temp[1]); GotoXY(2,1);
Print(str3);
if(!flag) //正
{
Print(zhen_temp);
if(dot_dis)
Print(".");
Print(xiaoshu_temp);
}
else //负
{
Print("-");
Print(zhen_temp);
if(dot_dis)
Print(".");
Print(xiaoshu_temp);
}
ds18b20_init();
ds18b20_writecommand(0xcc);
ds18b20_writecommand(0x44);
delay(500);
match_rom(ds18b20_num4); //匹配第四路ds18b20_writecommand(0xbe);
for(i=0;i<2;i++)
{
temp[i]=ds18b20_readdata();
}
temperature_process(temp[0],temp[1]); GotoXY(19,1);
Print(str4);
if(!flag) //正
{
Print(zhen_temp);
if(dot_dis)
Print(".");
Print(xiaoshu_temp);
}
else //负
{
Print("-");
Print(zhen_temp);
if(dot_dis)
Print(".");
Print(xiaoshu_temp);
}
delay(1000);
ClrScreen();
ds18b20_init();
ds18b20_writecommand(0xcc);
ds18b20_writecommand(0x44);
delay(500);
match_rom(ds18b20_num5); //匹配第五路ds18b20_writecommand(0xbe);
for(i=0;i<2;i++)
{
temp[i]=ds18b20_readdata();
}
temperature_process(temp[0],temp[1]); GotoXY(12,0);
Print(a);
GotoXY(29,0);
Print(a);
GotoXY(12,1);
Print(a);
GotoXY(29,1);
Print(a);
GotoXY(2,0);
Print("5:");
if(!flag) //正
{
Print(zhen_temp);
if(dot_dis)
Print(".");
Print(xiaoshu_temp);
}
else //负
{
Print("-");
Print(zhen_temp);
if(dot_dis)
Print(".");
Print(xiaoshu_temp);
}
ds18b20_init();
ds18b20_writecommand(0xcc);
ds18b20_writecommand(0x44);
delay(500);
match_rom(ds18b20_num6); //匹配第六路ds18b20_writecommand(0xbe);
for(i=0;i<2;i++)
{
temp[i]=ds18b20_readdata();
}
temperature_process(temp[0],temp[1]); GotoXY(19,0);
Print("6:");
if(!flag) //正
{
Print(zhen_temp);
if(dot_dis)
Print(".");
Print(xiaoshu_temp);
}
else //负
{
Print("-");
Print(zhen_temp);
if(dot_dis)
Print(".");
Print(xiaoshu_temp);
}
ds18b20_init();
ds18b20_writecommand(0xcc);
ds18b20_writecommand(0x44);
delay(500);
match_rom(ds18b20_num7); //匹配第七路ds18b20_writecommand(0xbe);
for(i=0;i<2;i++)
{
temp[i]=ds18b20_readdata();
}
temperature_process(temp[0],temp[1]); GotoXY(2,1);
Print("7:");
if(!flag) //正
{
Print(zhen_temp);
if(dot_dis)
Print(".");
Print(xiaoshu_temp);
}
else //负
{
Print("-");
Print(zhen_temp);
if(dot_dis)
Print(".");
Print(xiaoshu_temp);
}
ds18b20_init();
ds18b20_writecommand(0xcc);
ds18b20_writecommand(0x44);
delay(500);
match_rom(ds18b20_num8); //匹配第八路ds18b20_writecommand(0xbe);
for(i=0;i<2;i++)
{
temp[i]=ds18b20_readdata();
}
temperature_process(temp[0],temp[1]); GotoXY(19,1);
Print("8:");
if(!flag) //正
{
Print(zhen_temp);
if(dot_dis)
Print(".");
Print(xiaoshu_temp);
}
else //负
{
Print("-");
Print(zhen_temp);
if(dot_dis)
Print(".");
Print(xiaoshu_temp);
}
delay(1000);
}
while(1);
}
/**************************************************************
**lcd1602.h头文件**
**功能LCD1602驱动函数的申明** **创建人:xingyuegu **
**创建日期:2006-7-13 **
**版本:1.0 **
**************************************************************/
#ifndef _LCD1602_H_
#define _LCD1602_H_
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
/***接口定义*************************************************/
sbit LcdRs =P2^0;
sbit LcdRw =P2^1;
sbit LcdEn =P2^2;
sfr DBPort =0x80;
/************************************************************* **功能:判断LCD忙**
**参数:无**
*************************************************************/ unsigned char Lcd_Wait(void);
/************************************************************** **功能:写LCD函数**
**参数:style为写命令/数据,0-命令,1-数据;input为写入的8位** ** 命令/数据**
**************************************************************/ #define Lcd_Command 0
#define Lcd_Data 1
#define Lcd_Clear_Screen 0x01
#define Lcd_Home 0x02
void Lcd_Write(bit style,unsigned char input);
/*************************************************************** **功能:设置显示模式**
**参数:**
***************************************************************/ #define Lcd_Display_On 0x04
#define Lcd_Display_Off 0x00
#define Lcd_Cursor 0x02
#define Lcd_No_Cursor 0x00
#define Lcd_Flash 0x01
#define Lcd_No_Flash 0x00
void Lcd_SetDisplay(unsigned char DisplayMode);
/***************************************************************
**功能:LCD移动设置**
**参数:取值如下**
***************************************************************/ #define Lcd_CursorMove 0x00
#define Lcd_PictureMove 0x08
#define Lcd_Left 0x00
#define Lcd_Right 0x04
void Lcd_Move(unsigned char MoveMode);
/**************************************************************** **功能:LCD输入设置**
**参数:取值如下**
****************************************************************/
#define Lcd_Ac_Up 0x02
#define Lcd_Ac_Down 0x00
#define Lcd_Move_To 0x01
#define Lcd_No_Move 0x00
void Lcd_SetInput(unsigned char InputMode);
/**************************************************************** **功能:LCD初始化**
**参数:取值如下**
****************************************************************/ void Lcd_Init(void);
/**************************************************************** **功能:显示位置设置**
**参数:x-行;y-列**
****************************************************************/ void GotoXY(unsigned char x,unsigned char y);
/**************************************************************** **功能:LCD显示函数**
**参数:str-要显示的字符串指针**
****************************************************************/ void Print(unsigned char *str);
void print_char(uchar );
/****************************************************************
**功能:LCD清屏函数**
**参数:无**
****************************************************************/ void ClrScreen(void);
/****************************************************************
**功能:LCD归位函数**
**参数:无**
****************************************************************/
//void Screen_home(void);
#endif
/******************************************************************* **函数功能:LCD的驱动函数**
**
**修改日期:2008-10-30 **
**版本:3.0 **
*******************************************************************/ #include "lcd1602.h"
#define uchar unsigned char
#define uint unsigned int
/*************************************************************
**功能:延时1.64ms **
**参数:无**
*************************************************************/
void delay1_64ms(void)
{
uchar i;
for(i = 0;i < 250;i++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
/************************************************************* **功能:延时40us **
**参数:无**
*************************************************************/ /*void delay40us(void)
{
uchar i;
for(i = 0;i < 20;i++)
{
;
}
}*/
/************************************************************* **功能:判断LCD忙**
**参数:无**
*************************************************************/ unsigned char Lcd_Wait(void)
{
while(1)
{
DBPort=0xff;
LcdEn=0;
_nop_();
LcdRs=0;
_nop_();
_nop_();
LcdRw=1;
_nop_();
_nop_();
LcdEn=1;
_nop_();
_nop_();
_nop_();
_nop_();
if((DBPort&0x80)==0)
{
break;
}
LcdEn=0;
}
//delay40us();
return DBPort;
}
/************************************************************** **功能:写LCD函数**
**参数:style为写命令/数据,0-命令,1-数据;input为写入的8位** ** 命令/数据**
**************************************************************/ void Lcd_Write(bit style,unsigned char input)
{
LcdEn=0;
_nop_();
_nop_();
LcdRs=style;
_nop_();
_nop_();
LcdRw=0;
DBPort=input;
_nop_();
_nop_();
LcdEn=1;
_nop_();
_nop_();
LcdEn=0;
_nop_();
Lcd_Wait();
}
/**************************************************************** **功能:LCD清屏函数**
**参数:无**
****************************************************************/ void ClrScreen(void)
{
Lcd_Write(Lcd_Command,Lcd_Clear_Screen);
//delay1_64ms();
}
/**************************************************************** **功能:LCD归位函数**
**参数:无**
****************************************************************/ /*void Screen_home(void)
{
Lcd_Write(Lcd_Command,Lcd_Home);
//delay1_64ms();
}*/
/*************************************************************** **功能:设置显示模式**
**参数:**
***************************************************************/ void Lcd_SetDisplay(unsigned char DisplayMode)
{
Lcd_Write(Lcd_Command,0x08|DisplayMode);
}
/***************************************************************
**功能:LCD移动设置**
**参数:取值如下**
**************************************************************
void Lcd_Move(unsigned char MoveMode)
{
Lcd_Write(Lcd_Command,0x10|MoveMode);
}
/****************************************************************
**功能:LCD输入设置**
**参数:取值如下**
****************************************************************/
void Lcd_SetInput(unsigned char InputMode)
{
Lcd_Write(Lcd_Command,0x04|InputMode);
}
/****************************************************************
**功能:LCD初始化**
**参数:取值如下**
****************************************************************/
void Lcd_Init(void)
{
delay1_64ms();
Lcd_Write(Lcd_Command,0x38); //8位数据端口,2行显示,5*7点阵
Lcd_Write(Lcd_Command,0x38);
Lcd_Write(Lcd_Command,0x38);
Lcd_SetDisplay(Lcd_Display_On); //开启显示, 无光标|Lcd_Cursor|Lcd_Flash
//Lcd_Move(Lcd_CursorMove|Lcd_Left);
Lcd_SetInput(Lcd_Ac_Up|Lcd_No_Move); //AC递增, 画面不动_To }
/**************************************************************** **功能:显示位置设置**
**参数:x-行;y-列**
****************************************************************/ 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));
}
}
/**************************************************************** **功能:LCD显示函数**
**参数:str-要显示的字符串指针**
****************************************************************/ void Print(unsigned char *str)
{
while(*str!='\0')
{
Lcd_Write(Lcd_Data,*str);
str++;
}
}
void print_char(uchar a)
{
if(a>=0&&a<=9)
Lcd_Write(Lcd_Data,a+'0');
else if(a>=0x0a &&a<= 0x0f)
Lcd_Write(Lcd_Data,a+0x37);
}
// DS18B20的头文件如下:
#ifndef _DS18B20_H_
#define _DS18B20_H_
//DS18b20数据线接口及需要的数组等
sbit DQ=P1^0;
extern unsigned char temp[5];
extern char xiaoshu_temp[5],zhen_temp[4];
extern bit flag;
extern bit dot_dis;
extern void ds18b20_init(void); //初始化
extern unsigned char ds18b20_readdata(void); //读DS18b20的温度数据extern void ds18b20_writecommand(unsigned char command);//向DS18B20写命令字extern void temperature_process(unsigned char,unsigned char); //数值处理,把读回的温度分解成整数和小数部分,并转换成ASIC码
//存放在xiaoshu_temp[5],zhen_temp[4];
extern unsigned char *read_rom(void); //读DS18b20中ROM
extern bit match_rom(unsigned char *rom); //匹配ROM
#endif
/*******************************************************************
**函数功能:ds18b20的驱动函数**
**修改日期:2008-10-30 **
**版本:3.0 **
*******************************************************************/
#include <reg52.h>
#include <intrins.h>
#include "ds18b20.h"
#define uchar unsigned char
#define uint unsigned int
void process(unsigned char,unsigned char);
char volatile xiaoshu_temp[5],zhen_temp[4]; //
bit flag;
bit dot_dis=1;
//sbit DQ=P1^0;
extern unsigned char temp[5];
/************************************************************* **功能:延时600us **
**参数:无**
*************************************************************/ void delay600us(void)
{
uchar i;
for(i=0;i<255;i++);
}
/************************************************************* **功能:延时60us **
**参数:无**
*************************************************************/ void delay60us(void)
{
uchar i;
for(i=0;i<20;i++);
}
/*************************************************************
**功能:延时240us **
**参数:无**
************************************************************ void delay240us(void)
{
uchar i;
for(i=0;i<80;i++);
}
/************************************************************* **功能:延时18us **
**参数:无**
*************************************************************/ /*void delay15us(void)
{
uchar i;
for(i=0;i<2;i++);
}*/
/************************************************************* **功能:复位脉冲**
**参数:bool **
*************************************************************/ bit resetpulse(void)
{
DQ=0;
delay600us(); //延时500us
DQ=1;
delay60us(); // 延时60us
return(DQ); //读取DQ的状态
}
/************************************************************* **功能:ds18b20的初始化**
**参数:无**
*************************************************************/ void ds18b20_init(void)
{
while(1)
{
if(!resetpulse()) //收到ds18b20的应答信号
{
//delay240us(); //延时240us
DQ=1;
delay600us(); //延时240us
break;
}
else
resetpulse(); //否则再发复位信号
}
}
/************************************************************* **功能:向ds18b20写命令**
**参数:无**
*************************************************************/ void ds18b20_writecommand(uchar command)
{
uchar i;
for(i=0;i<8;i++)
{
if((command & 0x01)==0)
{
DQ=0; //写0
delay60us(); //延时60us
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
DQ=1;
_nop_();
_nop_();
}
else //写1
{
DQ=0;
_nop_();
_nop_(); //延时2us
DQ=1;
delay60us(); //延时60us
_nop_();
_nop_();
_nop_();
_nop_();
}
command=_cror_(command,1); // 右移1位
}
}
/************************************************************* **功能:读ds18b20数据**
**参数:返回读到的数据**
*************************************************************/ uchar ds18b20_readdata(void)
{
uchar readdata;
uchar i;
for(i=0;i<8;i++)
{
DQ=0;
_nop_();
_nop_();
_nop_();
DQ=1; //释放总线
//delay15us(); 注意不需要
if(DQ==0) //如果读到的是0
{
readdata=readdata&0x7f;
delay60us();
}
else //读到的是1
{
readdata=readdata|0x80;
delay60us();
}
if(i<7)
readdata=_cror_(readdata,1);
}
return readdata;
}
/************************************************************* **功能: 温度处理函数**
**参数:无返回**
*************************************************************/ void temperature_process(uchar low,uchar high)
{
uint temp1,temp2,temp3;
if(high&0x80) //判断正负
{
flag=1; //负温度
temp3=temp3|high;
temp3=temp3&0x00ff;
temp3=temp3<<8;
temp1=temp3;
temp1=temp1|low;
temp1=(temp1^0xffff);
temp1=temp1+1; //取反加1
low=temp1&0x000f;
high=temp1>>4;
process(high,low);
}
else
{
flag=0; //正温度
temp1=high;
temp2=low;
temp1=temp1<<4;
temp2=temp2>>4;
temp3=temp1|temp2;
high=temp3;
low=low&0x0f;
process(high,low);
}
}
/*************************************************************** **功能: 数值处理,把读回的温度分解成整数和小数部分,并转换成ASIC码
**
**参数:存放在xiaoshu_temp[5],zhen_temp[4] 中
****************************************************************/ void process(unsigned char high,unsigned char low)
{
uint temp1;
uchar i;
temp1=low*625;
xiaoshu_temp[0]=temp1/1000+'0';
xiaoshu_temp[1]=temp1/100%10+'0'; xiaoshu_temp[2]=temp1%100/10+'0'; xiaoshu_temp[3]=temp1%10+'0';
xiaoshu_temp[4]='\0';
dot_dis=1;
if(xiaoshu_temp[3]=='0')
{
xiaoshu_temp[3]='\0';
if(xiaoshu_temp[2]=='0')
{
xiaoshu_temp[2]='\0';
if(xiaoshu_temp[1]=='0')
{
xiaoshu_temp[1]='\0';
if(xiaoshu_temp[0]=='0')
{
xiaoshu_temp[0]='\0';
dot_dis=0;
}
else
dot_dis=1;
}
}
}
zhen_temp[0]=high/100+'0';
zhen_temp[1]=high%100/10+'0';
zhen_temp[2]=high%10+'0';
zhen_temp[3]='\0';
for(i=0;i<2;i++)
if(zhen_temp[0]=='0')
{
zhen_temp[0]=zhen_temp[1];
zhen_temp[1]=zhen_temp[2];
zhen_temp[2]='\0';
}
else
break;
}
/************************************************************* **功能: 读序列号子程序**
*************************************************************/ uchar *read_rom(void)
{
uchar rom[8],i;
ds18b20_init();
ds18b20_writecommand(0x33);
for(i=8;i>0;i--)
{
rom[i-1]=ds18b20_readdata();
}
return &rom[0];
}
/************************************************************* **功能:序列号匹配子程序
*************************************************************/ bit match_rom(uchar *rom)
{
uchar i;
ds18b20_init();
ds18b20_writecommand(0x55);
for(i=8;i>0;i--)
{ ds18b20_writecommand(*(rom+i-1));
}
return 1;
}。