找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1602|回复: 0
打印 上一主题 下一主题
收起左侧

注释详细的51单片机读取DS18B20温度C语言源代码

[复制链接]
跳转到指定楼层
楼主
ID:618342 发表于 2020-9-16 15:18 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. #include <reg51.h>
  2. #include <intrins.h>
  3. #define uchar unsigned  char

  4. sbit   DQ=P3^7;
  5. bdata  uchar dat;
  6. sbit   dat0=dat^0;
  7. sbit   dat7=dat^7;
  8. uchar dp[16]={0,0,1,1,2,3,3,4,5,5,6,6,7,8,8,9};

  9. uchar code segtab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
  10. 0x80,0x90, 0x88,0x83,0xc6,0xa1,0x86,0x8e,0x89,0x8c,0xbf,0xff};

  11. uchar dbuf[4]={0,0,0,0x12};

  12. void disp(void)
  13. {
  14.         uchar i,n,bsel;
  15.         bsel=0x01;
  16.         for(n=0;n<4;n++)
  17.         {
  18.                 P2=0xf0|bsel;
  19.                 P0=segtab[dbuf[n]];
  20.                 if(n==1)P0=P0&0x7f;
  21.                 bsel=_crol_(bsel,1);
  22.                 for(i=1;i<200;i++);
  23.                 P0=0xff;
  24.                
  25.         }
  26.         
  27. }

  28. void  delay15(uchar n)                //15us????
  29. { do {
  30.         _nop_();
  31.         _nop_();
  32.         _nop_();
  33.         _nop_();
  34.         _nop_();
  35.         _nop_();
  36.         _nop_();
  37.         _nop_();
  38.         _nop_();
  39.         _nop_();
  40.         _nop_();
  41.         _nop_();               
  42.                 n--;
  43.         }while(n);
  44.   }
  45. bit reset(void)         //初始化DS18B20
  46. {
  47.          bit err;
  48.    DQ=0;                        //在数据线上产生600US低电平
  49.    delay15(40);               
  50.    DQ=1;                        //数据线电平拉高
  51.    delay15(4);        //延时60us
  52.    err=DQ;                        //将读数据线状态,如果为低则复位成功
  53.    delay15(18);        //     如果数据线为高则复位不成功
  54.    return(err);
  55. }

  56. void wrbyte(uchar d)        //单片机向DS18B20发送一个字节的命令
  57. {
  58.          uchar i;
  59.    dat=d;         
  60.    for(i=8;i>0;i--)           //循环写入8位
  61.    {
  62.                  DQ=0;                            //数据低电平产生15us
  63.      delay15(1);
  64.            DQ=dat0;                        //将当前数据为送至数据总线
  65.            dat=dat>>1;                //将下一位要写入的数据移到最低位
  66.            delay15(1);                //延时15us
  67.      DQ=1;                            //数据线拉高为写入下一位做准备
  68.     }
  69. }

  70. uchar  rdbyte(void)        //从DS18B20读取一个字节数据
  71.   {  
  72.                 uchar i;
  73.     dat=0;                                 //读取数据初始值要为0
  74.     for(i=8;i>0;i--)         //循环读取8位(先低后高)
  75.     {  
  76.                           dat=dat>>1;   //读出数据线右移一位        
  77.                                 DQ=0;         //产生1us负脉冲
  78.                                 _nop_();
  79.         DQ=1;                            // 产生15us高电平
  80.         delay15(1);     
  81.         dat7=DQ;            // 读取到数据放入暂存·
  82.         delay15(4);  // 延时,为读取下一位做准备
  83.       }
  84.      return(dat);  //将读取到的温度值返回给单片机
  85.   }   
  86.         
  87. void convert(void) //启动DS18B20开始温度转换
  88. {
  89.         bit err;
  90.         err=reset();     //先复位温度传感器
  91.         wrbyte(0xcc);   //由于我们本次只用了一个温度传感器,则这里跳过传感器的识别
  92.         wrbyte(0x44);   //启动温度传感器
  93.         
  94. }
  95. int readt(void)//读取DS18B20暂存器中的值
  96. {
  97.         uchar h,l;
  98.         bit err;
  99.         err=reset();  //复位温度传感器
  100.         wrbyte(0xcc);//跳过多传感器识别
  101.         wrbyte(0xbe);//读暂存指令
  102.         l=rdbyte();  //读取温度低位
  103.         h=rdbyte();  //读取温度高位
  104.         return(h*256+l);  //返回读取到的温度
  105. }

  106. void format(int t)//将读取到的温度值转换为带一位小数的BCD码格式送至缓存区,并灭掉高位0
  107. {
  108.         bit zf;     // 正负标记,0正数;1负数
  109.         zf=0;      
  110.         if(t<0)     //如果温度在0度以下
  111.         {
  112.                 zf=1;     //置为负数标志
  113.                 t=-t;     //求补码
  114.         }
  115.         dbuf[0]=dp[t&0x0f]; //求出温度的小数
  116.         t=t>>4;   //移掉小数部分
  117.         
  118.         if(t==0xff)t=99;  //字节扩展
  119.         dbuf[3]=t/100;    //求出百位
  120.         t=t%100;
  121.         dbuf[2]=t/10;    //求出十位
  122.         dbuf[1]=t%10;   // 求出个位
  123.         if(zf==1)         //如果是负数
  124.         {
  125.                 if(dbuf[2]==0)  // 如果十位为零
  126.                 {
  127.                         dbuf[3]=0x13;   //显示格式为“-x.x"
  128.                         dbuf[2]=0x12;
  129.                         
  130.                 }
  131.                 else        // 如果十位不为零
  132.                 dbuf[3]=0x12;  //显示格式为“-xx.x"
  133.                
  134.         }
  135.         else  //如果是正数
  136.         {
  137.         
  138.       if(dbuf[3]==0) //如果百位,十位都为零
  139.                         {
  140.                                 if(dbuf[2]==0)  //显示格式为x.x
  141.                                  dbuf[2]=0x13;   //如果只有百位为零
  142.                            dbuf[3]=0x13;   //显示格式为xx.x
  143.                            
  144.                         }        
  145.         }

  146. }

  147. main()
  148. {
  149.         int temp;   //保存测量的温度值
  150.         while(1)
  151.         {
  152.                 temp=0;  
  153.                 convert();  //启动温度转换
  154.                 temp=readt(); // 读取温度值
  155.                 format(temp);  //将温度值转换为BCD码送至显缓区
  156.                 disp();

  157.         }
  158. }
复制代码

DS18B20.7z

19.7 KB, 下载次数: 27, 下载积分: 黑币 -5

评分

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

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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