搜索
bottom↓
回复: 5

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

[复制链接]

出0入0汤圆

发表于 2013-4-19 20:29:39 | 显示全部楼层 |阅读模式
我这个程序是在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[8];
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[i]=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[16];
        num=0;
        while(num<16)
        {
                for(i=0;i<8;i++)
                {       
                        tableL=table[i]&0x0f;                                        //低四位
                        tableH=table[i]>>4;
                        tableH&=0x0f;                                                           //高四位
                        if((tableH<=0x09)&&(tableH>=0x00))                                                                //小于等于9的话,显示数字,+0x30
                        {
                                table0[num]=tableH+0x30;
                        }
                        else table0[num]=tableH+0x37;
                        num++;
                        if((tableL<=0x09)&&(tableL>=0x00))                                                               
                        {
                                table0[num]=tableL+0x30;
                        }
                        else table0[num]=tableL+0x37;                       
                        num++;
                }
        }
        Write_com(0x80);
        for(num=0;num<16;num++)
        {
                Write_data(table0[num]);
                delay(5);
        }
}
void display(int T)                                                                //液晶显示
{
        uchar wendu[6]={0,0,0,0,0,0};
        uint t,num;                                                                                //液晶初始化
        Write_com(0x80+0x40);
        for(num=0;num<3;num++)                                                 //第二排显示"is "
        {
                Write_data(table1[num]);
                delay(5);
        }
       
        if(T<0)wendu[0]=0x2d;                                                         //显示温度正负号
    else wendu[0]=0x2b;
        t=abs(T);
        wendu[1]=t%1000/100+0x30;                                //温度值十位                               
        wendu[2]=t%100/10+0x30;                                //温度个位
        wendu[3]='.';                                                        //小数点
        wendu[4]=t%10+0x30;                                        //小数点后一位
        wendu[5]='C';                                                        //度C

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


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

         
}

显示是这样的:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2013-4-19 21:52:02 | 显示全部楼层
你读取序列号的循环里面就是错误的,for(i=0;i>=7;i++),应该是for(i=0;i<=7;i++),这样才会循环读取8次

出0入0汤圆

发表于 2013-4-19 21:58:03 | 显示全部楼层
lidar 发表于 2013-4-19 21:52
你读取序列号的循环里面就是错误的,for(i=0;i>=7;i++),应该是for(i=0;i

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

出0入0汤圆

 楼主| 发表于 2013-4-20 20:29:06 | 显示全部楼层
谢谢各位大神!太感谢了!

出0入0汤圆

 楼主| 发表于 2013-4-20 20:35:34 | 显示全部楼层
lidar 发表于 2013-4-19 21:52
你读取序列号的循环里面就是错误的,for(i=0;i>=7;i++),应该是for(i=0;i

,太感谢你啦!我都没注意到!

出0入0汤圆

发表于 2013-4-21 13:36:37 | 显示全部楼层
这么长的代码,坛子里的人认真看完了还给找出问题了,都是好人啊!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 18:22

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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