ds18b20测温

ds18b20测温,第1张

首先,如果你要使用12864液晶显示温度的话,请保证你本身的液晶显示程序没有问题,这个可以通过让他随便显示一个数据或字符得到验证。假设本省液晶显示程序没有问题,那十有八九的问题就出在ds18B20温度传感器的程序上,应该是你的ds18b20温度传感器本身就没有工作,也就是说你的f_temp一直就是默认的值0,因为温度传感器没有正常工作吗,所以程序中也就无法给f_temp重新赋值,在保证液晶程序正确的情况下,你可以这样,给你要显示的变量,比如这里的这个f_temp赋上一个值,看他还显0吗,显然,如果现在显示的是你赋给他的这个值,那问题就出在我说的这个地方,温度传感器没有工作。我估计十有八九是这样的原因。对于温度传感器,你首先要明白,对于这类单总线的器件,由于其本省外部结构简单,所以他是需要较为复杂的软件程序来进行弥补的。本身它对时序的要求比较严格,所以延时一定要尽量精确,请在这一方面进行详细的检查。对于每一次的ds18B20 *** 作,基本都是一个复位、一个ROM指令、一个ram指令这样的顺序。ds18B20前段时间我用过,不过现在算起也有一些时间了,有些东西也在忘,所以暂时对你的程序我也不能帮你进行详细的检查了。你自己试试看吧。有时间的话我就在帮你瞅瞅。
刚才简单看了一下,你ds18B20程序肯定是有问题。首先就是你复位函数里最后少一个延时,这个延时是要有的,不然ds18b20是不能正常工作的。
简单说明如下,先多定义一个延时函数,以后用着方便。
void delay1(uchar count)
{
while(count>0) count--;
}
void dsreset(void) //初始化函数
{
DS=0;
delay1(103); //延时804473,符合480-960us之间
DS=1;
delay1(4); //延时36449us,符合15-60us之间

delay1(20); //延时164494us,符合60-240us之间(这个你少了!)
}
下面是读一位的函数,感觉也是延时有点问题,修改如下:(头文件多包涵一个#include <intrinsh>,这是定义下面调用的_nop_()函数用的头文件,该函数对于51系列12时钟单片机执行一次的时间为1us)
bit tempreadbit(void) //读一位函数
{uint i;
bit dat;
ds=0;
_nop_();
ds=1;
_nop_();
dat=ds;
delay1(7);
return(dat);
}
下面是写一个字节的函数(我只是改成了我用的延时函数,如果你的延时效果和我定义是一样的,其实也没有必要改,但是一定保证延时的时间,即时序!两个i++执行下来是1us吗,我没试,一般延时一毫秒我都是习惯用_nop_()函数,是的话你不该也成)
void tempwritebyte(uchar dat)
{uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{testb=dat&0x01;
dat=dat>>1;
if(testb)// xie 1
{ds=0;
_nop_();
ds=1;
delay1(7);
}
else
{ ds=0;
delay1(7);
ds=1;
_nop_();
}
}
}
上面这三个函数算是基础,一定要保证时序的准确性,先给你检查了这三个,你自己看看其他的地方还有没有需要是要改的。ds18B20就这样,你只要保证了时序,一般按照数据手册来写就差不多了。网上有很多现成的资料,在不理解的话你自己下下来看看。ds18b20的源程序网上一般很好找的。一定自己多看看数据手册,把一些最基本的搞清楚。最近事比较多,就不能给你细看了,就到这,祝你成功!

声明:以下的是我复制的
DS18B20
特点 独特的一线接口,只需要一条口线通信 多点能力,简化了分布式温度传感应用 无需外部元件 可用数据总线供电,电压范围为30 V至55 V 无需备用电源 测量温度范围为-55 ° C至+125 ℃ 。华氏相当于是-67 ° F到257华氏度 -10 ° C至+85 ° C范围内精度为±05 ° C
温度传感器可编程的分辨率为9~12位 温度转换为12位数字格式最大值为750毫秒 用户可定义的非易失性温度报警设置 应用范围包括恒温控制,工业系统,消费电子产品温度计,或任何热敏感系统
描述该DS18B20的数字温度计提供9至12位(可编程设备温度读数。信息被发送到/从DS18B20 通过1线接口,所以中央微处理器与DS18B20只有一个一条口线连接。为读写以及温度转换可以从数据线本身获得能量,不需要外接电源。 因为每一个DS18B20的包含一个独特的序号,多个ds18b20s可以同时存在于一条总线。这使得温度传感器放置在许多不同的地方。它的用途很多,包括空调环境控制,感测建筑物内温设备或机器,并进行过程监测和控制。

8引脚封装 TO-92封装 用途 描述
5 1 接地 接地
4 2 数字 信号输入输出,一线输出:源极开路
3 3 电源 可选电源管脚。见"寄生功率"一节细节方面。电源必须接地,为行动中,寄生虫功率模式。
不在本表中所有管脚不须接线 。
概况框图图1显示的主要组成部分DS18B20的。DS18B20内部结构主要由四部分组成:64位光刻ROM、温度传感器、非挥发的温度报警触发器TH和TL、配置寄存器。该装置信号线高的时候,内部电容器 储存能量通由1线通信线路给片子供电,而且在低电平期间为片子供电直至下一个高电平的到来重新充电。 DS18B20的电源也可以从外部3V-5 5V的电压得到。
DS18B20采用一线通信接口。因为一线通信接口,必须在先完成ROM设定,否则记忆和控制功能将无法使用。主要首先提供以下功能命令之一: 1 )读ROM, 2 )ROM匹配, 3 )搜索ROM, 4 )跳过ROM, 5 )报警检查。这些指令 *** 作作用在没有一个器件的64位光刻ROM序列号,可以在挂在一线上多个器件选定某一个器件,同时,总线也可以知道总线上挂有有多少,什么样的设备。
若指令成功地使DS18B20完成温度测量,数据存储在DS18B20的存储器。一个控制功能指挥指示DS18B20的演出测温。测量结果将被放置在DS18B20内存中,并可以让阅读发出记忆功能的指挥,阅读内容的片上存储器。温度报警触发器TH和TL都有一字节EEPROM 的数据。如果DS18B20不使用报警检查指令,这些寄存器可作为一般的用户记忆用途。在片上还载有配置字节以理想的解决温度数字转换。写TH,TL指令以及配置字节利用一个记忆功能的指令完成。通过缓存器读寄存器。所有的数据都读,写都是从最低位开始。
DS18B20有4个主要的数据部件:
(1)光刻ROM中的64位序列号是出厂前被光刻好的,它可以看作是该DS18B20的地址序列码。64位光刻ROM的排列是:开始8位(28H)是产品类型标号,接着的48位是该DS18B20自身的序列号,最后8位是前面56位的循环冗余校验码(CRC=X8+X5+X4+1)。光刻ROM的作用是使每一个DS18B20都各不相同,这样就可以实现一根总线上挂接多个DS18B20的目的。
(2) DS18B20中的温度传感器可完成对温度的测量,以12位转化为例:用16位符号扩展的二进制补码读数形式提供,以00625℃/LSB形式表达,其中S为符号位。
表1 DS18B20温度值格式表

