有谁知道DS18B20 温度采集程序,用C 语言编程, 用KeilC51 编译。

作者&投稿:晏裕 (若有异议请与网页底部的电邮联系)
有谁知道AT89C52和DS18B20温度采集系统的C语言程序?~

#include "REG51.H"
#include "INTRINS.H"

typedef unsigned char BYTE;

sbit DQ = P3^3; //DS18B20的数据口位P3.3
BYTE TPH; //存放温度值的高字节
BYTE TPL; //存放温度值的低字节

void DelayXus(BYTE n);
void DS18B20_Reset();
void DS18B20_WriteByte(BYTE dat);
BYTE DS18B20_ReadByte();

void main()
{
DS18B20_Reset(); //设备复位
DS18B20_WriteByte(0xCC); //跳过ROM命令
DS18B20_WriteByte(0x44); //开始转换命令
while (!DQ); //等待转换完成

DS18B20_Reset(); //设备复位
DS18B20_WriteByte(0xCC); //跳过ROM命令
DS18B20_WriteByte(0xBE); //读暂存存储器命令
TPL = DS18B20_ReadByte(); //读温度低字节
TPH = DS18B20_ReadByte(); //读温度高字节

while (1);
}

/**************************************
延时X*10微秒(STC90C52RC@12M)
不同的工作环境,需要调整此函数
当改用1T的MCU时,请调整此延时函数
**************************************/
void DelayX0us(BYTE n)
{
while (n--)
{
_nop_();
_nop_();
}
}

/**************************************
复位DS18B20,并检测设备是否存在
**************************************/
void DS18B20_Reset()
{
CY = 1;
while (CY)
{
DQ = 0; //送出低电平复位信号
DelayX0us(48); //延时至少480us
DQ = 1; //释放数据线
DelayX0us(6); //等待60us
CY = DQ; //检测存在脉冲
DelayX0us(42); //等待设备释放数据线
}
}

/**************************************
从DS18B20读1字节数据
**************************************/
BYTE DS18B20_ReadByte()
{
BYTE i;
BYTE dat = 0;

for (i=0; i<8; i++) //8位计数器
{
dat >>= 1;
DQ = 0; //开始时间片
_nop_(); //延时等待
_nop_();
DQ = 1; //准备接收
_nop_(); //接收延时
_nop_();
if (DQ) dat |= 0x80; //读取数据
DelayX0us(6); //等待时间片结束
}

return dat;
}

