当前位置:首页 > 技术学院 > 热搜器件
[导读]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();
    }

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

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