单片机实现温度传感器的读取

蓝色幻想 2019-12-17 ⋅ 23 阅读

引言

温度传感器是一种常见的传感器,用于测量周围环境温度。在单片机应用中,我们可以通过连接温度传感器到单片机,实现温度的精确测量。本博客将介绍如何使用单片机读取温度传感器的数值,并给出一个示例实现。

温度传感器简介

温度传感器是一种能够转换温度为电信号的传感器。常见的温度传感器有热敏电阻、热电偶和数字温度传感器等。本文将以DS18B20数字温度传感器为例进行讲解。

DS18B20是一款基于1-Wire总线协议的数字温度传感器,具有精确度高、响应时间快、抗干扰能力强等特点。该传感器能够输出数字信号,直接连接到单片机的IO口进行读取。

硬件连接

使用DS18B20传感器时,我们需要将其与单片机相连。连接步骤如下:

  1. 将DS18B20的VCC引脚连接到单片机的电源(一般为3.3V或5V)。
  2. 将DS18B20的GND引脚连接到单片机的地线。
  3. 将DS18B20的DQ引脚连接到单片机的IO口。

软件实现

在单片机上使用DS18B20传感器的第一步是搜索和初始化传感器。DS18B20使用1-Wire协议进行通信,通过发送一系列指令来和传感器进行交互。

以下是使用C语言实现的初始化函数代码:

#include <reg52.h>
#include <stdio.h>
#include <intrins.h>

sbit DQ = P1^5;  // DQ引脚连接到P1.5

void delay_us(unsigned char us)
{
    while (us--)
    {
        _nop_();
        _nop_();
        _nop_();
        _nop_();
    }
}

bit init_ds18b20()
{
    bit ack;
    DQ = 1;  // 总线拉高
    delay_us(2);
    DQ = 0;  // 总线拉低
    delay_us(80);
    DQ = 1;  // 总线拉高
    delay_us(5);
    ack = DQ;  // 读取总线
    delay_us(50);
    return ack;
}

接下来是搜索DS18B20传感器的函数:

unsigned char search_ds18b20()
{
    unsigned char i, j;
    unsigned char id[8];
    unsigned char count = 0;

    for (i = 0; i < 8; i++)
    {
        id[i] = 0;
    }

    if (!init_ds18b20())  // 初始化总线
    {
        printf("No device detected.\n");
        return count;
    }

    for (i = 0; i < 64; i++)
    {
        DQ = 0;  // 总线拉低
        delay_us(6);
        DQ = 1;  // 总线拉高
        delay_us(8);
        id[i / 8] |= DQ << (i % 8);
        delay_us(50);
    }

    if ((id[0] == 0x28) && (id[1] == 0xFF))  // 判断是否为DS18B20传感器
    {
        count++;
    }

    printf("Device count: %d\n", count);

    return count;
}

最后,我们可以使用读取温度的函数来获取DS18B20传感器的数值:

float read_ds18b20()
{
    unsigned char i;
    unsigned char temp1, temp2;
    float temp;
    
    init_ds18b20();
    
    write_byte(0xCC);  // 跳过ROM操作
    write_byte(0x44);  // 温度转换命令
    delay_us(200);
    
    init_ds18b20();
    
    write_byte(0xCC);  // 跳过ROM操作
    write_byte(0xBE);  // 读取温度命令
    
    temp1 = read_byte();
    temp2 = read_byte();
    
    temp = (float)((temp2 << 8 | temp1) * 0.0625);
    
    return temp;
}

示例实现

以下是一个使用DS18B20传感器读取温度,并将温度值通过串口发送的例子:

#include <reg52.h>
#include <stdio.h>
#include <intrins.h>

sbit DQ = P1^5;  // DQ引脚连接到P1.5

void delay_us(unsigned char us)
{
    while (us--)
    {
        _nop_();
        _nop_();
        _nop_();
        _nop_();
    }
}

bit init_ds18b20()
{
    bit ack;
    DQ = 1;  // 总线拉高
    delay_us(2);
    DQ = 0;  // 总线拉低
    delay_us(80);
    DQ = 1;  // 总线拉高
    delay_us(5);
    ack = DQ;  // 读取总线
    delay_us(50);
    return ack;
}

unsigned char read_byte()
{
    unsigned char i;
    unsigned char byte = 0;

    for (i = 0; i < 8; i++)
    {
        DQ = 0;  // 总线拉低
        byte >>= 1;
        DQ = 1;  // 总线拉高
        if (DQ)
        {
            byte |= 0x80;
        }
        delay_us(6);
    }

    return byte;
}

void write_byte(unsigned char byte)
{
    unsigned char i;

    for (i = 0; i < 8; i++)
    {
        DQ = 0;  // 总线拉低
        DQ = byte & 0x01;  // 写入bit
        delay_us(6);
        DQ = 1;  // 总线拉高
        byte >>= 1;
    }
}

unsigned char search_ds18b20()
{
    unsigned char i, j;
    unsigned char id[8];
    unsigned char count = 0;

    for (i = 0; i < 8; i++)
    {
        id[i] = 0;
    }

    if (!init_ds18b20())  // 初始化总线
    {
        printf("No device detected.\n");
        return count;
    }

    for (i = 0; i < 64; i++)
    {
        DQ = 0;  // 总线拉低
        delay_us(6);
        DQ = 1;  // 总线拉高
        delay_us(8);
        id[i / 8] |= DQ << (i % 8);
        delay_us(50);
    }

    if ((id[0] == 0x28) && (id[1] == 0xFF))  // 判断是否为DS18B20传感器
    {
        count++;
    }

    printf("Device count: %d\n", count);

    return count;
}

float read_ds18b20()
{
    unsigned char i;
    unsigned char temp1, temp2;
    float temp;
    
    init_ds18b20();
    
    write_byte(0xCC);  // 跳过ROM操作
    write_byte(0x44);  // 温度转换命令
    delay_us(200);
    
    init_ds18b20();
    
    write_byte(0xCC);  // 跳过ROM操作
    write_byte(0xBE);  // 读取温度命令
    
    temp1 = read_byte();
    temp2 = read_byte();
    
    temp = (float)((temp2 << 8 | temp1) * 0.0625);
    
    return temp;
}

void main()
{
    unsigned char deviceCount;
    float temperature;
    
    deviceCount = search_ds18b20();
    if (deviceCount >= 1)
    {
        while (1)
        {
            temperature = read_ds18b20();
            printf("Temperature: %.2f\n", temperature);
        }
    }
}

总结

本博客介绍了如何使用单片机读取温度传感器的数值,以DS18B20数字温度传感器为例进行了说明。通过合理的硬件连接和软件处理,我们可以实现精确地测量环境温度的功能。希望本文对你理解和应用温度传感器有所帮助。


全部评论: 0

    我有话说: