期末到了,刚刚好是实训周,做了个温度检测系统。大家交流交流!
如果有什么错误欢迎指出,本人感激不尽!
///////////////////////////////////////////分///割///线//////////////////////////////////////////////////////
用的是学校的单片机开发仪。
在开始写程序前,要把思路整理清楚:
先从DS18B20数字温度传感器获得当前的温度数据,然后再把温度数据显示在数码管上。
那么怎么从DS18B20数字温度传感器里获得数据呢?
引用百科的数据:
DS18B20的读写时序和测温原理与DS1820相同,只是得到的温度值的位数因分辨率不同而不同,且温度转换时的延时时间由2s减为750ms。 DS18B20测温原理如图3所示。图中低温度系数晶振的振荡频率受温度影响很小,用于产生固定频率的脉冲信号发送给计数器1。高温度系数晶振随温度变化其振荡频率明显改变,所产生的信号作为计数器2的脉冲输入。计数器1和温度寄存器被预置在-55℃所对应的一个基数值。计数器1对低温度系数晶振产生的脉冲信号进行减法计数,当计数器1的预置值减到0时,温度寄存器的值将加1,计数器1的预置将重新被装入,计数器1重新开始对低温度系数晶振产生的脉冲信号进行计数,如此循环直到计数器2计数到0时,停止温度寄存器值的累加,此时温度寄存器中的数值即为所测温度。斜率累加器用于补偿和修正测温过程中的非线性,其输出用于修正计数器1的预置值。
通俗点来讲,DS18B20数字温度传感器只有一个用于传数据的引脚线,所以它用了单总线协议。通过控制高低电平的时间来传输数据。(硬件上的简单带来的是软件上的复杂)
那么,我们既然要使用DS18B20,那么初始化就是必要的了。为了检测单片机有没有DS18B20和“告诉”DS18B20你要准备工作了。
首先,总线置0,然后至少延时480us,然后在拉高总线;接着延时60us后检测总线(因为DS18B20的响应时间为5~60us),看看是否为低电平,如果是低电平就是说明总线那头有DS18B20,如果不是就说明没有。不过在这里要注意,检测的时间最小要480us,所以还要延时哦。
这个是要读取从DS18B20发送回单片机的数据。时序图如下:
(1).先把总线拉低(置0)。
(2).延时15us。
(3).将数据线拉高“1”,释放总线准备读数据。
(4).读取总线的数据(就是看看是0或1)【变量=总线】。
(5).读数据线的状态得到1个状态位,并进行数据处理。
(6).延时45微妙。
(7).重复1~7步骤,直到读完一个字节(8bite)。
这是为了写RAM指令和ROM指令。
(1).总线先置低电平“0”
(2).延时1us。
(3).按从低位到高位的顺序发送数据(一次只发送一位)。
(4).延时60微妙。
(5).将数据线拉到高电平。
(6).重复1~5步骤,直到发送完整的字节。
指令表:
写完了以上的基本函数,DS18B20的准备工作就差不多了!
接下来就是启动温度转化;“叫DS18B20”发送数据;数据转化等函数了……
我们获取到了温度数据后,把温度数据的每一位提取出来,存放进数组里,按位显示在数码管上。
数码管显示就不多说了。
开发条件(DS18B20数字温度传感器,89C52单片机,数码管)
Keil 4软件
//main.c
#include
#include "001.h"
typedef unsigned int u16;
typedef unsigned char u8;
u8 code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//共阴极数码管字码
sbit pca=P2^2;
sbit pcb=P2^3;
sbit pcc=P2^4;
unsigned char wendu[8];
void daley(u16 i){
while(i--);
}
//数据处理(获取数据,进行处理,得到想要的数字)
void tp(int date){
float wd;
if(date<0)
{
wendu[0]=0x40;
date=date-1;
date=~date;
wd=date;
date=wd*0.0625*100+0.5;
}
else
{
wendu[0]=0x00;
wd=date;
date=wd*0.0625*100+0.5;
}
wendu[1] = smgduan[date / 10000]; //第五位
wendu[2] = smgduan[date % 10000 / 1000]; //第四位
wendu[3] = smgduan[date % 1000 / 100] | 0x80; //第三位
wendu[4] = smgduan[date % 100 / 10]; //第二位
wendu[5] = smgduan[date % 10]; //第一位
}
//显示数据
void sdp(){
u8 i;
for(i=0;i<6;i++)
{
switch(i)
{
case(0): pca=0;pcb=0;pcc=0;break;
case(1): pca=1;pcb=0;pcc=0;break;
case(2): pca=0;pcb=1;pcc=0;break;
case(3): pca=1;pcb=1;pcc=0;break;
case(4): pca=0;pcb=0;pcc=1;break;
case(5): pca=1;pcb=0;pcc=1;break;
}
P0=wendu[5-i];
daley(100);
P0=0x00;
}
}
void main(){
int date;
while(1)
{
date=drt();
tp(date);//处理
sdp();//显示
}
}
001.c
#include "001.h"
#include "intrins.h"
//#include "time .h"
////////各种延时函数////////////////
void Delay1ms(unsigned int y) //1ms
{
unsigned int x;
for( ; y>0; y--)
{
for(x=110; x>0; x--);
}
}
void delay600us(void) //600us
{
unsigned char a,b;
for(b=119;b>0;b--)
for(a=1;a>0;a--);
}
//void delay10us(void) //10us
//{
// unsigned char a,b;
// for(b=1;b>0;b--)
// for(a=1;a>0;a--);
//}
void delay45us(void) //45us
{
unsigned char a;
for(a=20;a>0;a--);
}
void delay60us(void) //60us
{
unsigned char a,b;
for(b=11;b>0;b--)
for(a=1;a>0;a--);
}
void delay15us(void) //15us
{
unsigned char a;
for(a=5;a>0;a--);
}
////////////////////////////////////////////
// DS18B20初始化
uchar key()
{
uchar x,i=0;
s=0;
delay600us();
s=1;
delay60us();
i=s;
delay600us();
return x;
// while(s)
// {
// delay600us();
// i++;
// if(i>5){
// return 0;
// }
// }
// return 1;
}
//读时序
uchar drb()
{
uint i;
uchar shuju,bi;
for(i=8;i>0;i--)
{
s=0;
delay15us();
s=1;
//delay10us();
bi=s;
shuju = (shuju >> 1) | (bi << 7);
delay45us();
}
return shuju;
}
//写时序
void dwb(uchar i)
{
uint m, j;
for(m=8;m>0;m--){
s=0;
j++;
s=i&0x01;
delay60us();
s=1;
i>>=1;
}
}
//“叫DS18B20”发送数据
void drtc()
{
key();
Delay1ms(1);
dwb(0xcc);//
dwb(0xbe);//
}
//启动温度转化
void dct()
{
key();
Delay1ms(1);
dwb(0xcc);
dwb(0x44);
}
//温度转化
int drt(){
uint L,H,time=0;//l为低,h为高
dct();
drtc();
L=drb();
H=drb();
time=H;
time<<=8;
time|=L;
return time;
}
001.h
#ifndef _001_h_
#define _001_h_
#include "regx52.h"
#ifndef uchar
#define uchar unsigned char
#endif
#ifndef uint
#define uint unsigned int
#endif
sbit s=P3^7;
void Delay1ms(uint y);
uchar key();//初始化
uchar drb();//读数据
void dwb(uchar i ); //写数据
int drt();//温度转换,取出数据
void dct();//启动温度转换
void drtc();//温度读取
#endif
应该没有多少人看到这里吧
第一次写这种博客,有什么不足请指出!谢谢!!