找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1561|回复: 5
收起左侧

大佬帮我看下单片机DS18b20程序哪里有错误?

[复制链接]
ID:518415 发表于 2019-4-22 11:06 | 显示全部楼层 |阅读模式
我是用DS18B20传感器检测温度的,然后用数码管把它显示出来,但是数码管显示的数值一直是00000006固定不变,数码管代码好像也没啥问题,让它显示87654321这些固定值也可以显示出来,请大佬帮帮忙

z3.jpg
z2.jpg
z1.jpg
回复

使用道具 举报

ID:432823 发表于 2019-4-22 15:01 | 显示全部楼层
应与显示无关,与DS18b20读出数据有关,可能没有读出,tp=0是初始值。
回复

使用道具 举报

ID:314000 发表于 2019-4-22 17:10 | 显示全部楼层
检查下单片机读DS18B20传感器的时序机延时是否有问题
回复

使用道具 举报

ID:293247 发表于 2019-4-22 21:01 | 显示全部楼层
如果你用protues上的ds18b20,你检查的ds18b20的时序,
之前我也存在这个问题
回复

使用道具 举报

ID:164602 发表于 2019-4-23 08:32 | 显示全部楼层
直接贴程序不好吗?还方便一些嘛。
给你一个例程:
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

程序适用的电路:
1.jpg

1.jpg

1.jpg

回复

使用道具 举报

ID:382454 发表于 2019-4-23 15:24 | 显示全部楼层
初学不要直接去写,在开发板里小小修改一下,等熟透了再去写,这样才是对的。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表