/**************************************
向DS18B20写1字节数据
**************************************/
void DS18B20_WriteByte(BYTE dat)
{
char i;

for (i=0; i<8; i++) //8位计数器
{
DQ = 0; //开始时间片
_nop_(); //延时等待
_nop_();
dat >>= 1; //送出数据
DQ = CY;
DelayX0us(6); //等待时间片结束
DQ = 1; //恢复数据线
}

#include

extern GetTemp(); //声明引用外部函数
extern unsigned int idata Temperature; // 声明引用外部变量
void delay(unsigned int i);

//else IO
sbit LS138A=P2^2; //管脚定义
sbit LS138B=P2^3;
sbit LS138C=P2^4;


//此表为 LED 的字模, 共阴数码管 0-9 -
unsigned char code Disp_Tab[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};
unsigned long LedOut[5],LedNumVal;


void system_Ini()
{
TMOD|= 0x11;
TH1 = 0xD8; //10
TL1 = 0xF0;
IE = 0x8A;
TR1 = 1;

}

main()
{ unsigned char i;
system_Ini();
while(1)
{
GetTemp();

/********以下将读18b20的数据送到LED数码管显示*************/
LedNumVal=Temperature; //把实际温度送到LedNumVal变量中
LedOut[0]=Disp_Tab[LedNumVal%10000/1000];
LedOut[1]=Disp_Tab[LedNumVal%1000/100];
LedOut[2]=Disp_Tab[LedNumVal%100/10];//十位
LedOut[3]=Disp_Tab[LedNumVal%10]; //个位

for(i=0; i<4; i++)
{
P0 = LedOut[i] ;

switch(i)
{ //138译码
case 0:LS138A=0; LS138B=0; LS138C=0; break;
case 1:LS138A=1; LS138B=0; LS138C=0; break;
case 2:LS138A=0; LS138B=1; LS138C=0; break;
case 3:LS138A=1; LS138B=1; LS138C=0; break;
}

delay(100);
}

P0 = 0;

}
}

//延时程序
void delay(unsigned int i)
{
char j;
for(i; i > 0; i--)
for(j = 200; j > 0; j--);
}

#include <reg52.h>
#include <math.h> //Keil library
#include <stdio.h> //Keil library
#include <INTRINS.H>
#define uchar unsigned char
#define uint unsigned int
#define display1 0xfe //数码管1从左至右
#define display2 0xfd //数码管2从左至右
#define display3 0xfb //数码管3从左至右
#define display4 0xf7 //数码管4从左至右
#define display5 0xef //数码管5从左至右
#define display6 0xdf //数码管6从左至右
#define display7 0xbf //数码管7从左至右
#define display8 0x7f //数码管8从左至右
sbit led=P1^5;
sbit DQ=P3^6; //根据实实际情况设定
sbit setth=P1^0;//设定 th
sbit up=P1^1;//加
sbit down=P3^2;//减
sbit beep= P3^3;
uchar tempint,f,bb,tempth,temptl,th,tl,beepflag; //温度整数部分和小数部分
int tempdf,c;
code unsigned char ledmap[]={0xc0,0xf9,0xa4,0xb0,0x99,
0x92,0x82,0xf8,0x80,0x90,0xbf};
code unsigned char ledmap1[]={0x40,0x79,0x24,0x30,
0x19,0x12,0x02,0x78,0x00,0x10};
//7段数码管0~9数字的共阳显示代码和负号位代码(最后一位)

void set_ds18b20(); //初始化DS18B20子程序
void get_temperature(); //获得温度子程序
void read_ds18b20(); //读DS18B20子程序
void write_ds18b20(uchar command); //向DS18B20写1字节子程序
void delayms(uchar count); //延时count毫秒子程序
void disp_temp(tempint,tempdf); //显示温度子程序

//***********************初始化DS18B20子程序**********************************
//****************************************************************************
void set_ds18b20()
{
while(1)
{
uchar delay,flag;
flag=0;
DQ=1;
delay=1;
while(--delay);
DQ=0; //数据线置低电平
delay=250;
while(--delay); //低电平保持500us
DQ=1; //数据线置高电平
delay=30;
while(--delay); //高电平保持60us
while(DQ==0) //判断DS18B20是否发出低电平信号
{
delay=210; //DS18B20响应,延时420us
while(--delay);
if(DQ) //DS18B20发出高电平初始化成功,返回
{
flag=1; //DS18B20初始化成功标志

//初始化成功LED标志

break;
}
}
if(flag) //初始化成功,再延时480us,时序要求
{
delay=240;
while(--delay);
break;
}
}
}
//***********************获得温度子程序***************************************
//****************************************************************************
void get_temperature() //温度转换、获得温度子程序
{
set_ds18b20(); //初始化DS18B20
write_ds18b20(0xcc); //发跳过ROM匹配命令
write_ds18b20(0x44); //发温度转换命令
// delayms(750);
disp_temp(tempint,tempdf); //显示温度,等待AD转换
set_ds18b20();
write_ds18b20(0xcc); //发跳过ROM匹配命令
write_ds18b20(0xbe); //发出读温度命令
read_ds18b20(); //将读出的温度数据保存到tempint和tempdf处

}
//***********************读DS18B20子程序***************************************
//****************************************************************************
void read_ds18b20()
{
uchar delay,i,j,k,temp,temph,templ;

j=4; //读2位字节数据
do
{
for(i=8;i>0;i--) //一个字节分8位读取
{
temp>>=1; //读取1位右移1位
DQ=0; //数据线置低电平
delay=1;
while(--delay);
DQ=1; //数据线置高电平
delay=4;
while(--delay); //延时8us
if(DQ) //读取1位数据
temp|=0x80;
delay=25; //读取1位数据后延时50us
while(--delay);
}
if(j==4)
templ=temp;//读取的第一字节存templ

if(j==3)
temph=temp; //读取的第二字节存temph
if(j==2)
tempth=temp; //读取的第3字节存tempth TH的值
if(j==1)
temptl=temp; //读取的第4字节存tempth TL的值
}while(--j);
f=0;
if((temph & 0xf8)!=0x00) //若温度为负的处理,对二进制补码的处理
{
f=1; //为负温度f置1

temph=~temph;
templ=~templ;
k=templ+1;
templ=k;
if(k>255)
{
temph++;
}
}
tempdf=templ & 0x0f; //将读取的数据转换成温度值,整数部分存tempint,小数部分存tempdf
c=(tempdf*625);
tempdf=c;
templ>>=4; //
temph<<=4; //转化成字节温度
tempint=temph|templ;//两字节合并为一个字节

if (tempint>th|tempint==th|tempint<tl|tempint==tl)
beepflag=1;
else
beepflag=0;

}
//***********************写DS18B20子程序***************************************
//****************************************************************************
void write_ds18b20(uchar command)
{
uchar delay,i;
for(i=8;i>0;i--) //将一字节数据一位一位写入
{
DQ=0; //数据线置低电平
delay=6; //延时12us
while(--delay);
DQ=command&0x01; //将数据放置在数据线上
delay=25; //延时50us
while(--delay);
command=command>>1; //准备发送下一位数据
DQ=1; //发送完一位数据,数据线置高电平
}
}
//***********************显示子程序***************************************
//****************************************************************************
void disp_temp( tempint,tempdf)
{
uchar tempinth,tempintl,tempinbai,shifen,baifen,gefen,qianfen;

if (bb==1)
{
tempinbai=th/100;
tempinth=(th%100)/10;
tempintl=th%10; //整数取模

gefen=0/1000;
shifen=0%1000/100;
baifen =0%100/10;
qianfen=0%10; //小数取模
}
else if(bb==2)
{ tempinbai=tl/100;
tempinth=(tl%100)/10;
tempintl=tl%10; //整数取模

gefen=0/1000;
shifen=0%1000/100;
baifen =0%100/10;
qianfen=0%10; //小数取模
}
else
{
tempinbai=tempint/100;
tempinth=(tempint%100)/10;
tempintl=tempint%10; //整数取模

gefen=tempdf/1000;
shifen=tempdf%1000/100;
baifen =tempdf%100/10;
qianfen=tempdf%10; //小数取模

}

if (f==0)
{

P0=display1; //符号位
P2=ledmap[0];
}
else
{
P0=display1; //符号位
P2=ledmap[10];
}

delayms(2);
P0=display2;
P2=ledmap[tempinbai]; //开百位
delayms(2);
P0=display3;
P2=ledmap[tempinth];//开十位
delayms(2);
P0=display4;
P2=ledmap1[tempintl];//开个位
delayms(2);
P0=display5;
P2=ledmap[gefen];//开个分位
delayms(2);
P0=display6;
P2=ledmap[shifen]; //开十分位
delayms(2);
P0=display7;
P2=ledmap[baifen]; //开百分位
delayms(2);
P0=display8;
P2=ledmap[qianfen];//开千分位

}

//*******************************************************************/
//* 蜂鸣器响一声 */
//*******************************************************************/
void beep_st()
{
if (beepflag==1)
{ beep=0;
delayms(1000) ;
beep=1;
}
else
beep=1;
}

//***********************延时count ms子程序***************************************
//****************************************************************************
void delayms(uchar count) //延时count ms子程序
{
uchar i,j;
do
{
for(i=5;i>0;i--)
for(j=98;j>0;j--);
}while(--count);
}

//****************************************************************************
void keyscan() //键盘扫描
{

if(setth==0)
{
delayms(1);
}
if(setth==0)
{

bb++;
while(!setth); //循环在此 非0=1
}
if(bb==1)
{

if(up==0)
{
delayms(1);
}
if(up==0)
{

disp_temp(th,tempdf);
if(th<125)
{th++;}

while(!up)//非0=1
{
disp_temp(th,tempdf);
}
}
if(down==0)
{
delayms(1);
}
if(down==0)
{
disp_temp(th,tempdf);
if(th!=0) //不等于0为真执行
{
th--;
while(!down) // down为(非0=1)循环执行
{
disp_temp(th,tempdf);
}
}
}
}

if(bb==2)
{

if(up==0)
{
delayms(1);
}
if(up==0)
{

disp_temp(tl,tempdf);
if(tl<125)
{tl++;}

while(!up)//非0=1
{
disp_temp(th,tempdf);
}
}
if(down==0)
{
delayms(1);
}
if(down==0)
{
disp_temp(th,tempdf);
if(tl!=0) //不等于0为真执行
{
tl--;
while(!down) // down为(非0=1)循环执行
{
disp_temp(tl,tempdf);
}
}
}
}

if(bb==3)
{bb=0;
set_ds18b20(); //初始化DS18B20
write_ds18b20(0xcc); //发跳过ROM匹配命令
write_ds18b20(0x4e); //发温度转换命令
write_ds18b20(th); //写TH 3
write_ds18b20(tl);
// write_ds18b20(0x7f);
set_ds18b20(); //初始化DS18B20
write_ds18b20(0xcc); //发跳过ROM匹配命令
write_ds18b20(0x48);

}
}

void main()
{ set_ds18b20();
write_ds18b20(0xcc); //发跳过ROM匹配命令
write_ds18b20(0xbe); //发出读温度命令
read_ds18b20(); //将读出的数据
th=tempth; //将TH读到单片机
tl=temptl;

SP=0x60; //设置堆栈指针
bb=0;
beepflag=0;
while(1)
{

keyscan();
get_temperature(); //获得温度

disp_temp(tempint,tempdf); //显示温度
beep_st();
}
}

#include<reg52.h>
#include"18b20.h"
#include"delay.h"

sbit DQ = P1^1;

unsigned char csh_ds18b20() //18b20初始化函数
{
unsigned char n;
DQ = 1;
delay_us(8);
DQ = 0;
delay_us(80);
DQ = 1;
delay_us(8);
n = DQ;
delay_us(4);
if(n)
return 1; //有器件
else
return 0; //无器件

}

void w_1byte(unsigned char dat) //写入一字节函数
{
unsigned char i;
for(i=0; i<8; i++)
{
DQ = 0;
DQ = dat & 0x01;
delay_us(4);
DQ = 1;
dat >>= 1;
}
delay_us(4);
}

unsigned char r_ds18b20(void) //读一字节函数
{
unsigned char i,r_dat;
for(i=0; i<8; i++)
{
DQ = 0;
r_dat >>= 1;
DQ = 1;
if(DQ)
r_dat |= 0x80;
delay_us(4);
}
return r_dat;
}

unsigned char r_temp(void) //温度读取函数
{
unsigned char l_temp,h_temp;
csh_ds18b20(); //初始化18b20
w_1byte(0xcc); //跳过ROM指令
w_1byte(0x44); //启动温度转换
delay_us(200); //等待转换结果
csh_ds18b20();
w_1byte(0xcc);
w_1byte(0xbe); //读暂存器指令
l_temp = r_ds18b20(); //读LS Byte八位数
h_temp = r_ds18b20(); //读MS Byte八位数
h_temp <<= 4; //取MS Byte的低四位
l_temp &= 0xf0; //取LS Byte的高四位
l_temp >>= 4;
h_temp = h_temp + l_temp; //温度的最终值
return h_temp;
}

下面是.h程序:
#ifndef __18B20_H__
#define __18B20_H__

unsigned char csh_ds18b20(); //18b20初始化函数
void w_1byte(unsigned char dat); //写入一个字节函数
unsigned char r_ds18b20(void); //读一字节函数
unsigned char r_temp(void); //温度读取函数

#endif

我空间里有DS18B20设计的温度采集程序,希望有所帮助!那是我的作业,刚觉可以!

我有,留联系方式或hi我,我给你


DS18B02温度读不出来,只能读出0XFF
DS18B02是有时娇气点,对使用时序操作很严格,如果一点做错了,可能测不出来!还有那些延时程序,必须要精确延时,按DATASHEET上的标准来,不然都不行。它规定了温度的读数起点(零点)和测量温度的基本单位。国际单位为热力学温标(K)。目前国际上用得较多的其他温标有华氏温标(°F)、摄氏温标(°C...

DS18B20的数字温度传感器DS18B20介绍
DS18BDS1822“一线总线”数字化温度传感器同DS1820一样,DS18B20也支持“一线总线”接口,测量温度范围为-55°C~+125°C,在-10~+85°C范围内,精度为±0.5°C。DS1822的精度较差为±2°C。DS18B20是常用的数字温度传感器,其输出的是数字信号,具有体积小,硬件开销低,抗干扰能力强,精度高的...

protues运行出现:[DS18B22]RAM COMMAND UNSUPPORTED 是什么原因_百度知 ...
你可以把数码管动态显示的延时改长一点,就不会有警告了,可能是读取得太快了,以致DS18B20还没来得及准备数据

ds18b20温度传感器引脚
DS18BDS1822“一线总线”数字化温度传感器同DS1820一样,DS18B20也支持“一线总线”接口,测量温度范围为-55°C~+125°C,在-10~+85°C范围内,精度为±0.5°C。DS1822的精度较差为±2°C。DS18B20是常用的数字温度传感器,其输出的是数字信号,具有体积小,硬件开销低,抗干扰能力强,精度高的...

在写ds18b02时下到单片机中只有一个数码管亮,一个微亮,显示为5且数值...
显示数值是85吧 表示ds18b20读取数据,没有成功 只有一个数码管亮,一个微亮 这个是你,显示程序有问题。看看各部分的延时。肯定是一个延时长,一个延时短,要调一下

ds18b20写0和写1是什么意思有什么区别?那什么时候应该写0什么时候应 ...
单总线是一位一位传的..当你要给ds18b20写命令的时候,例如写跳过rom指令CCH (11001100B )就要一位一位的写0写1的传过去..

Sensata公司的代理商有哪些?
      公司主要的产品有:PT100温度传感器、PT20温度传感器、PT200温度传感器、PT500温度传感器、PT1000温度传感器、PT10000温度传感器、KTY84-130温度传感器、PTC热敏电阻温度传感器、INT69保护器、NTC温度传感器、电机马达温度传感器、温度仪表、温度变送器、DS18B220...

请问我用DS18B20编写的程序,想通过7段数码管显示温度,为什么数据显示不...
再者,我觉得你在显示函数中调用了温度值测量函数是有大问题的,因为这样每次扫描之前都会有段延时,而且这个延时至少都是几十毫秒,因为这个时间使得你的扫描数码管显示不连续,看起来就不稳定。如果你想间隔一段时间就采样一次温度值的话,可以用定时器中断,在中断函数中来测量温度,这样就可以了。

基于18B20的多点温度显示系统
55H 只有地址码匹配的DS18B2才能接受后续的命令 4EH 写入温度上\/下限,紧随其后是2字节数据,对应上限和下限值 F0H 锁定总线上DS18B20的个数和识别其ROM中的64位地址序列码 48H 将9字节暂存寄存器的第3和4字节复制到EEPROM中 ECH 只有温度超过上限或下限的DS18B20才做出响应 B8H 将EEPROM的内容恢复到暂存寄存器...

单片机与DS18B20并用LCD1602显示 c程序
\/\/Init_DS18B20();\/\/温度传感器DS18b2初始化子函数,在头文件中 flag=ReadTemperature();\/\/将18b2头文件运行返回的函数结果送到变量FLAG中,用于显示 \/\/读取秒时分周日月年七个数据(DS1302的读寄存器与写寄存器不一样): miao = BCD_Decimal(read_1302(0x81)); fen = BCD_Decimal(read_1302(0x83)); shi...

红旗区15220295453: 火灾报警DS18B20设定温度是多少?
主父刷壹枚: 报警温度是自己设定的哈 你可以设定20°也可以设定75° 关键是看你自己 设置报警温度就是设置寄存器的值 采集值与设置的报警值相比较 我当时设置了报警上限和报警下限,比较准确

红旗区15220295453: 基于51单片机的DS18B20程序(数码管显示) -
主父刷壹枚: 参考下吧! 18B20数字温度显示系统 综合实验:用18B20(数字温度采集)74LS47(数码管译码)74LS138(三八译码) DS18B20是DALLAS公司生产的一线式数字温度传感器,具有3引脚TO-92小体积封装形式;温度测量范围为-55℃~+125...

红旗区15220295453: 寻求一个基于MSP430与DS18B20的温度采集报警C程序 -
主父刷壹枚: 采集程序我有 至于报警 自己设定吧 这个是DS18B20的程序:#include<msp430x14x.h>#define DQ1 P5OUT|=BIT0#define DQ0 P5OUT&=~BIT0#define DQ_out P5DIR|=BIT0#define DQ_in P5DIR&=~BIT0#define DQ_volt (P5IN&BIT0) typedef ...

红旗区15220295453: DS18B20温度采集模块编程思想? -
主父刷壹枚: DS18B20内部结构主要由四部分组成:64位光刻ROM、温度传感器、非挥发的温度报警触发器TH和TL、配置寄存器.光刻ROM中的64位序列号是出厂前被光刻好的,它可以看作是该DS18B20的地址序...

红旗区15220295453: avr单片机18B20温度传感器编程 -
主父刷壹枚: ;这是关于DS18B20的读写程序,数据脚P2.2,晶振12MHZ ;温度传感器18B20汇编程序,采用器件默认的12位转化,最大转化时间750微秒 ;可以将检测到的温度直接显示到AT89C51开发实验板的两个数码管上 ;显示温度00到99度,很准...

红旗区15220295453: DS18B20是怎样进行数据采集的?? 还有就是其输出信号的电平范围 -
主父刷壹枚: DS18B20有六条控制命令 指 令 约定代码 操 作 说 明 温度转换 44H 启动DS18B20进行温度转换 读暂存器 BEH 读暂存器9个字节内容 写暂存器 4EH 将数据写入暂存器的TH、TL字节 复制暂存器 48H 把暂存器的TH、TL字节写到E2RAM中 重新调E2RAM B8H 把E2RAM中的TH、TL字节写到暂存器TH、TL字节 参考http://baike.baidu.com/view/1341776.htm?fr=ala0_1(摘自)

红旗区15220295453: DS18B20测温程序 -
主父刷壹枚: 895.9,说明温度传感器还没有完成转换,你就读它了,注意时序,最后要有750ms的延时你好像没写

红旗区15220295453: 单片机:18B20温度传感器的程序:
主父刷壹枚: 这两句话是在读取18B20里面的数据,这个温度传感器是将温度已16个字节上传的,高5位表示的时温度的正负,后面12位表示的是无符号数值.最大精度为0.0625度.第一句是将16字节数据的低8位读出来,第二局是将数据的高8位读出来.

红旗区15220295453: 关于ds18b20温度采集时间 -
主父刷壹枚: 如果是12位的话大概是750mS,利用定时中断,你可以在采集之后做一次转换数据,在每次采集时是上一次转换的数据,这样可以做到并行工作.

红旗区15220295453: 用DS18B20采集温度,有段程序不太理解,求大神指教. -
主父刷壹枚: temp*0.0625 就是实际温度值 但为了传输方便,又要转成整型,还想保留一位小数,那就乘10,因为temp是整型的,temp=f_temp*10+0.5的时候,会发生强制类型转换,等号后面的数据的小数会直接被砍掉,不管是.1还是.9都会别忽略掉,+0.5...

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网