找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2815|回复: 13
收起左侧

DS1820 温度检测,串口输出

  [复制链接]
ID:283037 发表于 2018-2-27 09:17 | 显示全部楼层 |阅读模式

请教一下大神,我用STC15W408AS+DS18B20, 想实现串口输出文本类型的温度数值,类似28.50这样的温度数值,用下面这个代码需要怎么样改,感谢。

#ifndef _DS18B20_H  
#define _DS18B20_H  

#include "reg51.h"
#include "intrins.h"

#define uchar unsigned char  
#define uint  unsigned int  

sbit DQ = P3^2;         //DS1820数据线IO口  
bit nflag;                //温度正负标志  


/*****************************************************
    延时函数:延时1us
******************************************************/  
void delayus(uint i)  
{  
    while(i--);  
}  

/*****************************************************
    功能:         延时,最小单位为ms(晶振为11.0592
    计算方法:一个for循环 = 8个指令周期 = 8*12个机器周期
                        = 8*12*1/11.0592 = 0.0086ms
                        xms = 0.0086 * 110 = 0.946 ms
******************************************************/  
void delayms(uint xms)  
{  
    uint i,j;  
    for(i=xms;i>0;i--)            
        for(j=110;j>0;j--);  
}  

/*****************************************************
    DS18B20复位函数:
    1 数据线拉低,延时480us
    2 数据线拉高,延时480us
******************************************************/  
void ds1820rst()         
{  

    DQ = 1;             //初始状态  
    delayus(4);      
    DQ = 0;             //拉低  
    delayus(480);   //延时480us  
    DQ = 1;             //拉高  
    delayus(480);   
}  


/****************************************************
    18b20读数据:由低位到高位,重复八次,读一个字节
    1 数据线拉低,延时4us
    2 数据线拉高,延时10us
    3 读数据线状态一位,处理数据,延时45us
    4 重复步骤1-3
*****************************************************/  
uchar ds1820rd()  
{  
    uchar i = 0;  
    uchar dat = 0;  
    for(i=8;i>0;i--)  
    {  
        DQ = 0;         //拉低数据线  
        delayus(4);  
        dat>>=1;      //空出第一位  
        DQ = 1;         //拉高数据线  
        delayus(10);  
        if(DQ)          //若为高电平,则最高位置一  
            dat|=0x80;  
        delayus(45);//延时45us  
    }  
    return(dat);  
}  


/**************************************************
    18b20写数据:由低位到高位,重复八次,写一个字节
    1 数据线拉低,延时15us
    2 送一位数据到数据线,延时60us
    3 数据线拉高
    4 重复步骤1-3
**************************************************/  
void ds1820wr(uchar wdata)  
{  
    uchar i = 0;  
    for (i=8; i>0; i--)  
    {  
        DQ = 0;                  //数据线拉低  
        delayus(15);  
        DQ = wdata&0x01; //将数据最低位送入数据线  
        delayus(60);         //延时10us  
        DQ = 1;                  //数据线拉高  
        wdata>>=1;             //字节右移一位  
    }  
}  


/*****************************************************
    读温度并转换,根据RAM命令表写命令
        0xcc:               不读取序列地址
        0x44:               启动温度转换
        0xbe:               读取温度
******************************************************/  
uint read_temp()     
{  
    uchar TL,TH;                                        //TL:低八位 TH:高八位  
    uchar wd;                                               //最终温度的绝对值  

    ds1820rst();                                    //先复位  
    ds1820wr(0xcc);                             //不读取64位地址,因为总线上只有一个DB1820,单片工作  
    ds1820wr(0x44);                               //启动温度转换  

    delayus(125);  

    ds1820rst();  
    ds1820wr(0xcc);                             //跳过读序列号  
    ds1820wr(0xbe);                             //读取温度  

    TL = ds1820rd();                                //读低八位  
    TH = ds1820rd();                                //读高八位  

    wd = TL/16+TH*16;  
//  tvalue = TH;                                //tvalue为16位  
//  tvalue = (tvalue<<8)+TL;  
//  if((tvalue&0xf800) == 0xf800)       //判断负温度  
//  {  
//      tvalue=~tvalue+1;                           //补码=反码+1  
//      nflag = 0;                                      //置标志位为0  
//  }  
//  else  
//      nflag = 1;  
//   
//  wd = tvalue*0.625;                          //计算温度值  
    return(wd);                                         //返回温度值  
}  


