直接贴程序不好吗?还方便一些嘛。
给你一个例程:
main.c
#include<reg51.h>
#include"DS18B20.h"
#define SMG P0//数码管IO
sbit LSA=P2^2;//138译码器
sbit LSB=P2^3;
sbit LSC=P2^4;
unsigned char code ZF[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//要显示的数字
unsigned int XS[5]={0x3f,0x3f,0x3f,0x3f,0x3f};//显示缓存
void FZ(int temp)//给数码管显示缓存放入数据
{
float tp;//要进行带符号的小数运算,必须用有符号实型数据,32位
if(temp< 0)//当温度值为负数
{
XS[0] = 0x40;//显示负号-
temp=temp-1;//因为读取的温度是实际温度的补码,所以减1,再取反求出原码
temp=~temp;
tp=temp;
temp=tp*0.0625*100+0.5;//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数
//转换为整型的时候把小数点后面的数自动去掉,不管是否
//大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
//算加上.5,还是在小数点后面。
}
else
{
XS[0] = 0x70;//正数就显示┣
tp=temp;
temp=tp*0.0625*100+0.5;
}
XS[1] = ZF[temp % 10000 / 1000];
XS[2] = ZF[temp % 1000 / 100] + 0x80;//显示小数点
XS[3] = ZF[temp % 100 / 10];
XS[4] = ZF[temp % 10 / 1];
}
void DISPLAY()
{
LSC=1;LSB=0;LSA=0;//温度正负号
SMG=XS[0];
Delay1ms(1);
SMG=0x00;
LSC=0;LSB=1;LSA=1;//温度的十位
SMG=XS[1];
Delay1ms(1);
SMG=0x00;
LSC=0;LSB=1;LSA=0;//温度的个位带小数点
SMG=XS[2];
Delay1ms(1);
SMG=0x00;
LSC=0;LSB=0;LSA=1;//温度的小数点后第一位
SMG=XS[3];
Delay1ms(1);
SMG=0x00;
LSC=0;LSB=0;LSA=0;//温度的小数点后第二位
SMG=XS[4];
Delay1ms(1);
SMG=0x00;
}
void main()
{
while(1)
{
FZ(Ds18b20ReadTemp());//读取温度值并对显示缓存赋值
DISPLAY();//数码管显示
}
}
DS18B20.c
#include"DS18B20.h"
void Delay1ms(unsigned int y)//延时yms
{
unsigned int x;
for(y;y>0;y--)
for(x=110;x>0;x--);
}
unsigned char Ds18b20Init()//初始化
{
unsigned int i;
DSPORT=0;//将总线拉低480us~960us
i=70;
while(i--);//延时642us
DSPORT=1;//然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低
i=0;
while(DSPORT)//等待DS18B20拉低总线
{
i++;
if(i>1000)//等待>1MS
{
return 0;//初始化失败
}
}
return 1;//初始化成功
}
void Ds18b20WriteByte(unsigned char dat)//向18B20写入一个字节
{
unsigned int i,j;
for(j=0;j<8;j++)
{
DSPORT=0;//每写入一位数据之前先把总线拉低1us
i++;
DSPORT=dat&0x01;//然后写入一个数据,从最低位开始
i=6;
while(i--);//延时68us,持续时间最少60us
DSPORT=1;//然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值
dat>>=1;
}
}
unsigned char Ds18b20ReadByte()//从DS18B20读取一个字节
{
unsigned char byte,bi;
unsigned int i,j;
for(j=8;j>0;j--)
{
DSPORT=0;//先将总线拉低1us
i++;
DSPORT=1;//然后释放总线
i++;
i++;//延时6us等待数据稳定
bi=DSPORT;//读取数据,从最低位开始读取
byte=(byte>>1)|(bi<<7);
i=4;//读取完之后等待48us再接着读取下一个数
while(i--);
}
return byte;
}
void Ds18b20ChangTemp()//向DS18B20发送温度转换命令
{
Ds18b20Init();
Delay1ms(1);
Ds18b20WriteByte(0xcc);//跳过ROM操作命令
Ds18b20WriteByte(0x44);//温度转换命令
}
void Ds18b20ReadTempCom()//发送读取温度命令
{
Ds18b20Init();
Delay1ms(1);
Ds18b20WriteByte(0xcc);//跳过ROM操作命令
Ds18b20WriteByte(0xbe);//发送读取温度命令
}
int Ds18b20ReadTemp()//读取温度
{
int temp=0;
unsigned char tmh,tml;
Ds18b20ChangTemp();//先写入转换命令
Ds18b20ReadTempCom();//然后等待转换完后发送读取温度命令
tml=Ds18b20ReadByte();//读取温度值共16位,先读低字节
tmh=Ds18b20ReadByte();//再读高字节
temp=tmh;//把两次得到的8位数据,合并为16位实际数据
temp<<=8;
temp|=tml;
return temp;//温度的英文单词temperature
}
DS18B20.h
#ifndef __TEMP_H_
#define __TEMP_H_
#include<reg51.h>
sbit DSPORT=P3^7;
void Delay1ms(unsigned int );
unsigned char Ds18b20Init();
void Ds18b20WriteByte(unsigned char com);
unsigned char Ds18b20ReadByte();
void Ds18b20ChangTemp();
void Ds18b20ReadTempCom();
int Ds18b20ReadTemp();
#endif
程序适用的电路:
|