蓝桥杯单片机外设驱动-3


单片机外设驱动-DS18B20温度传感器

DS18B20介绍

单总线数字温度传感器DS18B20几乎成了各类单片机甚至ARM实验板的标配模块。
不管是嵌入式的学习还是蓝桥杯的备赛,都应熟悉DS18B20的工作原理,掌握DS18B20的基本操作,也就是把传感器的温度数据正确读出来。
DS18B20单线通信功能是分时完成的,它有严格的时隙概念,如果出现序列混乱,器件将不响应主机。

DS18B20的协议

步骤1: 复位初始化
步骤2: ROM操作指令
步骤3: DS18B20功能指令

<1> CCH:跳过ROM指令,忽略64位ROM地址,直接向DS18B20发起各种温度转换指令。
<2> 44H:温度转换指令,启动DS18B20进行温度转换,转换时间最长为500ms(典型值为200ms),结果保存在高速RAM中。
<3> BEH:读暂存器指令,读取高速暂存存储器9个字节的内容。

读取DS18B20温度的基本操作

1. 主机对DS18B20进行复位初始化。

2. 主机向DS18B20写0xCC命令,跳过ROM。

3. 主机向DS18B20写0x44命令,开始进行温度转换。

4. 等待温度转换完成。

5. 主机对DS18B20进行复位初始化。

6. 主机向DS18B20写0xCC命令,跳过ROM。

7. 主机向DS18B20写0xBE命令,依次读取DS18B20发出的从第0一第8,共九个字节的数据。

DS18B20电路原理图

DS18B20

可以看出DS18b20的接线得却十分简单,但需要注意的是,当传感器与单片机相连时,要加一个4.7K的上拉电阻(5K左右即可)

DS18B20驱动

//DS18B20初始化
bit init_ds18b20(void)
{
    bit initflag = 0;

    DQ = 1;
    Delay_OneWire(12);
    DQ = 0;
    Delay_OneWire(80);  // 延时大于480us
    DQ = 1;
    Delay_OneWire(10);  // 14
    initflag = DQ;      // initflag等于1初始化失败
    Delay_OneWire(5);

    return initflag;
}

“读”操作

//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
    unsigned char i;
    unsigned char dat;

    for(i=0; i<8; i++)
    {
        DQ = 0;
        dat >>= 1;
        DQ = 1;
        if(DQ)
        {
            dat |= 0x80;
        }
        Delay_OneWire(5);
    }
    return dat;
}

“写”操作

//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
    unsigned char i;
    for(i=0; i<8; i++)
    {
        DQ = 0;
        DQ = dat&0x01;
        Delay_OneWire(5);
        DQ = 1;
        dat >>= 1;
    }
    Delay_OneWire(5);
}
//DS18B20温度采集程序:整数
unsigned char rd_temperature(void)
{
    unsigned char low,high;
    char temp;

    init_ds18b20();
    Write_DS18B20(0xCC);     //跳过ROM指令
    Write_DS18B20(0x44);     //启动温度转换
    Delay_OneWire(200);

    init_ds18b20();
    Write_DS18B20(0xCC);     //跳过ROM指令
    Write_DS18B20(0xBE);     //读取寄存器

    low = Read_DS18B20();    //低字节
    high = Read_DS18B20();   //高字节
    /** 精度为1摄氏度 */
    temp = high<<4;
    temp |= (low>>4);

    return temp;
}

//DS18B20温度采集程序:浮点数
float rd_temperature_f(void)
{
    unsigned int temp;
    float temperature;
    unsigned char low,high;

    init_ds18b20();
    Write_DS18B20(0xCC);     //跳过ROM指令
    Write_DS18B20(0x44);     //启动温度转换
    Delay_OneWire(200);

    init_ds18b20();
    Write_DS18B20(0xCC);     //跳过ROM指令
    Write_DS18B20(0xBE);     //读取寄存器

    low = Read_DS18B20();    //低字节
    high = Read_DS18B20();   //高字节
    /** 精度为0.0625摄氏度 */
    temp = (high&0x0f);
    temp <<= 8;
    temp |= low;
    temperature = temp*0.0625;

    return temperature;
}

举一个例子来说明这个处理的具体过程:
假设DS18B20的温度采样结果是:LSB = 0x96,MSB = 0x01。
温度数据变量T_dat为16位无符号int整型,初始值为0x0000。
执行T_dat = MSB;语句后, T_dat 的值为:0x0001。
执行T_dat <<= 8;语句后, T_dat 的值为:0x0100。
执行T_dat = T_dat | LSB;语句后, T_dat 的值为:0x0196。
通过高5位的符号扩展位判断,进行正温度的处理算法,正常来说,应该是:
T_dat = 0x0196 × 0.0625 = 406 × 0.0625 = 25.375 摄氏度。

实验效果

用手摸一会温度传感器数值就上去了 额…我是不是有点虚 ,,Ծ‸Ծ,,

实验效果


文章作者: Rb菌
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Rb菌 !
  目录