lanye 发表于 2013-4-19 20:29:39

关于DS18B20读ROM序列号,总读不出来,请教各位大虾啊!

我这个程序是在1602上作显示,第一排显示ROM序列号(挂一个DS18B20),第二排显示温度值。温度可以读出来,但是序列号读不出来,为什么啊???第一排显示16个0!请各位大虾指教一下啊!我是一个新手!程序如下

#include<reg52.h>
#include <Intrins.h>
#include "math.h"

#define uchar unsigned char
#define uint unsigned int

uchar data table;
uchar code table1[]="is ";

uchar tempL,tempH;                                       //设置温度值高位和低位

sbit RS=P2^4;                                                                   //数据命令选择端
sbit RW=P2^5;                                                                   //读写选择端
sbit EN=P2^6;                                                                   //使能端
sbit DQ=P1^3;



//延时16us子函数
void Delay16us()
{
        unsigned char a;
        for (a = 0; a < 4; a++);
}
//延时60us子函数
void Delay60us()
{
        unsigned char a;

        for (a = 0; a < 18; a++);
}

//延时480us子函数
void Delay480us()
{
        unsigned char a;

        for (a = 0; a < 158; a++);
}

//延时240us子函数
void Delay240us()
{
        unsigned char a;

        for (a = 0; a < 78; a++);
}

//延时500ms子函数
//void Delay500ms()
//{
//        unsigned char a, b, c;

//        for (a = 0; a < 250; a++)
//        for (b = 0; b < 3; b++)
//        for (c = 0; c < 220; c++);
//}

//芯片初始化
void Init18b20()
{
        while(1)
        {
                DQ = 0;
                Delay480us();                         //延时480us
                DQ = 1;
                Delay60us();                        //延时60us
                if(!DQ)                                //收到ds18b20的应答信号
                {       
                        DQ = 1;
                        Delay240us();                //延时240us
                        break;               
                }
        }
}

//写一个字节(从低位开始写)
void WriteByte(unsigned char btData)
{
        unsigned char i, btBuffer;

        for (i = 0; i < 8; i++)
        {
                btBuffer = btData >> i;
                if (btBuffer & 1)
                {
                        DQ = 0;
                        _nop_();
                        _nop_();
                        DQ = 1;
                        Delay60us();
                }
                else
                {
                        DQ = 0;
                        Delay60us();
                        DQ = 1;                       
                }
        }
}

//读一个字节(从低位开始读)
unsigned char ReadByte()
{
        unsigned char i, dat;

        for (i = 0; i < 8; i++)
        {
                dat >>= 1;
                DQ = 0;
                _nop_();
                _nop_();
                DQ = 1;
                Delay16us();
                if (DQ) dat |= 0x80;
                Delay60us();
        }

        return dat;
}
int ReadTemperature(void)
{                       
        float t;                                       
        int temperature,temp;                       //存放温度数值

        Init18b20();                                       //18b20初始化
           Delay16us();                            //延时1ms, 因为DS18B20会拉低DQ 60~240us作为应答信号
        WriteByte(0xcc);                               //跳过读取序列号
        WriteByte(0x44);                               //启动温度转换

        Init18b20();
           Delay16us();
        WriteByte(0xcc);                               //跳过读取序列号
        WriteByte(0xbe);                               //读温度寄存器(头两个值分别是温度低位和温度高位)
        tempL=ReadByte();                       //读出温度低位值
        tempH=ReadByte();                       //读出温度高位值
        temp=tempH;                                       //char是8位的,所以要将其转成int型
        temp<<=8;                                       
        temp|=tempL;
    t=temp * 0.0625;                  //算出温度值
        temperature=t*10+(t>0?0.5:-0.5);                  //将值扩大100倍,同时四舍五入
        return temperature;   
}

void ReadROM(void)                                                          //读ROM
{
    uint i;
        Init18b20();
        Delay16us();       
        WriteByte(0x33);
        Delay16us();
        for(i=0;i>=7;i++)
        {
          Delay16us();
                table=ReadByte();               
        }
}
//*****************液晶显示程序*****************************************************//

