不可以;
Get_Tmp() 函数中 a、b 为读18B20 的温度寄存器,然后将 16位结果 赋值到 无符号的 temp 变量上,然后进行温度换算,再放大1000倍,对小数点进行 四舍五入 运算。整个过程不涉及 温度符号(正负) 识别,就直接送往 显示函数 显示。
//安装目录下的EXE文件打开后可在电脑上显示当前温度值
#include <reg52h>
#define uchar unsigned char
#define uint unsigned int
sbit DS=P2^2; //define interface
uint temp; // variable of temperature
uchar flag1; // sign of the result positive or negative
sbit dula=P2^6;
sbit wela=P2^7;
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
unsigned char code table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,
0x87,0xff,0xef};
void delay(uint count) //delay
{
uint i;
while(count)
{
i=200;
while(i>0)
i--;
count--;
}
}
///////功能:串口初始化,波特率9600,方式1///////
void Init_Com(void)
{
TMOD = 0x20;
PCON = 0x00;
SCON = 0x50;
TH1 = 0xFd;
TL1 = 0xFd;
TR1 = 1;
}
void dsreset(void) //send reset and initialization command
{
uint i;
DS=0;
i=103;
while(i>0)i--;
DS=1;
i=4;
while(i>0)i--;
}
bit tmpreadbit(void) //read a bit
{
uint i;
bit dat;
DS=0;i++; //i++ for delay
DS=1;i++;i++;
dat=DS;
i=8;while(i>0)i--;
return (dat);
}
uchar tmpread(void) //read a byte date
{
uchar i,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=tmpreadbit();
dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里
}
return(dat);
}
void tmpwritebyte(uchar dat) //write a byte to ds18b20
{
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb) //write 1
{
DS=0;
i++;i++;
DS=1;
i=8;while(i>0)i--;
}
else
{
DS=0; //write 0
i=8;while(i>0)i--;
DS=1;
i++;i++;
}
}
}
void tmpchange(void) //DS18B20 begin change
{
dsreset();
delay(1);
tmpwritebyte(0xcc); // address all drivers on bus
tmpwritebyte(0x44); // initiates a single temperature conversion
}
uint tmp() //get the temperature
{
float tt;
uchar a,b;
dsreset();
delay(1);
tmpwritebyte(0xcc);
tmpwritebyte(0xbe);
a=tmpread();
b=tmpread();
temp=b;
temp<<=8; //two byte compose a int variable
temp=temp|a;
tt=temp00625;
temp=tt10+05;
return temp;
}
void readrom() //read the serial
{
uchar sn1,sn2;
dsreset();
delay(1);
tmpwritebyte(0x33);
sn1=tmpread();
sn2=tmpread();
}
void delay10ms() //delay
{
uchar a,b;
for(a=10;a>0;a--)
for(b=60;b>0;b--);
}
void display(uint temp) //显示程序
{
uchar A1,A2,A2t,A3,ser;
ser=temp/10;
SBUF=ser;
A1=temp/100;
A2t=temp%100;
A2=A2t/10;
A3=A2t%10;
dula=0;
P0=table[A1]; //显示百位
dula=1;
dula=0;
wela=0;
P0=0x7e;
wela=1;
wela=0;
delay(1);
dula=0;
P0=table1[A2]; //显示十位
dula=1;
dula=0;
wela=0;
P0=0x7d;
wela=1;
wela=0;
delay(1);
P0=table[A3]; //显示个位
dula=1;
dula=0;
P0=0x7b;
wela=1;
wela=0;
delay(1);
}
void main()
{
uchar a;
Init_Com();
do
{
tmpchange();
// delay(200);
for(a=10;a>0;a--)
{
display(tmp());
}
}while(1);
}
将二管脚接到P22就可以了
具体的电路图你可以留个邮箱我发给你
我应经发给你了,那个是一个开发板的原理图,外设什么的都有了,你可以参考一下
#include "reg52h"
#include<intrinsh>
#include <mathH> //要用到取绝对值函数abs()
#define uchar unsigned char
#define uint unsigned int
sbit ds=P2^1; //sbit ds=P3^2;//DS18B20
sbit duan=P2^6;
sbit wei=P2^7;
uchar i;
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x00,0x40}; //0x00是用在显示函数中0x40显示“-”(负号)
//
void delay(uchar i)
{
uint j;
while(i--)
{
for(j = 0; j < 125; j++);
}
}
//
//延时函数, 对于110592MHz时钟, 例i=10,则大概延时10ms
void dsInit()
{
//对于110592MHz时钟, unsigned int型的i, 作一个i++ *** 作的时间大于8us
unsigned int i;
ds = 0;
i = 100; //拉低约800us, 符合协议要求的480us以上
while(i>0) i--;
ds = 1; //产生一个上升沿, 进入等待应答状态
i = 4;
while(i>0) i--;
}
void dsWait()
{
unsigned int i;
while(ds); //等待应答信号
while(~ds); //检测到应答脉冲
i = 4;
while(i > 0) i--;
}
//向DS18B20读取一位数据
//读一位, 让DS18B20一小周期低电平, 然后两小周期高电平,
//之后DS18B20则会输出持续一段时间的一位数据
bit readBit()
{
unsigned int i;
bit b;
ds = 0;
i++; //延时约8us, 符合协议要求至少保持1us
ds = 1;
i++;
i++; //延时约16us, 符合协议要求的至少延时15us以上
b = ds;
i = 8;
while(i>0) i--; //延时约64us, 符合读时隙不低于60us要求
return b;
}
//读取一字节数据, 通过调用readBit()来实现
unsigned char readByte()
{
unsigned int i;
unsigned char j, dat;
dat = 0;
for(i=0; i<8; i++)
{
j = readBit();
//最先读出的是最低位数据
dat = (j << 7) | (dat >> 1);
}
return dat;
}
//向DS18B20写入一字节数据
void writeByte(unsigned char dat)
{
unsigned int i;
unsigned char j;
bit b;
for(j = 0; j < 8; j++)
{
b = dat & 0x01;
dat >>= 1;
//写"1", 将DQ拉低15us后, 在15us~60us内将DQ拉高, 即完成写1
if(b)
{
ds = 0;
i++;
i++; //拉低约16us, 符号要求15~60us内
ds = 1;
i = 8; while(i>0) i--; //延时约64us, 符合写时隙不低于60us要求
}
else //写"0", 将DQ拉低60us~120us
{
ds = 0;
i = 8; while(i>0) i--; //拉低约64us, 符号要求
ds = 1;
i++;
i++; //整个写0时隙过程已经超过60us, 这里就不用像写1那样, 再延时64us了
}
}
}
//向DS18B20发送温度转换命令
void sendChangeCmd()
{
dsInit(); //初始化DS18B20, 无论什么命令, 首先都要发起初始化
dsWait(); //等待DS18B20应答
delay(1); //延时1ms, 因为DS18B20会拉低DQ 60~240us作为应答信号
writeByte(0xcc); //写入跳过序列号命令字 Skip Rom
writeByte(0x44); //写入温度转换命令字 Convert T
}
//向DS18B20发送读取数据命令
void sendReadCmd()
{
// EA=0;//关闭中断是因为进入显示中断会影响到DS18B20的读写时序
dsInit();
dsWait();
delay(1);
writeByte(0xcc); //写入跳过序列号命令字 Skip Rom
writeByte(0xbe); //写入读取数据令字 Read Scratchpad
// EA=1;
}
//获取当前温度值
int getTmpValue()
{
unsigned int tmpvalue;
int value; //存放温度数值
float t;
unsigned char low, high;
// EA=0;
sendReadCmd();
//连续读取两个字节数据
low = readByte();
high = readByte();
//将高低两个字节合成一个整形变量
//计算机中对于负数是利用补码来表示的
//若是负值, 读取出来的数值是用补码表示的, 可直接赋值给int型的value
tmpvalue = high;
tmpvalue <<= 8;
tmpvalue |= low;
value = tmpvalue;
//使用DS18B20的默认分辨率12位, 精确度为00625度, 即读回数据的最低位代表00625度
t = value 00625;
//将它放大100倍, 使显示时可显示小数点后两位, 并对小数点后第三进行4舍5入
//如t=110625, 进行计数后, 得到value = 1106, 即1106 度
//如t=-110625, 进行计数后, 得到value = -1106, 即-1106 度
value = t 100 + (value > 0 05 : -05); //大于0加05, 小于0减05
return value;
// EA=1;
}
/
void Init_timer0()
{
TMOD=0x01;
TH0=th0;
TL0=tl0;
EA=1;
ET0=1;
TR0=1;
} /
void display(int dd)
{
uchar SH,SZ,SL,GH,GL,i,temp;
uchar dis[8]={10,10,10,10,10,10,10,10}; //从5-8的数字为10,相应的段码是0x00,即不显示
uint dda;
dda=abs(dd);
SH = dda/ 10000;
SZ = dda % 10000 / 1000;
SL = dda % 1000 / 100;
GH = dda % 100 / 10;
GL = dda % 10;
dis[0]=GL;
dis[1]=GH;
dis[2]=SL;
if((SZ==0)&&(SH==0))
dis[3]=10;
else
dis[3]=SZ;
if (dd<0)
dis[4]=11; //是负温度,显示“-”
else
{
if(SH==0)
dis[4]=10; //温度高位是0,不显示
else
dis[4]=SH;
}
temp=0xbf;
for(i=0;i<8;i++)
{
P0=0xff;
wei=1;
temp=_cror_(temp,1);
P0=temp;
wei=0;
P0=0;
duan=1;
if(i==2)
{
P0=0x80|table[dis[2]];
}
else
P0=table[dis[i]];
duan=0;
delay(1);
}
/
P0=0xff;
wei=1;
P0=0xdf;
wei=0;
P0=0;
duan=1;
P0=table[GL];
delay(1);
duan=0;
P0=0xff;
wei=1;
P0=0xef;
wei=0;
P0=0;
duan=1;
P0=table[GH];
delay(1);
duan=0;
P0=0xff;
wei=1;
P0=0xf7;
wei=0;
P0=0;
duan=1;
P0=table[SL]|0x80;
delay(1);
duan=0;
P0=0xff;
wei=1;
P0=0xfb;
wei=0;
P0=0;
duan=1;
P0=table[SZ];
delay(1);
duan=0;
P0=0xff;
wei=1;
P0=0xfd;
wei=0;
P0=0;
duan=1;
P0=table[SH];
delay(1);
duan=0;
P0=0xff;
wei=1;
P0=0xff;
wei=0; /
}
void main()
{
int tempValue1;
// init();
// Init_timer0();
while(1)
{
//启动温度转换
sendChangeCmd();
tempValue1 = getTmpValue();
display(tempValue1);
}
}
//根据自己的硬件改改端口,我已经成功了
#include <reg52h>
#define uchar unsigned char
#define uint unsigned int
sbit DS=P3^7; //define interface 定义DS18B20接口
uint temp; // variable of temperature
uchar flag1; // sign of the result positive or negative
sbit p0_5=P0^5;
sbit p2_7=P2^7;
sbit p2_4=P2^4;
sbit p2_5=P2^5;
sbit p2_6=P2^6;
unsigned char code TABLE[]={
0xd7,0x11,0xcd,0x5d,0x1b,
0x5e,0xde,0x15,0xdf,0x5f,
0x9f,0xdf,0xc6,0xd7,0xce,0x8e};
void delay(uint count) //delay
{
uint i;
while(count)
{
i=200;
while(i>0)
i--;
count--;
}
}
void Init_Com(void)
{
TMOD = 0x20;
PCON = 0x00;
SCON = 0x50;
TH1 = 0xFd;
TL1 = 0xFd;
TR1 = 1;
}
void dsreset(void) //send reset and initialization command
{
uint i; //DS18B20初始化
DS=0;
i=103;
while(i>0)i--;
DS=1;
i=4;
while(i>0)i--;
}
bit tmpreadbit(void) //read a bit 读一位
{
uint i;
bit dat;
DS=0;i++; //i++ for delay 小延时一下
DS=1;i++;i++;
dat=DS;
i=8;while(i>0)i--;
return (dat);
}
uchar tmpread(void) //read a byte date 读一个字节
{
uchar i,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=tmpreadbit();
dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好
//一个字节在DAT里
}
return(dat); //将一个字节数据返回
}
void tmpwritebyte(uchar dat) //write a byte to ds18b20
{ //写一个字节到DS18B20里
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb) //write 1 写1部分
{
DS=0;
i++;i++;
DS=1;
i=8;while(i>0)i--;
}
else
{
DS=0; //write 0 写0部分
i=8;while(i>0)i--;
DS=1;
i++;i++;
}
}
}
void tmpchange(void) //DS18B20 begin change 发送温度转换命令
{
dsreset(); //初始化DS18B20
delay(1); //延时
tmpwritebyte(0xcc); // 跳过序列号命令
tmpwritebyte(0x44); //发送温度转换命令
}
uint tmp() //get the temperature 获得温度
{
float tt;
uchar a,b;
dsreset();
delay(1);
tmpwritebyte(0xcc);
tmpwritebyte(0xbe); //发送读取数据命令
a=tmpread(); //连续读两个字节数据
b=tmpread();
temp=b;
temp<<=8; //two byte compose a int variable
temp=temp|a; //两字节合成一个整型变量。
tt=temp00625; //得到真实十进制温度值,因为DS18B20
//可以精确到00625度,所以读回数据的最低位代表的是
//00625度。
temp=tt10+05; //放大十倍,这样做的目的将小数点后第一位
//也转换为可显示数字,同时进行一个四舍五入 *** 作。
return temp; //返回温度值
}
void delay10ms() //delay
{
uchar a,b;
for(a=10;a>0;a--)
for(b=60;b>0;b--);
}
void display(uint temp)
{
uchar a,b,c,d;
a=temp/100;
b=temp/10-a10;
d=temp%10;
c=(temp%100-d)/10;
P0=TABLE[d];
p0_5=0;
p2_7=0;
delay(1);
p2_7=1;
P0=TABLE[c];
p2_4=0;
delay(1);
p2_4=1;
P0=TABLE[b];
p0_5=1;
p2_5=0;
delay(1);
p2_5=1;
P0=TABLE[a];
p2_6=0;
delay(1);
p2_6=1;
}
void main() //主函数
{
uchar a;
Init_Com(); //初始化串口
do
{
tmpchange(); //温度转换
for(a=10;a>0;a--)
{
display(tmp()); //显示十次
}
}
while(1);
}
把返回值放到你数码管显示子程序中分解显示即可
sbit DQ=P1^6; //采集温度数据线
sbit SPK=P3^7;
unsigned char tflag;
unsigned int tive;
float temper;
/
函数功能:短暂延时
入口参数:num
出口参数:
/
void delay(unsigned int num)
{
while(num--);
}
/
函数功能:DS18B20初始化
入口参数:
出口参数:
/
void init_DS18B20(void)
{
//主机发送复位脉冲
DQ=1;
DQ=0;
delay(600); //x
DQ=1;
//等待DS18B20发送应答信号
delay(60); //防止DS18B20本身问题而读不出数据采用确认法
while(!DQ);
// delay(480); //DS18B20本身没有问题,可以延时将应答过程忽略
}
/
函数功能:读一个字节
入口参数:
出口参数:
/
readchar(void) //从低位开始读
{
unsigned char i=0;
unsigned char dat=0;
for(i=0;i<8;i++)
{
DQ=1;
DQ=0;
delay(10); //CPU缓冲时间 采样时间
dat>>=1; //从高到低先存放一位数据
DQ=1;
if(DQ) //如果是1,将数据存放
dat|=0x80;
DQ=1;
delay(9); //数据读取时间,下一次数据读取前需要延时
}
return(dat);
}
/
函数功能:写一个字节
入口参数:
出口参数:
/
writechar(unsigned char dat)
{
unsigned char i=0;
for(i=0;i<8;i++)
{
DQ=1;
DQ=0; //等待接收缓冲区的来临,整个过程的时间为60~120us
delay(15); //
DQ=dat&0x01; //第一次写最低位,将字节变为位
delay(15); //
dat>>=1; //准备写入下一位数据。
}
}
/
函数功能:读取温度
入口参数:
出口参数:
/
read_temperature(void)
{
unsigned int a,b;
init_DS18B20(); //初始化子程序
writechar(0xcc); //写入指令
writechar(0x44);
init_DS18B20();
writechar(0xcc);
writechar(0xbe);
a=readchar(); //低八位
b=readchar(); //高八位
tive=b;
tive<<=8;
tive=tive|a;
if(tive>0x0800) //温度为负温度第13位到15为为1,温度为正温度 //第13位到15为为0,所以值小于0x800说明为正温度
tive=~tive+1;
else
tive=tive;
temper=tive00625; //采用12位分辨率所以每次的增量是00625
temper=temper10; //保留小数点后面一位
return(temper);
}
以上就是关于求STC89C51单片机和DS18B20用两位共阳数码管显示温度C程序全部的内容,包括:求STC89C51单片机和DS18B20用两位共阳数码管显示温度C程序、ds18b20显示温度程序,写完温度跳变很大,而且感觉显示的与实际温度无关,求大神、请问这个DS18B20程序能显示零度以下的温度吗等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)