发新帖我要提问
12
返回列表
打印

DS18B20

[复制链接]
楼主: 林志财
手机看帖
扫描二维码
随时随地手机跟帖
21
林志财|  楼主 | 2013-7-29 23:36 | 只看该作者 回帖奖励 |倒序浏览
按3楼的调出来了,不过不是很准、差一两度好像
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar temp1,temp2,num,bai,shi,ge;
sbit ds18b20_pin=P3^7;
sbit lcdrs = P2^6;   /*定义LCD控制端口*/
sbit lcdrw= P2^5;   /*定义LCD控制端口*/
sbit lcden = P2^7;   /*定义LCD控制端口*/                       //单总线引脚
void delay(uint z)
{
   uint x,y;
   for(x=z;x>0;x--)
      for(y=110;y>0;y--);
}
void write_com(uchar com)
{
        lcdrs=0;
        P0=com;
        delay(5);
        lcden=1;
        delay(5);
        lcden=0;
}
void write_data(uchar date)
{
        lcdrs=1;
        P0=date;
        delay(5);
        lcden=1;
        delay(5);
        lcden=0;
}
void init()
{
        lcden=0;
    lcdrw=0;
        write_com(0x38);
        write_com(0x0c);
        write_com(0x06);
        write_com(0x01);
        write_com(0x84);
}
void ds18b20_init();                        //ds18b20初始化
bit  ds18b20_reset();                        //ds18b20复位
void ds18b20_write_dat(unsigned char dat);//些数据到ds18b20
unsigned char ds18b20_read_dat();//读数据

/****************************************
*DS18B20 初始化
*函数名称:ds18b20_init()
*说明:本初始化程序可以不要,因为18B20在出厂时就被配置为12位精度了
*****************************************/
void ds18b20_init()
{
        ds18b20_reset();
        ds18b20_write_dat(0xcc);                //跳过ROM        
        ds18b20_write_dat(0x4e);                //写暂存器
        ds18b20_write_dat(0x20);                //往暂存器的第三字节中写上限值
        ds18b20_write_dat(0x00);                //往暂存器的第四字节中写下限值
        ds18b20_write_dat(0x7f);                //将配置寄存器配置为12位精度
        ds18b20_reset();
}
void delay1(uint i)
{
        while(i--);
}

/*********************************************
*DS18B20复位及存在检测(通过存在脉冲可以判断DS18B20是否损坏
*函数名称:ds18b20_reset()
*说明:函数返回一个位标量(0或1)flag=0存在,反之flag=1不存在
**********************************************/
bit ds18b20_reset()
{
        unsigned char i;
        bit flag;

        ds18b20_pin=0;                                        //拉低总线
        for(i=240;i>0;i--);                                 //延时480微秒,产生复位脉冲
        ds18b20_pin=1;                                        //释放总线
        for(i=40;i>0;i--);                                //延时80微秒对总线采样
        flag=ds18b20_pin;                                //对数据脚采样
        for(i=200;i>0;i--);                                //延时400us等待总线恢复
        return (flag);

}
/********************************************
*写数据到DS18B20
*函数名称:ds18b20_write_dat()
*********************************************/
void ds18b20_write_dat(unsigned char dat)
{
        unsigned char i,j;
        for(i=8;i>0;i--)
        {
                 ds18b20_pin=0;                                //拉低总线,产生写信号
                for(j=2;j>0;j--);                        //延时4us
                ds18b20_pin=dat&0x01;                //发送1位
                for(j=30;j>0;j--);                        //延时60us,写时序至少要60us
                ds18b20_pin=1;                                //释放总线,等待总线恢复
                dat>>=1;                                        //准备下一位数据的传送
        }
}
/**********************************************
*从DS18B20中读数据
*函数名称:ds18b20_read_dat()
*
**********************************************/

unsigned char ds18b20_read_dat()
{
        unsigned char i,j,tempdat;
        for(i=8;i>0;i--)
        {
         tempdat>>=1;
         ds18b20_pin=0;                                        //拉低总线,产生读信号
         for(j=2;j>0;j--);                                //延时4us
         ds18b20_pin=1;                                        //释放总线,准备读数据
         for(j=4;j>0;j--);                                //延时8us读数据
         if(ds18b20_pin==1)
                 {        
                        tempdat|=0x80;
                }
          for(j=30;j>0;j--);                        //延时60us
          ds18b20_pin=1;                                //拉高总线,准备下一位数据的读取
        }
        return(tempdat);                                //返回读到的数据
}
uchar  read_temper(void)
{
        uchar a=0;
        uchar b=0;
        uchar c=0;
        ds18b20_reset();
        ds18b20_write_dat(0xcc);
        ds18b20_write_dat(0x44);
        delay1(10);
        ds18b20_reset();
        ds18b20_write_dat(0xcc);
        ds18b20_write_dat(0xbe);
        delay1(20);
        a=ds18b20_read_dat();
        b=ds18b20_read_dat();
        temp1=b<<4;
        temp1+=(a&0xf0)>>4;
        temp2=a&0x0f;
        return(temp1);
}
main()
{
        init();
        delay1(20);
        ds18b20_init();
        while(1)
        {
                write_com(0x84);               
                num=read_temper();
                  shi=num%100/10;
                ge=num%100%10;
                write_data(0x30+shi);
                write_data(0x30+ge);
        }
}

使用特权

评论回复
22
林志财|  楼主 | 2013-7-29 23:38 | 只看该作者
不过还是对DS18B20的时序难搞。读不到就要慢慢调了

使用特权

评论回复
23
叶伤| | 2013-7-30 08:26 | 只看该作者
林志财 发表于 2013-7-29 23:38  不过还是对DS18B20的时序难搞。读不到就要慢慢调了

DS18B20误差±0.5摄氏度,感觉上来说就是差了一两度。想精准就要读出温度剩余值自己计算。

我做过的这玩意都是发读取控制,然后回主程序,n次(大概也有1~2秒再读),读取速度太快会让芯片发热。

使用特权

评论回复
24
zjxcml| | 2013-11-15 15:42 | 只看该作者
我做的是9位 100ms就读回来了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则