/*****************************************************
    串口初始化函数:
******************************************************/  
void init()  
{                 
    P1M0 = 0;P1M1 = 0;  
    SCON = 0x40;  
    T2L  = 0xe0;  
    T2H  = 0xfe;  
    AUXR = 0x14;  
    AUXR |= 0x01;  
    TI = 1;  
}  


/*****************************************************
    串口通讯函数:发送两个字节,首字节为正负标志位,
                                第二个字节为温度值
******************************************************/  
void comm(uchar temper)  
{  

//  while(!TI == 1);  
//  {  
//      TI = 0;  
//      SBUF = nflag;  
//  }  
    while(!TI == 1);  
    {  
        TI = 0;  
        SBUF = temper;  
    }  
}  


#endif  


void main()  
{  
    uchar temp;                     //临时变量存储温度  
    init();                             //串口的初始化  

    while(1)  
    {  
        temp=read_temp();       //读取温度  
        delayms(500);               //延时0.5s  
        comm(temp);                 //发送至上位机  
    }  
}   

评分

参与人数 1黑币 +1 收起 理由
deaker + 1 很给力!

查看全部评分

回复

使用道具 举报

ID:285855 发表于 2018-2-27 10:05 | 显示全部楼层
基本都有了,把串口参数波特率设置好就可以了吧
回复

使用道具 举报

ID:96072 发表于 2018-2-27 11:24 | 显示全部楼层
加串口参数波特率
回复

使用道具 举报

ID:151348 发表于 2018-2-27 11:25 | 显示全部楼层
//  tvalue = TH;                                //tvalue为16位  
//  tvalue = (tvalue<<8)+TL;  
//  if((tvalue&0xf800) == 0xf800)       //判断负温度  
//  {  
//      tvalue=~tvalue+1;                           //补码=反码+1  
//      nflag = 0;                                      //置标志位为0  
//  }  
//  else  
//      nflag = 1;  
//   
//  wd = tvalue*0.625;                          //计算温度值  
    return(wd);                                         //返回温度值  
被注释掉的这段就是把温度转换为10进制,另外,数字转字符方法:数字0~9+0x30,就是将数字0-9转换为字符'0'~'9'
回复

使用道具 举报

ID:283037 发表于 2018-2-27 11:33 | 显示全部楼层
这个程序是学习别人的,输出是hex格式,我想要文本格式的。
回复

使用道具 举报

ID:285771 发表于 2018-2-27 13:12 | 显示全部楼层
把得到的temp 转换成ascii码,然后串口打印出来就好了
回复

使用道具 举报

ID:285953 发表于 2018-2-27 13:48 | 显示全部楼层
有时间一定好好学习一下!不错
回复

使用道具 举报

ID:94031 发表于 2018-2-27 14:30 | 显示全部楼层
你用串口发送,完全没有必要考虑转成字符,你按浮点发送,上位机会把浮点转成字符的。
回复

使用道具 举报

ID:283037 发表于 2018-2-27 16:16 | 显示全部楼层
xuyaqi 发表于 2018-2-27 14:30
你用串口发送,完全没有必要考虑转成字符,你按浮点发送,上位机会把浮点转成字符的。

我试了,上位机收到的就是15,换算成10进制就是21度。我想直接收到21.00这样的温度数值,不知道怎么改。
回复

使用道具 举报

ID:190832 发表于 2018-2-27 17:16 | 显示全部楼层
把printf函数重映射,即重写int fputc(int ch)函数,把串口发送一个字节函数放进去就行了

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:274747 发表于 2018-2-27 21:22 | 显示全部楼层
不是要改成浮点型吗

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:283037 发表于 2018-2-28 17:36 | 显示全部楼层
已经搞定,感谢大家帮忙。
回复

使用道具 举报

ID:286508 发表于 2018-3-1 09:58 | 显示全部楼层

加串口参数波特率
回复

使用道具 举报

ID:618577 发表于 2020-6-26 16:57 | 显示全部楼层
有时间可以一起交流下
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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