DS18B20温度读取,定点小数显示-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 7556|回复: 2

DS18B20温度读取,定点小数显示

[复制链接]
发表于 2017-10-27 11:20 | 显示全部楼层 |阅读模式
本帖最后由 希岩 于 2020-5-28 13:08 编辑

    DS18B20是一个常用的高精度的温度传感器。采用单总线形式进行通讯。
    本次,我们通过Arduino UNO R3读取温度数据,然后通过串口打印。使用开发板上的数字口3作为DQ,Vdd连接5V。DQ和VDD之间用4.7K或者5.1k上拉电阻。
    烧录程序,结果如下,代码完全贴出来了。
[mw_shl_code=arduino,true]//功能: DS18B20 温度读取,定点小数显示
//制作: 希岩 (凌晨七點半)
//时间: 2017.10.27
//端口:  D3(PD3)作为单总线端口
typedef unsigned char uint08;
typedef signed   char sint08;
typedef unsigned int  uint16;
typedef signed   int  sint16;
typedef unsigned long uint32;
typedef const unsigned char cuint08;

#define DS_HIGH          DDRD&=~(1<<DDD3)          //作为输出
#define DS_LOW           DDRD|=(1<<DDD3)

#define READ_1WIRE_BUS   PIND&(1<<PIND3)          //读取数据
#define FAULT  1
#define RIGHT  0
#define DS18B20_READ_ROM         0x33
#define DS18B20_MATCH_ROM        0X55
#define DS18B20_SKIP_ROM         0XCC
#define DS18B20_SEARCH_ROM       0XF0
#define DS18B20_ALARM_SEARCH_ROM 0XEC
#define DS18B20_WRITE_RAM        0X40
#define DS18B20_READ_RAM         0XBE
#define DS18B20_COPY_RAM         0X48
#define DS18B20_CONVERT_TEM      0X44
#define  WDR()   MCUSR &= ~(1<<WDRF)   //清看门狗

uint08 DS_Data[3];   
uint08 Show_Buff[7];        //显示缓冲区
uint08 Flag=0;              //正负标志   
//------------------------------------------------------------------
uint08 DS18B20_Init(void)
{ uint08 ret;
   cli();
while(!READ_1WIRE_BUS) WDR();    //等待总线为高
   DS_LOW;
   delayMicroseconds(500);               //至少延时480us
   DS_HIGH;
   delayMicroseconds(50);                //延时15us-60us
   if(READ_1WIRE_BUS)
    ret = FAULT;
else
    ret = RIGHT;
   delayMicroseconds(500);
   sei();
   return ret;
}
//-----------------------------------------------------------------------------
//单总线读取8位数据
uint08 ds18b20_read(void)
{
uint08 data=0;
uint08 i=0;
cli();
for(i=0;i<8;i++)
{
data>>=1;
//DS_HIGH;
//while(!READ_1WIRE_BUS) WDR();    //等待总线为高
//delayMicroseconds(10);

DS_LOW;
delayMicroseconds(2);               //延时>1us
DS_HIGH;
delayMicroseconds(10);               // <15us
if(READ_1WIRE_BUS)
   data|=0x80;
   delayMicroseconds(50);            //>45us
}
sei();
return data;
}
//------------------------------------------------------------
//单总线写一字节
void ds18b20_write(uint08 data)
{
   uint08 i=0;
   cli();       //关中断
   for(i=0;i<8;i++)
   {
     if(data&0x01)
     {
       DS_LOW;
      delayMicroseconds(10);//10us
       DS_HIGH;
       delayMicroseconds(55);//55us
     }
     else
     {
       DS_LOW;
       delayMicroseconds(55);;//55us
       DS_HIGH;
       delayMicroseconds(10);//10us
     }
     data>>=1;
   }
   sei();      //开中断
}
//-----------------------------------------------------------------------------------
//执行转换
uint08 Ds18b20_Convert(void)
{
   //发送转换命令
   if(DS18B20_Init()==FAULT)
    return FAULT;
   
   ds18b20_write(DS18B20_SKIP_ROM); //忽略地址匹配,总线上只有一个器件时,或对总线所有器件操作
   
   ds18b20_write(DS18B20_CONVERT_TEM);//开始转换命令
   
   //等待转换完成,ds18b20默认转换精度为12位,此时最大转换时间为750ms
   delayMicroseconds(1000);      //延时
   
   //读温度字节
if(DS18B20_Init()==FAULT)  return FAULT;
   //SCI_Send_Str("test2\n");  
   ds18b20_write(DS18B20_SKIP_ROM); //忽略地址匹配
   ds18b20_write(DS18B20_READ_RAM); //读RAM命令
   DS_Data[0]=ds18b20_read();
   DS_Data[1]=ds18b20_read();
    //SCI_Send_Str("test3\n");  

   return RIGHT;
}
//----------------------------------------------------------------------------
//根据DS18B20中读的温度字节,计算实际温度值
uint16 Get_Temperature(void)
{
   uint16 u16tmp;
   u16tmp=(DS_Data[1]*256)+DS_Data[0];
   if((DS_Data[1]&0xf8)==0xf8)        //若负温度,从补码转换(取反加一)
   {
     Flag=1;              //负数标志
     u16tmp=~u16tmp;
     u16tmp++;
   }
   else Flag=0;        // 正 符号为0
   u16tmp&=0x07ff;     // 确保前5位为0
   
   //乘0.0625操作,为此本函数只适用于DS18B20 12位转换(默认)时
    u16tmp=((uint32)u16tmp)*625/100;  //乘6.25,即放大100倍,用于保留两位小数            
   
   
// if(Flag)
// temp|=0x80;          //变负数
   return u16tmp;
}
//-----------------------------------------------------------------------
void Init_Port(void)
{
   DDRD |=(1<<DDD3);
}
//USART发送数据--------------------------------------------------------------
void USART_Send(uint08 data)
{ while(!(UCSR0A&(1<<UDRE0)));   //等待发送缓冲器为空
   UDR0=data;                     //将数据放入缓冲器,发送数据
}
//串口发送字符串============================================================
//返回值
void SCI_Send_Str(uint08 *str)
{
   uint08 *p;
   p=str;
   while(*p) USART_Send(*(p++));   //发送一个字符  
}
//------------------------------------------------
void setup()
{
   Init_Port();
   Serial.begin(9600);
}
uint16 u16temp=0;
uint08 i;
void loop()
{
    delay(300);
    if(Ds18b20_Convert()==RIGHT)
      {
       u16temp=Get_Temperature();
      // Serial.println(u16temp);
     if(Flag)
     {
      Show_Buff[0]='-';      //负号
     }
     else
     {
      Show_Buff[0]=' ';      //空格
     }   
     
      //定点小数显示格式  
      Show_Buff[1]=(u16temp/1000)%10+'0';
      Show_Buff[2]=(u16temp/100)%10+'0';
      Show_Buff[3]='.';      // 小数点
      Show_Buff[4]=(u16temp/10)%10+'0';
      Show_Buff[5]=u16temp%10+'0';
      Show_Buff[6]=0;       //字符串结束标志
      SCI_Send_Str(Show_Buff);
      SCI_Send_Str("\n");
   
     }
}[/mw_shl_code]
2017-10-27_111422.png
 楼主| 发表于 2017-10-27 11:27 | 显示全部楼层
啃罗布代码上传不了,弹出的窗口没有用
 楼主| 发表于 2017-11-1 13:52 | 显示全部楼层
好了,用win10修改了一下
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-28 07:47 , Processed in 0.199536 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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