标题: DS1820 温度检测,串口输出 [打印本页]

作者: alewe    时间: 2018-2-27 09:17
标题: DS1820 温度检测,串口输出

请教一下大神,我用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);                 //发送至上位机  
    }  
}   


作者: gk2017    时间: 2018-2-27 10:05
基本都有了,把串口参数波特率设置好就可以了吧
作者: HEIZI555    时间: 2018-2-27 11:24
加串口参数波特率
作者: imxuheng    时间: 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'
作者: alewe    时间: 2018-2-27 11:33
这个程序是学习别人的,输出是hex格式,我想要文本格式的。
作者: lo_    时间: 2018-2-27 13:12
把得到的temp 转换成ascii码,然后串口打印出来就好了
作者: lbmjsj    时间: 2018-2-27 13:48
有时间一定好好学习一下!不错

作者: xuyaqi    时间: 2018-2-27 14:30
你用串口发送,完全没有必要考虑转成字符,你按浮点发送,上位机会把浮点转成字符的。
作者: alewe    时间: 2018-2-27 16:16
xuyaqi 发表于 2018-2-27 14:30
你用串口发送,完全没有必要考虑转成字符,你按浮点发送,上位机会把浮点转成字符的。

我试了,上位机收到的就是15,换算成10进制就是21度。我想直接收到21.00这样的温度数值,不知道怎么改。
作者: hange_v    时间: 2018-2-27 17:16
把printf函数重映射,即重写int fputc(int ch)函数,把串口发送一个字节函数放进去就行了
作者: 其二v    时间: 2018-2-27 21:22
不是要改成浮点型吗
作者: alewe    时间: 2018-2-28 17:36
已经搞定,感谢大家帮忙。
作者: 171650333    时间: 2018-3-1 09:58

加串口参数波特率
作者: asdf152128    时间: 2020-6-26 16:57
有时间可以一起交流下




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1