DS18B20课程设计Word格式.docx
《DS18B20课程设计Word格式.docx》由会员分享,可在线阅读,更多相关《DS18B20课程设计Word格式.docx(26页珍藏版)》请在冰点文库上搜索。
在芯片匹配完成后,接下来就是存储器操作。
指令共8为6条,指令代表着芯片将进行什么样的工作,是芯片的关键。
5执行读写:
指令和温度数据都是通过对芯片的读写操作进行的,应严格按照数据手册时序图。
温度传感器硬件连接:
DS18B20为单总线连接,只需接电源和地,将数据线连接在单片机IO口即可,因为DS18B20内部开漏,所以需加10K的上拉电阻,以保证温度传感器正常工作。
也可以连接寄生电源模式,此处不用不做详细介绍。
操作时序图:
1复位及应答时序:
2写时序:
3读时序:
注:
未尽说明详见达拉斯官方英文数据手册。
一、单片机
单片机介绍:
单片机采用STC89C52,PDIP-40封装。
该单片机是STC推出的新一代高速、低功耗、超强抗干扰的单片机,指令代码完全兼容传统8051单片机,12时钟和6时钟可任意选择,HD版本和90C版本内部集成MAX810专用复位电路。
单片机参数:
型号:
STC89C52RCPDIP-40
工作电压:
5.5-3.3V
最高时钟频率:
0-80M
Flash:
8K
SRAM:
512
定时器:
3个
UART串口:
1个
DPTR:
2
EEPRM:
4K
看门狗:
有
中断源:
8个
中断优先级:
4级
IO:
35/39
掉电唤醒中断:
4个
内置复位:
封装:
40-PinPDIP44-PinLQFP/PLCC
引脚图:
电路连接图:
最小系统:
更多详细资料参考STC官网数据手册
三、晶振
介绍:
此系统采用12M高精度晶振,接与单片机18、19脚,并接30pf电容对地,帮助晶振起振,使系统更稳定。
电路:
四、复位电路
系统正常工作必要条件,上电自动复位。
五、继电器控制电路
因为单片机IO端口输出电流较小,故需三极管对其驱动,为缩小体积三极管使用贴片型S8550。
当控制端输出低电平,三极管饱和导通使继电器吸合,继电器在断电时会产生感应电动势,为防止冲击损坏单片机和三极管,在继电器两端反向并联IN4148二极管以吸收感应电流。
继电器采用10A大功率继电器,可控制大功率电器,工作电压5V。
六、声光报警电路
声音报警使用采用5V有源蜂鸣器,使用S8550驱动发生,当温度达到上限和下限时均可报警,发出滴~滴~声。
光报警电路使用两只发光二极管分别显示上下限,报警时为常量,单片机IO直接驱动。
实际电路图:
蜂鸣器
二极管
七、键盘
按键使用4个5*5微动,功能分别是设置、加、减,第四个按键暂时不用,为日后系统升级预留,连接方式为独立按键。
电路图
八、电源
一个单片机系统离不开电源。
本系统有两种供电方式,一种使用5VUSB直接供电,一种使用9V叠层电池供电,经7805芯片稳压后,为系统提供5V电源,此为移动需求。
用一个双刀双掷开关切换。
九、显示部分
为实现人机交换离不开显示部分,此系统采用两个三位八段的数码管显示,显示方式为动态扫描,用两片74HC573锁存器分别驱动位和段,数码管为共阴数码管。
一十、整机电路:
第二部分、软件系统
/**********************************************************************************
程序名:
DS18B20温度计
设计者:
高鹏展
单位:
河南工业职业技术学院
编写时间:
2012年04月28日
硬件支持:
STC89C52RC
系统时钟:
12MHz
接口说明:
DS18B20总线接MCU的P2^2口
修改日志:
2012/4/2922:
00:
00实现小数-50.0~125.0测温功能下一步实现温度报警功能
2012/4/3017:
19:
00小数点BUG解决通过调整点的显示时间
2012/4/3019:
18:
00实现上下限温度设定
2012/4/3022:
00:
00上限蜂鸣报警
2012/5/0110:
05:
00取消蜂鸣器,定时器
2012/5/0221:
41:
00程序编写完毕
实现上下限温度设定,包括负温度
快速温度转换
精确小数点后一位
等
2012/5/1613:
55:
00制作实物修改接口定义
2012/5/0421:
00功能完美实现
下一步计划使用EEPROM
2012/5/1714:
06:
00取消温度误差调整
BUG:
开机会显示85c2012/5/01此BUG解决开机读一次温度并延时
小数点过亮2012/4/3017:
小数点过亮2012/4/3019:
10:
00小数点后加空显示问题完美解决
数码管还需要消影2012/4/3019:
00解决
开定时器0会乱码不使用定时器实现蜂鸣器间隔响
备注:
版本V1.02012/5/2
默认上限26下限25
基于Keil4开发环境
**********************************************************************************/
#include<
reg52.h>
intrins.h>
#defineuintunsignedint
#defineucharunsignedchar
sbitled1=P1^0;
//下限指示灯
sbitled2=P1^1;
//上限指示灯
sbitJDQ1=P2^0;
//下限继电器
sbitJDQ2=P2^1;
//上限继电器
sbitFM=P2^5;
//蜂鸣器
sbitSET=P3^4;
//设置键
sbitjian=P3^5;
//减键
sbitjia=P3^6;
//加键
sbitDQ=P2^2;
//定义总线接口
sbitwela=P2^7;
//定义位锁存端
sbitdula=P2^6;
//定义段锁存端
voidinit();
//初始化总程序
voiddelay_18B20(uintt);
//延时
ucharinit_DS18B20();
//初始化
voidwrite_DS18B20(uchardat);
//写数据
ucharread_DS18B20();
//读数据
intreadtemp();
//读取温度有符号型
voidtempp_18B20();
//主程序温度处理
voidSET_alarm();
//报警温度设置
inttempp;
//定义运算变量
voidtemp_alarm();
//温度报警
uintbai,shi,ge,dian;
//定义温度位
ucharzf;
//定义显示正负
intshangxian=500;
//定义默认上限数值26C
intxiaxian=200;
//定义默认下限数值25C
ucharMODE=0;
//模式
uintt0;
//用于蜂鸣器
voidMODE_SET();
//模式设定
ucharcodeshu[]=//数码管表
{
0x3f,0x06,0x5b,0x4f,0x66,0x6d,
0x7d,0x07,0x7f,0x6f,0x77,0x7c,
0x39,//C
0x5e,0x79,0x71,
0x40,//显示"
-"
号16
0x00,//显示空,表示+17
0x76,//显示H18
0x38//显示L19
};
voiddisplay(uintaa,uintbb,uintcc,uintbai,uintshi,uintge);
//数码管显示函数
voiddelay(uintz);
//延时函数
voidyunsuan();
//运算出温度各位的数值
voidmain()//主函数
init();
//程序初始化
while
(1)//进入大循环
{
MODE_SET();
if(MODE==0)
{
tempp_18B20();
//读回温度,判断温度正负,并进行处理
temp_alarm();
yunsuan();
//运算出要显示各位的数值
display(zf,bai,shi,ge,dian,12);
//显示数值
}
else
SET_alarm();
//报警温度设定
}
}
/******************主程序初始化********************/
voidinit()
dula=0;
wela=0;
zf=17;
//默认显示正,即空
jia=1;
jian=1;
tempp_18B20();
//读取一次温度跳过85C
wela=1;
//初始化屏幕
P0=0xc0;
dula=1;
P0=0x40;
delay(1500);
//转换温度延时大于750MS
/***************************************
函数:
精准延时函数
功能:
DS18B20延时函数,实现15uS倍数精准延时
参数:
z为定时时间长度
说明:
延时公式:
15(t+1)uS,晶振12MHz
需要加入头文件#include<
****************************************/
voiddelay_18B20(uintt)
for(t;
t>
0;
t--)
_nop_();
_nop_();
_nop_();
/***************DS18B20初始化函数******************/
ucharinit_DS18B20()
uchara;
DQ=1;
//尽量短的延时
DQ=0;
delay_18B20(45);
//延时700
delay_18B20
(2);
//延时45
a=DQ;
delay_18B20(11);
//延时180
returna;
//返回a的值
/******************写数据一个字节*****************/
voidwrite_DS18B20(uchardat)
ucharx;
for(x=0;
x<
8;
x++)
DQ=0;
DQ=dat&
0x01;
delay_18B20
(1);
//延时30
DQ=1;
//稍微延时
dat>
>
=1;
/*******************读数据一个字节*****************/
ucharread_DS18B20()
ucharx,dat;
delay_18B20(0);
//延时151以上
if(DQ)
dat|=0x80;
delay_18B20
(2);
//延时45
//高电平恢复期
returndat;
//返回dat
/****************读取温度*****************/
intreadtemp()
intx,y,temp;
floattt=0;
//定义浮点运算
init_DS18B20();
write_DS18B20(0xcc);
//跳过ROM
write_DS18B20(0x44);
//温度转换
write_DS18B20(0xbe);
//读出寄存器值
x=read_DS18B20();
//读出低八位
y=read_DS18B20();
//读出高八位
temp=y;
//高八位赋给temp
temp<
<
=8;
//高八位左移
temp=temp|x;
//高低八位组合
tt=temp*0.0625;
//转换温度值
temp=tt*10;
//放大10倍输出
returntemp;
//返回温度
/***************显示函数*********************/
voiddisplay(uintaa,uintbb,uintcc,uintbai,uintshi,uintge)//先段
P0=shu[aa];
P0=0xff;
P0=0xfe;
P0=0x00;
delay(4);
//第一位
P0=shu[bb];
P0=0xfd;
//第二位
P0=shu[cc];
P0=0xfb;
//第三位
P0=shu[bai];
P0=0xf7;
//第百位
P0=shu[shi];
P0=0xef;
//第十位
P0=shu[ge];
P0=0xdf;
//第个位
P0=0x80;
delay
(2);
//显示点
//空显示
/*********************延时************************/
voiddelay(uintz)
uintx,y;
for(x=z;
x>
x--)
for(y=50;
y>
y--);
/********************温度处理*************************/
voidtempp_18B20()
tempp=readtemp();
//将温度值赋给tempp调整误差0.3C此处不在调整误差
if(tempp<
0)//判断温度值正负
zf=16;
//显示符号负温度
tempp=0-tempp;
else
zf=17;
//显示+
/***************运算出温度各位的数值**************/
voidyunsuan()
bai=tempp/1000;
shi=tempp%1000/100;
ge=tempp%100/10;
dian=tempp%10;
/****************温度报警程序*********************/
voidtemp_alarm()
if(tempp>
=shangxian||tempp<
=xiaxian)
t0++;
if(tempp>
=shangxian)//上限
led2=0;
JDQ2=0;
led1=1;
JDQ1=1;
if(tempp<
=xiaxian)//下限
led1=0;
JDQ1=0;
led2=1;
JDQ2=1;
led2=1;
JDQ2=1;
led1=1;
JDQ1=1;
FM=1;
if(t0==30)
t0=0;
FM=~FM;
/**********************模式设定***********************/
voidMODE_SET()
if(SET==0)
delay(40);
//延时15ms
if(SET==0)
MODE++;
if(MODE>
=3)
MODE=0;
while(SET==0);
delay(20);
/*********************报警温度设置*******************/
voidSET_alarm()
intsx,xx;
sx=shangxian;
xx=xiaxian;
if(MODE==1)
if(shangxian>
=0)
display(18,shangxian/1000,shangxian%1000/100,shangxian%100/10,shangxian%10,12);
//上限设置H最后显示C
sx=0-sx;
display(18,16,sx/100,sx%100/10,sx%10,12);
if(MODE==2)
if(xiaxian>
display(19,xiaxian/1000,xiaxian%1000/100,xiaxian%100/10,xiaxian%10,12);
//下限设置L最后显示C
xx=0-xx;
display(19,16,xx/100,xx%100/10,xx%10,12);
if(jia==0)//加键
delay(30);
if(jia==0)
if(MODE==1)//模式1时,上限加
{
shangxian+=10;
if(shangxian>
=1250)
shangxian=1250;
while(jia==0);
delay(10);
}
if(MODE==2)
{//模式2时,上限加
xiaxian+=10;
if(xiaxian>
=shangxian)
xiaxian=shangxian;
}
if(jian==0)//减键
if(jian==0)
if(MODE==1)//模式1时,上限减
shangxian-=10;
if(shangxian<
shangxian=xiaxian;
while(jian==0);
if(MODE==2)//模式2时,上限减
xiaxian-=10;
if(xiaxian<
=-500)
xiaxian=-500;
while(jian=