void delay(uint z)                                                          //延时
{
        uint x,y;
        for(x=z;x>0;x--)
                for(y=110;y>0;y--);
}

void Write_com(uchar com)                                           //写命令
{
        RS=0;
        P0=com;
        delay(5);
        EN=1;
        delay(5);
        EN=0;

}

void Write_data(uchar date)                                               //写数据
{
        RS=1;
        P0=date;
        delay(5);
        EN=1;
        delay(5);
        EN=0;
}                                               

void init()                                                                                   //初始化程序
{
        EN=0;
        RW=0;
        Write_com(0x38);                                                        //设置16*2显示,5*7点阵,8位数据接口
        Write_com(0x0c);                                                //设置开显示,不显示光标
        Write_com(0x06);                                                //写一个字符后地址指针加1
        Write_com(0x01);                                                //显示清0,数据指针清0

}
void display00(void)                                                 //显示函数
{
        uint num,tableH,tableL,i;
        uchar table0;
        num=0;
        while(num<16)
        {
                for(i=0;i<8;i++)
                {       
                        tableL=table&0x0f;                                        //低四位
                        tableH=table>>4;
                        tableH&=0x0f;                                                           //高四位
                        if((tableH<=0x09)&&(tableH>=0x00))                                                                //小于等于9的话,显示数字,+0x30
                        {
                                table0=tableH+0x30;
                        }
                        else table0=tableH+0x37;
                        num++;
                        if((tableL<=0x09)&&(tableL>=0x00))                                                               
                        {
                                table0=tableL+0x30;
                        }
                        else table0=tableL+0x37;                       
                        num++;
                }
        }
        Write_com(0x80);
        for(num=0;num<16;num++)
        {
                Write_data(table0);
                delay(5);
        }
}
void display(int T)                                                                //液晶显示
{
        uchar wendu={0,0,0,0,0,0};
        uint t,num;                                                                                //液晶初始化
        Write_com(0x80+0x40);
        for(num=0;num<3;num++)                                               //第二排显示"is "
        {
                Write_data(table1);
                delay(5);
        }
       
        if(T<0)wendu=0x2d;                                                       //显示温度正负号
    else wendu=0x2b;
        t=abs(T);
        wendu=t%1000/100+0x30;                                //温度值十位                               
        wendu=t%100/10+0x30;                                //温度个位
        wendu='.';                                                        //小数点
        wendu=t%10+0x30;                                        //小数点后一位
        wendu='C';                                                        //度C

        Write_com(0x80+0x43);                   //设置液晶显示首位地址
        for(num=0;num<6;num++)                                  //显示温度值
        {
                Write_data(wendu);
                delay(5);
        }                                                                                                  
}


void main()                                                                                        //主函数
{          
        int i;
        init();
        Init18b20();                                                                        //液晶初始化
        ReadROM();
    display00();
        while(1)
        {
            i=ReadTemperature();                
            delay(5);                                          
            display(i);
            delay(5);
        }       

       
}

显示是这样的:

lidar 发表于 2013-4-19 21:52:02

你读取序列号的循环里面就是错误的,for(i=0;i>=7;i++),应该是for(i=0;i<=7;i++),这样才会循环读取8次

xintao 发表于 2013-4-19 21:58:03

lidar 发表于 2013-4-19 21:52 static/image/common/back.gif
你读取序列号的循环里面就是错误的,for(i=0;i>=7;i++),应该是for(i=0;i

{:lol:} 看来是笔误码了,
一失足成知古风流人物……

lanye 发表于 2013-4-20 20:29:06

谢谢各位大神!太感谢了!{:loveliness:}

lanye 发表于 2013-4-20 20:35:34

lidar 发表于 2013-4-19 21:52 static/image/common/back.gif
你读取序列号的循环里面就是错误的,for(i=0;i>=7;i++),应该是for(i=0;i

{:loveliness:} ,太感谢你啦!我都没注意到!

小小码字员 发表于 2013-4-21 13:36:37

这么长的代码,坛子里的人认真看完了还给找出问题了,都是好人啊!{:lol:}
页: [1]
查看完整版本: 关于DS18B20读ROM序列号,总读不出来,请教各位大虾啊!