DS18B20数字传感器学习笔记

DS18B20是一种半双工单总线通信方式,它共有6中信号:复位脉冲,应答脉冲,写0,写1,读0和读1。所有这些信号,除了应答脉冲以外,都是由主机发出同步信号,并且发送所有的命令和数据都是字节的低位在前。

复位脉冲

单总线上的所有通信都是以初始化序列开始。主机输出低电平,保持低电平时间至少480us,以产生复位脉冲,接着主机释放总线,4.7K的上拉电阻将总线拉高,延时15~16us,并进入接收模式。

//复位DS18B20

void DS18B20_Rst(void)

{                 

    DS18B20_IO_OUT(); //设置为输出模式

    DS18B20_DQ_OUT=0; //拉低DQ

    delay_us(750);    //拉低750us(至少480us)

    DS18B20_DQ_OUT=1; //DQ=1拉高释放总线

    delay_us(15);     //15US
  
}

此时进入接收模式,等待应答信号。

应答信号

将DS18B20总线拉低60~240us,产生低电平应答脉冲。

等待DS18B20的回应

//返回1:未检测到DS18B20的存在

//返回0:存在

u8 DS18B20_Check(void)

{   
    u8 retry=0;
    DS18B20_IO_IN();//SET PA0INPUT
    while(DS18B20_DQ_IN&&retry<200)// DS18B20_DQ_IN的作用为读引脚,观察其是否为低电平
    {
        retry++;//如果为高电平,则retry++
        delay_us(1);
    }
    if(retry>=200)//未检测到18B20
    {
      return 1;
    }
    else
    {
        retry=0;
    }
    while(!DS18B20_DQ_IN&&retry<240)
    {
        retry++;//低电平时retry++
        delay_us(1);
    }
    if(retry>=240)return1;//由于拉低总线的时间在60~240us,大于240则没检测到18B20    
    return 0;
}

写时序

写时序包括写0时序和写1时序。所有写时序至少需要60us,且在两次独立的写时序之间需要1us的恢复时间,两种写时序均起始于主机拉低总线。

写1时序:主机输出低电平,延时2us,然后释放总线,延时60us。

写0时序:主机输出低电平,延时60us,然后释放总线,延时2us。


//写一个字节到DS18B20
//dat:要写入的字节
void DS18B20_Write_Byte(u8 dat)     
{             
    u8 j;
    u8 testb;
    DS18B20_IO_OUT();//设置IO口为输出
    for (j=1;j<=8;j++) //八位数据,一位一位写
    {
        testb=dat&0x01;//取第一位数据
        dat=dat>>1;//移位
        if (testb) //输出高
        {
            DS18B20_DQ_OUT=0;//主机输出低电平
            delay_us(2);//延时2us                            
            DS18B20_DQ_OUT=1;
            delay_us(60);     //延时60us
        }
        else//输出低
        {
            DS18B20_DQ_OUT=0;//主机输出低电平
            delay_us(60);             
            DS18B20_DQ_OUT=1;//释放总线
            delay_us(2);                          
        }     
    }
}

读时序

单总线器件仅在主机发出读时序时,才向主机传输数据,所以,在主机发出读数据命令后,必须马上产生读时序,以便从机能传输数据。

所有读时序至少需要60us,且在2次独立的读时序之间至少需要1us的恢复时间。每个读时序都由主机发起,至少拉低总线1us。主机在读时序期间必须释放总线,并且在时序起始后的15us之内采样总线状态。

典型的读时序过程为:主机输出低电平延时2us,然后主机转入输入模式延时12us,然后读取单总线当前的电平,然后延时50us。

//从DS18B20读取一个位
//返回值:1/0
u8 DS18B20_Read_Bit(void)
{
    u8 data;
    DS18B20_IO_OUT();//设置IO口为输出
    DS18B20_DQ_OUT=0; //输出低电平2us
    delay_us(2);
    DS18B20_DQ_OUT=1; //拉高释放总线
    DS18B20_IO_IN();//设置IO口为输入
    delay_us(12);//延时12us
    if(DS18B20_DQ_IN)data=1;//读取总线数据(当前电平)
    else data=0;
    delay_us(50);//延时50us           
    return data;

}

 

