找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2239|回复: 3
收起左侧

51单片机—DS18B20简要记录

[复制链接]
ID:825513 发表于 2021-7-16 20:22 | 显示全部楼层 |阅读模式
昨天自己写了一个DS18B20的程序,能正常运行,发到51黑论坛上分享给和我一样的新手朋友们。

通过DS18B20采集环境温度,并在开发板的数码管模块上的左三位显示(带1位小数)。
MCU:AT89S52

源码:

#include <reg52.h>

sbit DS=P2^2;
sbit DU=P2^6;
sbit WE=P2^7;

unsigned char table0[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};                //无小数点
unsigned char table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};                //有小数点
unsigned int temp;

void Delay(unsigned int x)                //延时一定时间
{
  unsigned int i;
  while(x)
  {
    i=200;
    while(i>0)
    {
      i--;
    }
    x--;
  }
}

void DS18B20_init()                //DS18B20初始化
{
  unsigned int i;
  DS=0;                //MCU拉低电平最少480us,产生复位脉冲,然后释放总线
  i=103;                //延时480us~960us
  while(i>0)
  {
    i--;
  }
  DS=1;                //释放总线
  i=4;                //等待15~60us,然后DS18B20拉低电平60~240us表示应答
  while(i>0)
  {
    i--;
  }
  while(DS);
}

bit Read_bit()                //读取1比特的数据;“读”时序最少需要60us
{
  unsigned int i;
  bit dat;
  DS=0;
  i++;                //拉低电平最少1us,然后再释放总线
  DS=1;
  i++;                //等待一定时间后,再读取电平状态
  i++;
  dat=DS;
  i=8;
  while(i>0)
  {
    i--;                //等待最少60us
  }
  return dat;
}

unsigned char Read_byte()                //读取1字节的数据
{
  unsigned char i,j;
  unsigned char dat=0;
  for(i=1;i<=8;i++)
  {
    j=Read_bit();
    dat=(j<<7)|(dat>>1);
  }
  return dat;
}

void Write_byte(unsigned char dat)                //往DS18B20中写入1字节的数据
{
  unsigned int i;
  unsigned char j;
  bit x;
  for(j=1;j<=8;j++)
  {
    x=dat&0x01;                //依次将dat的每一位赋值给x
    dat=dat>>1;
    if(x)                //写入“1”
    {
      DS=0;                //拉低电平大于1us,在15us内拉高电平
      i++;
      i++;
      DS=1;                //“写”时序起始后的15~60us内,DS18B20处于采样状态,在此期间,若总线为高电平,则表示“1”
      i=8;
      while(i>0)
      {
        i--;                //等待最少60us
      }
    }
    else                //写入“0”;拉低电平60~120us,然后释放总线
    {
      DS=0;
      i=8;
      while(i>0)                //最少60us
      {
        i--;
      }
      DS=1;
    }
  }
}

void Change(void)                //温度转换,即测量温度
{
  DS18B20_init();
  Delay(1);
  Write_byte(0xcc);                //“跳过ROM”操作
  Write_byte(0x44);  //“温度转换”操作
}

unsigned int GET()                //获取温度数据
{
  float x;
  unsigned char a,b;
  DS18B20_init();
  Delay(1);
  Write_byte(0xcc);
  Write_byte(0xbe);                //读取DS18B20内的RAM的内容
  a=Read_byte();                //读取温度值的低8位
  b=Read_byte();                //读取温度值的高8位
  temp=b;
  temp<<=8;
  temp=temp|a;
  x=temp*0.0625;                //DS18B20默认设置为12位分辨率,即表示分辨率为0.0625摄氏度
  temp=x*10+0.5;
  return temp;
}

void OUTPUT(unsigned int temp)                //数码管显示
{
  unsigned char x0,x1,y,x2;
  x0=temp/100;
  y=temp%100;
  x1=y/10;
  x2=y%10;
  DU=0;
  P0=table0[x0];                //显示温度值的十位
  DU=1;
  DU=0;
  WE=0;
  P0=0xfe;
  WE=1;
  WE=0;
  Delay(1);
  DU=0;
  P0=table1[x1];                //显示温度值的个位
  DU=1;
  DU=0;
  WE=0;
  P0=0xfd;
  WE=1;
  WE=0;
  Delay(1);
  P0=table0[x2];                //显示温度值的十分位
  DU=1;
  DU=0;
  P0=0xfb;
  WE=1;
  WE=0;
  Delay(1);
}

void main()
{
  while(1)
  {
    Change();
    OUTPUT(GET());
  }
}


DS18B20.png
数码管模块.png
MCU.png

评分

参与人数 1黑币 +70 收起 理由
admin + 70 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:143767 发表于 2021-7-17 11:40 | 显示全部楼层
请问楼主,能显示负温度吗?
回复

使用道具 举报

ID:825513 发表于 2021-7-18 00:02 | 显示全部楼层
dj3365191 发表于 2021-7-17 11:40
请问楼主,能显示负温度吗?

DS18B20元器件能获取负温度的数据,不过我只做了正温度的显示,因为实际上负温度比较难营造(总不能放冰箱里吧),所以加上数码管显示负温度的功能的话就比较难完整地验证程序的正确性
回复

使用道具 举报

ID:146733 发表于 2021-7-18 15:02 | 显示全部楼层
请问楼主,这个要不要做个滤波?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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