# include <reg52h>
# include <intrinsh>
# define uchar unsigned char
# define uint unsigned int
sbit EN = P2^5; //使能端
sbit RS = P1^0; //数据/命令选择端1/0
sbit RW = P1^1; //读写状态
sbit BF = P0^7; //用来判忙
sbit key_1 = P2^6; //锁存U1开关
sbit key_2 = P2^7; //锁存U2开关
sbit ds = P2^2; //测温开关
uint temp;
void delay (int us); //延时函数
void cops ();
/============1602驱动==============/
void wait_1602 (); //判忙函数 1602
void write_com_1602 (uchar com); //写命令 1602
void write_date_1602 (uchar date); //写数据 1602
void write_sfm_1602 (uchar add,uint date); //发送数据 1602
void init_1602 (); //初始化 1602
/============DS18B20驱动===========/
void init_18B20 (); //初始化 18B20
void write_byte_18B20 (uchar com); //写一个数据 18B20
bit read_bit_18B20 (); //读一个数据 18B20
uchar read_byte_18B20 (); //读 18B20
void start_temp_sensor(void);
void read_t (); //读取温度

int main (void)
{
init_1602 (); //初始化 1602
init_18B20 ();
write_com_1602 (0x80+0x0e);
write_date_1602 (0xdf);
write_date_1602 ('C');
while (1)
{
start_temp_sensor();
delay (1000);
read_t (); //读取温度

write_sfm_1602 (0x0c,temp); //发送数据 1602 temp是温度
}
return 0;
}
void delay(int us) //延时函数
{
int a;
for(a=0;a<us;a++);
}
void nops () //延时4us
{
_nop_ ();_nop_ ();_nop_ ();_nop_ ();
}
/=======================1602驱动============================/
void wait_1602() //判忙
{
P0 = 0xff;
do
{
RS = 0;
RW = 1;
EN = 0;
EN = 1;
}
while(BF == 1);
EN = 0;
}
void write_com_1602(uchar com) //写命令
{
wait_1602 ();
RS = 0; //命令选择端
RW = 0; //读/写状态
P0 = com;
EN = 1;
EN = 0;
}
void write_date_1602(uchar date) //写数据
{
wait_1602 ();
RS = 1; //数据选择端
RW = 0; //读/写状态,选择写的状态
P0 = date;
EN = 1; //打开使能端
EN = 0; //关闭使能端
}
void write_sfm_1602(uchar add,uint date) //发送数据
{
uchar shi,ge;

shi=date/10;
ge=date%10;
write_com_1602 (0x80+add); //选择位置
delay(50);
write_date_1602 (0x30+shi); //0x30是把数字转化为字符
delay(50);
write_date_1602 (0x30+ge);
delay(50);
}
void init_1602() //1602初始化
{
key_1 = 0;
key_2 = 0;
EN = 0;
write_com_1602 (0x38); //用162显示
// delay(100);
write_com_1602 (0x0c); //设置开显示,不显示光标
// delay(100);
write_com_1602 (0x06); //每写一个字符后,地址加1
// delay(100);
write_com_1602 (0x01);
}
/=================DS18B20驱动====================/
void init_18B20 () //初始化 18B20
{
int i = 1;
while (i)
{
while (i)
{
ds = 1;
delay (1); //延时660
ds = 0;
delay (50);
ds = 1;
delay (6);
i = ds;
}
delay (45);
i = ~ds;
}
ds = 1;
}
void write_byte_18B20 (uchar com) //写一个数据 18B20
{
unsigned char j;
for(j = 0; j < 8; j++)
{
ds = 1;
_nop_ ();
ds = 0;
nops ();
ds = com&0x01;
delay (6);
com >>= 1;
}
ds = 1;
delay (1);
}
bit read_bit_18B20 () //读一个数据 18B20
{
bit b;
ds = 1;
_nop_ (); //延时1us
ds = 0;
nops ();
ds = 1;
nops ();
b = ds;
delay (6); //延时66us
return b;
}
uchar read_byte_18B20 () //读 18B20
{
int i;
uchar sdf = 0;
bit b;
// init_18B20 ();
for (i = 0;i < 8;i ++)
{
b = read_bit_18B20 ();
sdf >>= 1;
if (b)
{
sdf |= 0x80;
}
}
ds = 1;
return sdf;
}
void start_temp_sensor(void)
{
init_18B20();
write_byte_18B20(0xCC); // 发Skip ROM命令
write_byte_18B20(0x44); // 发转换命令
}
void read_t ()
{
uint l,h;
init_18B20 ();
write_byte_18B20 (0xcc);
write_byte_18B20 (0xbe);
l = read_byte_18B20 ();
h = read_byte_18B20 ();
temp = h;
temp <<= 8;
temp |= l;
temp >>= 4;
}
//我的用的是1602显示 至于IO口设置,您自己调一下


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/13205569.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-06-20
下一篇 2023-06-20

发表评论

登录后才能评论

评论列表(0条)

保存