切换到宽版
  • 2056阅读
  • 5回复

[C51]AT89S51 + DS18B20【温度计】 [复制链接]

上一主题 下一主题
离线小陈兔
 

发帖
4834
M币
1105
专家
26
粉丝
277
只看楼主 倒序阅读 我要置顶 楼主  发表于: 2018-08-28
临时起意作案:


不锈钢外壳探头,可以测液体温度,顺手做了木壳。
左1数码管显示符号位“-”,正温度则不显示,没有考虑>=100摄氏度时进位的问题,所以量程-55~99.9℃.


作案工具,【小推兔】赞助的T12-C4大马蹄。


烧录用Esay 51 Pro V2.0(EP51),因为笔记本没有COM接口,所以用到了上次修好的CH340G USB-TTL小板。


STC快用完了,临时起意把还有很多的AT拿来换上,把EA引脚接高电平就可以代换。
--------------------------------------------------------------------------------------------------------
下面Po上代码:

/*MCU = AT89S51
CLOCK = 12MHz
Sensor = DS18B20*/
#include <reg51.h>
#include <intrins.h>

#define uchar unsigned char

sbit DS18B20_data = P1^0;//DS18B20数据线;

uchar time;//精确延时专用变量;
uchar code table[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x7f};//数码管共阳极接法,负逻辑,0~9和小数点;

void delay(uchar x);//延时x ms;
void DS18B20_init();//初始化DS18B20;
void write_byte(uchar dat);//写字节;
void wait_to_read_byte();//准备读字节;
uchar read_byte();//读字节;
void display(uchar symbol, A, B, C);//显示结果;

void main(){
    uchar symbol;//符号位;
    uchar temp;//温度值临时变量;
    uchar TH, TL;//温度数据高低八位;
    uchar TN, TD;//温度值整数、小数部分;
    uchar A, B, C;//十位, 个位, 十分位;

    while(1){
    wait_to_read_byte();
    TL = read_byte();
    TH = read_byte();

    if((TH&0xf8)!= 0x00)//判断符号位;
    {symbol = 1;}//温度值为负;
    else
    {symbol = 0;}//温度值为正;

    if(symbol)
    {
    TL = ~TH;
    TH = ~TH;
    temp = TL + 1;
    TL = temp;//负温度时预处理;

    TN = TH<<4|TH>> 4;//温度值整数部分;
    TD = (((TL<<4) / 128*80) + ((TL<<5) / 128*40) + ((TL<<6) / 128*20) + ((TL<<7) / 128*10)) / 16;//温度值小数部分;
    }
    else
    {
    TN = TH<<4|TL>>4;//温度值整数部分;
    TD = (((TL<<4) / 128*80) + ((TL<<5) / 128*40) + ((TL<<6) / 128*20) + ((TL<<7) / 128*10)) / 16;//温度值小数部分;
    }

    A = TN / 10;//温度值十位;
    B = TN % 10;//温度值个位;
    C = TD;//温度值十分位;

    display(symbol, A, B, C);//显示结果

    P1 = 0xff;//显示消隐;
}
}

void delay(uchar x){
    uchar i, j;

    for(i = x*2; i>0; i--)
    for(j = 250; j>0; j--);
}

void DS18B20_init(){
    DS18B20_data = 1;//数据总线置高电平;
    for(time = 2; time>0; time --);//延时6us,去抖动;

    DS18B20_data = 0;//数据总线置低电平;
    for(time = 180; time>0; time--);
    for(time = 180; time>0; time--);//延时724us;

    DS18B20_data = 1;//数据总线置高电平;
    for(time = 180; time>0; time--);
    for(time = 180; time>0; time--);//延时724us;
}

void write_byte(uchar byte){
    uchar i = 0;

    for(i = 8; i>0; i--){
    DS18B20_data = 1;//释放数据总线;
    _nop_();//延时1us;
    DS18B20_data = 0;//数据总线置低电平;

    DS18B20_data = byte & 0x01;//按位与取出位值;

    for(time = 15; time>0; time--);//延时32us;

    DS18B20_data = 1;//释放数据总线;
    for(time = 1; time >0; time--);//延时3us;

    byte >>= 1;//byte右移1位;
    }

    for(time = 4; time>0; time--);//延时10us;
}

