当前位置:首页 > 技术学院 > 热搜器件
[导读]DS18B20温度计的C语言程序

#include<reg51.h>
#include<intrins.h>
#include <math.H>  //要用到取绝对值函数abs()
//通过DS18B20测试当前环境温度, 并通过数码管显示当前温度值, 目前显示范围: -55~ +125度
sbit wela = P2^7;  //数码管位选
sbit dula = P2^6;  //数码管段选
sbit ds = P2^2;
int tempValue;
//0-F数码管的编码(共阳极)
unsigned char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,
0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
//0-9数码管的编码(共阳极), 带小数点
unsigned char code tableWidthDot[]={0x40, 0x79, 0x24, 0x30,
0x19, 0x12, 0x02,0x78, 0x00, 0x10};
//延时函数, 对于11.0592MHz时钟, 例i=10,则大概延时10ms.
void delay(unsigned int i)
 {
  unsigned int j;
   while(i--)
    {
        for(j = 0; j < 125; j++);
    }
 }
 
//初始化DS18B20
//让DS18B20一段相对长时间低电平, 然后一段相对非常短时间高电平, 即可启动
void dsInit()
 {
   //对于11.0592MHz时钟, unsigned int型的i, 作一个i++操作的时间大于?us
   unsigned int i;
   ds = 0;
    i = 100;   //拉低约800us, 符合协议要求的480us以上
    while(i>0) i--;
    ds = 1;    //产生一个上升沿, 进入等待应答状态
     i = 4;
   while(i>0) i--;
 }
 