//从DS18B20读取一个字节
//返回值:读到的数据
u8 DS18B20_Read_Byte(void)   
{        
    u8 i,j,dat=0;
    for (i=1;i<=8;i++)
    {
        j=DS18B20_Read_Bit();
        dat=(j<<7)|(dat>>1);
    }
    return dat;
}

DS18B20是如何读取

现在我们来看看DS18B20是怎么读取温度的,DS18B20的典型温度读取过程为:复位->发SKIP ROM命令(0XCC)->发开始转换命令(0X44)->延时->复位->发送SKIP ROM命令(0XCC)->发读存储器命令(0XBE)->连续读出两个字节数据(即温度)->结束。


//从ds18b20得到温度值
//精度:0.1C
//返回值:温度值(-550~1250)
short
DS18B20_Get_Temp(void)
{
   u8 temp;
   u8 TL,TH;
   short tem;
   DS18B20_Start ();                    // ds1820 start convert
   DS18B20_Rst();//复位
   DS18B20_Check();
   DS18B20_Write_Byte(0xcc);// skip rom
   DS18B20_Write_Byte(0xbe);//convert
   TL=DS18B20_Read_Byte();// LSB   
   TH=DS18B20_Read_Byte();// MSB  
   if(TH>7)//(TH>xxxxx111)温度为负
   {
       TH=~TH;TL=~TL;
       temp=0; 
   }
   else  temp=1;//温度为正
   tem=TH;//获得高八位
   tem<<=8;    
   tem+=TL;//获得底八位
   tem=(float)tem*0.625;//转换
   if(temp) return tem; //返回温度值
   else  return -tem;    
}

其中

void
DS18B20_Start(void)// ds1820 start convert

{     
    DS18B20_Rst();
    DS18B20_Check();
    DS18B20_Write_Byte(0xcc);// skip rom
    DS18B20_Write_Byte(0x44);// convert
}

紧接着我们来讲后面有关温度计算的问题,首先,我们用DS18B20_Read_Byte()函数读取两个字节的温度,先低后高。

DS18B20 能够提供两个字节的温度数据,共16位数。但是因为18B20是单总线的,数据都是一位一位传输的。每次读出的操作,DS18B20 仅仅送出8位数。必须读出两次,才能完整的读出16位数。两次读出时,DS18B20 先输出的是低八位,后输出的是高八位。这是器件本身的特性。

1.jpg

转化后得到的12位数据,存储在18B20的两个8比特的RAM中,二进制中的前面5位是符号位,如果测得的温度大于0,这5位为0,只要将测得的数值乘以0.0625即可得到实际温度;如果温度小于0,这五位为1,检测到的数值需要取反加1再乘以0.0625即可得到实际温度。(源码中0.625是因为要保证精度,在主函数中温度有除以10,所以相当于0.0625)

2.jpg

由上图可以看出前五位为符号位。

主函数中初始化DS18B20的函数如下:

//初始化DS18B20的IO口DQ 同时检测DS的存在
//返回1:不存在
//返回0:存在
u8 DS18B20_Init(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能PORTA时钟

    GPIO_InitStructure.GPIO_Pin= GPIO_Pin_0;//PORTA0 推挽输出
    GPIO_InitStructure.GPIO_Mode= GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStructure);
    GPIO_SetBits(GPIOA,GPIO_Pin_0);    //输出1

    DS18B20_Rst();
    return DS18B20_Check();//未检测到DS18B20则返回1
}

既然学到了这里,想必大家对这个都十分熟悉,这里我就不再多说。

以上,DS18B20读取温度的方式就讲完了。学会使用这些函数,就可以在主函数中调用他们来读取外界温度。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容