void wait_to_read_byte(){
    DS18B20_init();//初始化DS18B20;

    write_byte(0xcc);//写命令,跳过ROM;
    write_byte(0x44);//写命令,启动温度转换;

    delay(1);//延时1ms;

    DS18B20_init();//初始化DS18B20;

    write_byte(0xcc);//写命令,跳过ROM;
    write_byte(0xbe);//写命令,读Cache;
}

uchar read_byte(){
    uchar i = 8;
    uchar byte;

    for(i = 8; i>0; i--){
    DS18B20_data = 1;//释放数据总线;
    _nop_();//延时1us;
    DS18B20_data = 0;//数据总线置低电平;
    _nop_();//延时1us,启动读时序;

    DS18B20_data = 1;//释放数据总线;
    for(time = 2; time>0; time--);//延时6us,等待采样;

    byte >>= 1;//byte右移一位,最高位缺省值为0;

    if(DS18B20_data)
    {byte |= 0x80;}//byte最高位赋值1;
    else
    {byte |= 0x00;}//byte最高位赋值0;

    for(time = 30; time>0; time--);//延时62us;
    }

    return byte;//返回byte的值
}

void display(uchar symbol, A, B, C){
    P2 = 0xfe;//数码管第1位使能;

    if(symbol)
    {P0 = 0xbf;
     delay(1);//延时1ms;
    }//显示负号;

    P0 = 0xff;//显示消隐;
/**********显示符号位**********/
    P2 = 0xfd;//数码管第2位使能;
    P0 = table[A];//显示十位;
    delay(1);//延时1ms;
    P0 = 0xff;//显示消隐;
/**********显示十位**********/
    P2 = 0xfb;//数码管第3位使能;
    P0 = table;//显示个位;
    delay(1);//延时1ms;
    P0 = 0xff;//显示消隐;
/**********显示个位**********/
    P2 = 0xfb;//数码管第3位使能;
    P0 = table[10];//显示小数点;
    delay(1);//延时1ms;
    P0 = 0xff;//显示消隐;
/**********显示小数点**********/
    P2 = 0xf7;//数码管第4位使能;
    P0 = table[C];//显示小数;
    delay(1);//延时1ms;
    P0 = 0xff;//显示消隐;
/**********显示小数**********/
}
---------------------------------
注意:数码管我用了共阳极形式,4个9012 PNP二极管作位使能,很好的利用了P0的开漏输出能力,连上拉电阻都省了。
更多作品见:
51 + ADC0804【电压表】http://bbs.mydigit.cn/read.php?tid=2511907
AT89C2051 + BH1750FVI【照度计】 http://bbs.mydigit.cn/read.php?tid=2513384
[ 此帖被小陈兔在2018-08-28 23:05重新编辑 ]
本文内容包含图片或附件,获取更多资讯,请 登录 后查看;或者 注册 成为会员获得更多权限
本帖最近打赏记录:共9条打赏M币+99
411183343 M币 +3 - 2018-08-30
dragonkyo M币 +8 原創內容 2018-08-30
吉米吉米 M币 +5 謝謝分享,不错 2018-08-29
数码家园 M币 +13 - 2018-08-29
红色的狂想 M币 +30 優秀文章 2018-08-29
温力口 M币 +9 谢谢分享。。。。。大婶终于睡醒了。。。。。。 2018-08-28
哈哈猫驴 M币 +13 多余探头求赠送一个 2018-08-28
花生仔 M币 +9 謝謝分享 2018-08-28
杨小伟 M币 +9 謝謝分享 探头跟我机台上的一样 2018-08-28
离线杨小伟

发帖
24750
M币
35424
专家
656
粉丝
16154
只看该作者 1楼 发表于: 2018-08-28
请登录后查看
离线411183343

发帖
2412
M币
4375
专家
166
粉丝
158
只看该作者 2楼 发表于: 2018-08-28
请登录后查看
离线哈哈猫驴

发帖
19257
M币
2
专家
737
粉丝
744
只看该作者 3楼 发表于: 2018-08-28
请登录后查看
离线温力口

发帖
60313
M币
51283
专家
569
粉丝
909
只看该作者 4楼 发表于: 2018-08-28
请登录后查看
离线吉米吉米

发帖
12447
M币
6412
专家
12
粉丝
115
只看该作者 5楼 发表于: 2018-08-29
请登录后查看
快速回复
限80 字节
温馨提示:所有技术区严禁灌水,“沙发”“顶”字样;禁止广告贴;以免被删除
 
上一个 下一个