void dsWait()
 {
     unsigned int i;
     while(ds);
    while(~ds);  //检测到应答脉冲
    i = 4;
    while(i > 0) i--;
}
//向DS18B20读取一位数据
//读一位, 让DS18B20一小周期低电平, 然后两小周期高电平,
//之后DS18B20则会输出持续一段时间的一位数据
bit readBit()
{
    unsigned int i;
   bit b;
   ds = 0;
  i++;   //延时约8us, 符合协议要求至少保持1us
  ds = 1;
  i++; i++;  //延时约16us, 符合协议要求的至少延时15us以上
   b = ds;
    i = 8;
    while(i>0) i--;  //延时约64us, 符合读时隙不低于60us要求
   return b;
}
//读取一字节数据, 通过调用readBit()来实现
unsigned char readByte()
{
   unsigned int i;
     unsigned char j, dat;
    dat = 0;
   for(i=0; i<8; i++)
   {
        j = readBit();
       //最先读出的是最低位数据
       dat = (j << 7) | (dat >> 1);
    }
    return dat;
}
//向DS18B20写入一字节数据
void writeByte(unsigned char dat)
{
 unsigned int i;
   unsigned char j;
    bit b;
  for(j = 0; j < 8; j++)
   {
       b = dat & 0x01;
       dat >>= 1;
       //写"1", 将DQ拉低15us后, 在15us~60us内将DQ拉高, 即完成写1
        if(b)
       {
            ds = 0;
           i++; i++;  //拉低约16us, 符号要求15~60us内
            ds = 1; 
           i = 8; while(i>0) i--;  //延时约64us, 符合写时隙不低于60us要求
       }
      else  //写"0", 将DQ拉低60us~120us
           ds = 0;
            i = 8; while(i>0) i--;  //拉低约64us, 符号要求
            ds = 1;
           i++; i++;  //整个写0时隙过程已经超过60us, 这里就不用像写1那样, 再延时64us了
    
    }
}
//向DS18B20发送温度转换命令
void sendChangeCmd()
{
   dsInit();    //初始化DS18B20, 无论什么命令, 首先都要发起初始化
   dsWait();   //等待DS18B20应答
   delay(1);    //延时1ms, 因为DS18B20会拉低DQ 60~240us作为应答信号
    writeByte(0xcc); //写入跳过序列号命令字 Skip Rom
   writeByte(0x44); //写入温度转换命令字 Convert T
}
//向DS18B20发送读取数据命令
void sendReadCmd()
{
   dsInit();
   dsWait();
   delay(1);
   writeByte(0xcc); //写入跳过序列号命令字 Skip Rom
   writeByte(0xbe); //写入读取数据令字 Read Scratchpad
}
//获取当前温度值
int getTmpValue()
{
    unsigned int tmpvalue;
   int value; //存放温度数值
  float t;
    unsigned char low, high;
   sendReadCmd();
    //连续读取两个字节数据
  low = readByte();
  high = readByte();
    //将高低两个字节合成一个整形变量
    //计算机中对于负数是利用补码来表示的
    //若是负值, 读取出来的数值是用补码表示的, 可直接赋值给int型的
value
    tmpvalue = high;
    tmpvalue <<= 8;
    tmpvalue |= low;
   value = tmpvalue;
 
    //使用DS18B20的默认分辨率12位, 精确度为0.0625度, 即读回数据的最低位代表0.0625度
   t = value * 0.0625;
    //将它放大100倍, 使显示时可显示小数点后两位, 并对小数点后第三进行4舍5入
   //如t=11.0625, 进行计数后, 得到value = 1106, 即11.06 度
   //如t=-11.0625, 进行计数后, 得到value = -1106, 即-11.06 度
    value = t * 100 + (value > 0 ? 0.5 : -0.5); //大于0加0.5, 小于0减0.5
   return value;
}
unsigned char const timeCount = 3; //动态扫描的时间间隔
//显示当前温度值, 精确到小数点后一位
//若先位选再段选, 由于IO口默认输出高电平, 所以当先位选会使数码管出现乱码
void display(int v)
{
    unsigned char count;
   unsigned char datas[] = {0, 0, 0, 0, 0};
   unsigned int tmp = abs(v);
    datas[0] = tmp / 10000;
   datas[1] = tmp % 10000 / 1000;
   datas[2] = tmp % 1000 / 100;
    datas[3] = tmp % 100 / 10;
    datas[4] = tmp % 10;
   if(v < 0)
    {
       //关位选, 去除对上一位的影响
       P0 = 0xff;
       wela = 1; //打开锁存, 给它一个下降沿量
       wela = 0;
       //段选
      P0 = 0x40; //显示"-"号
       dula = 1;  //打开锁存, 给它一个下降沿量
      dula = 0;
       //位选
      P0 = 0xfe;
       wela = 1; //打开锁存, 给它一个下降沿量
        wela = 0;
      delay(timeCount);
    }
    for(count = 0; count != 5; count++)
    {
        //关位选, 去除对上一位的影响
       P0 = 0xff;
      wela = 1; //打开锁存, 给它一个下降沿量
       wela = 0;
        //段选
        if(count != 2)
      {
    
               P0 = table[datas[count]];  //显示数字
        }
       else
        {
            P0 = tableWidthDot[datas[count]]; //显示带小数点数字
       }
        dula = 1;  //打开锁存, 给它一个下降沿量
        dula = 0;
        //位选
        P0 = _crol_(0xfd, count); //选择第(count + 1) 个数码管
       wela = 1; //打开锁存, 给它一个下降沿量
       wela = 0;
       delay(timeCount);
    }
}
void main()
{
  unsigned char i;
 
   while(1)
    {
        //启动温度转换
       sendChangeCmd();
       //显示5次
        for(i = 0; i < 40; i++)
        {
           display(tempValue);
     }
        tempValue = getTmpValue();
    }

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

该系列产品有助于嵌入式设计人员在更广泛的系统中轻松实现USB功能

关键字: 单片机 嵌入式设计 USB

单片机编程语言是程序员与微控制器进行交流的桥梁,它们构成了单片机系统的软件开发基石,决定着如何有效、高效地控制和管理单片机的各项资源。随着微控制器技术的不断发展,针对不同应用场景的需求,形成了丰富多样的编程语言体系。本文...

关键字: 单片机 微控制器

单片机,全称为“单片微型计算机”或“微控制器”(Microcontroller Unit,简称MCU),是一种高度集成化的电子器件,它是现代科技领域的关键组件,尤其在自动化控制、物联网、消费电子、汽车电子、工业控制等领域...

关键字: 单片机 MCU

STM32是由意法半导体公司(STMicroelectronics)推出的基于ARM Cortex-M内核的32位微控制器系列,以其高性能、低功耗、丰富的外设接口和强大的生态系统深受广大嵌入式开发者喜爱。本文将详细介绍S...

关键字: STM32 单片机

嵌入式开发作为信息技术领域的重要分支,其涉及的语言种类繁多,各具特色。这些语言的选择取决于目标平台的特性、性能需求、开发者的熟练程度以及项目的具体要求。本文将详细介绍几种常见的嵌入式开发语言,包括C语言、C++、汇编语言...

关键字: 嵌入式开发 C语言

在当前的科技浪潮中,单片机作为嵌入式系统的重要组成部分,正以其强大的功能和广泛的应用领域受到越来越多行业的青睐。在众多单片机中,W79E2051以其卓越的性能和稳定的工作特性,成为市场上的明星产品。本文将深入探讨W79E...

关键字: 单片机 w79e2051单片机

单片机,又称为微控制器或微处理器,是现代电子设备中的核心部件之一。它集成了中央处理器、存储器、输入输出接口等电路,通过外部信号引脚与外部设备进行通信,实现对设备的控制和管理。本文将详细介绍单片机的外部信号引脚名称及其功能...

关键字: 单片机 微控制器 中央处理器

随着科技的飞速发展,单片机和嵌入式系统在现代电子设备中的应用越来越广泛。它们不仅提高了设备的智能化水平,还推动了各行各业的创新与发展。在单片机和嵌入式系统的开发中,编程语言的选择至关重要。本文将深入探讨单片机和嵌入式系统...

关键字: 单片机 嵌入式系统 电子设备

DS18B20是常用的数字温度传感器,其输出的是数字信号,具有体积小,硬件开销低,抗干扰能力强,精度高的特点。

关键字: ds18b20 温度传感器 数字信号

PLC(可编程逻辑控制器)和单片机是两种不同的控制设备,它们之间存在明显的区别:

关键字: 单片机 plc 控制器
关闭
关闭