基于 LabVIEW 和 51 单片机的温度检测系统

温度检测系统,包含 51 单片机下位机(温度采集)、LabVIEW 上位机(数据显示与处理)、硬件连接和代码实现。

一、系统架构

复制代码
┌─────────────────────────────────────────────────────────────┐
│                    温度检测系统架构                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   DS18B20温度传感器  →  51单片机  →  USB/TTL  →  PC/LabVIEW  │
│                                                             │
│   温度采集模块          数据处理模块       通信模块           │
│                                                             │
└─────────────────────────────────────────────────────────────┘

二、硬件设计

1. 硬件清单

元件 型号 数量 备注
单片机 AT89C51/AT89S51 1 51 系列单片机
温度传感器 DS18B20 1 数字温度传感器
晶振 11.0592MHz 1 用于串口通信
电容 30pF 2 晶振匹配电容
电阻 4.7kΩ 1 DS18B20 上拉电阻
电阻 10kΩ 1 复位电路
电解电容 10μF 1 电源滤波
USB-TTL模块 CH340/PL2303 1 串口通信
面包板/PCB - 1 电路搭建

2. 硬件连接图

复制代码
                    ┌─────────────┐
                    │   DS18B20   │
                    │             │
                    │  GND ───────┼── GND
                    │  DQ  ───────┼── P3.7 (单总线)
                    │  VDD ───────┼── +5V
                    │             │
                    └─────────────┘
                          │
                       4.7kΩ
                          │
                        +5V
                        
                    ┌─────────────┐
                    │  AT89C51    │
                    │             │
                    │  P3.0(RXD) ─┼───→ USB-TTL TX
                    │  P3.1(TXD) ─┼───→ USB-TTL RX
                    │  P3.7      ─┼───→ DS18B20 DQ
                    │  RST       ─┼───→ 复位电路
                    │  XTAL1     ─┼───→ 晶振 11.0592MHz
                    │  XTAL2     ─┼───→ 晶振 11.0592MHz
                    │  GND       ─┼───→ GND
                    │  VCC       ─┼───→ +5V
                    │             │
                    └─────────────┘
                         │
                    ┌────┴────┐
                    │ USB-TTL │
                    │ 模块    │
                    └────┬────┘
                         │
                    ┌────┴────┐
                    │   PC    │
                    │ LabVIEW │
                    └─────────┘

三、51 单片机程序设计

1. 主程序 (main.c)

c 复制代码
/**
  ******************************************************************************
  * @file    main.c
  * @author  Embedded Developer
  * @version V1.0
  * @date    2024-01-01
  * @brief   51单片机温度检测主程序
  ******************************************************************************
  */

#include "reg52.h"
#include "ds18b20.h"
#include "uart.h"
#include "delay.h"

// 全局变量
float temperature = 0.0f;
unsigned char temp_int = 0;
unsigned char temp_dec = 0;

// 函数声明
void System_Init(void);
void Timer0_Init(void);
void Send_Temperature_To_PC(float temp);

void main(void)
{
    // 系统初始化
    System_Init();
    UART_Init();
    DS18B20_Init();
    Timer0_Init();
    
    EA = 1;  // 开启总中断
    
    // 发送启动信息
    UART_SendString("51单片机温度检测系统启动...\r\n");
    Delay_ms(100);
    
    while(1)
    {
        // 读取温度
        temperature = DS18B20_GetTemp();
        
        // 分离整数和小数部分
        temp_int = (unsigned char)temperature;
        temp_dec = (unsigned char)((temperature - temp_int) * 100);
        
        // 发送温度数据到PC
        Send_Temperature_To_PC(temperature);
        
        // 延时1秒
        Delay_ms(1000);
    }
}

/**
  * @brief  系统初始化
  * @param  None
  * @retval None
  */
void System_Init(void)
{
    // 端口初始化
    P3 = 0xFF;  // P3口作为输入
    P1 = 0x00;  // P1口作为输出
    P2 = 0x00;  // P2口作为输出
    
    // 关闭看门狗(如果使用STC单片机)
    // WDT_CONTR = 0x00;
}

/**
  * @brief  定时器0初始化(用于延时)
  * @param  None
  * @retval None
  */
void Timer0_Init(void)
{
    TMOD &= 0xF0;  // 清除T0控制位
    TMOD |= 0x01;  // 设置T0为模式1(16位定时器)
    TH0 = 0xFC;    // 装载初值(1ms@11.0592MHz)
    TL0 = 0x66;
    ET0 = 1;       // 允许T0中断
    TR0 = 1;       // 启动T0
}

/**
  * @brief  发送温度数据到PC
  * @param  temp: 温度值
  * @retval None
  */
void Send_Temperature_To_PC(float temp)
{
    unsigned char buffer[20];
    unsigned char i = 0;
    
    // 格式化温度数据
    buffer[i++] = 'T';
    buffer[i++] = ':';
    buffer[i++] = temp_int / 100 + '0';
    buffer[i++] = temp_int / 10 % 10 + '0';
    buffer[i++] = temp_int % 10 + '0';
    buffer[i++] = '.';
    buffer[i++] = temp_dec / 10 + '0';
    buffer[i++] = temp_dec % 10 + '0';
    buffer[i++] = 'C';
    buffer[i++] = '\r';
    buffer[i++] = '\n';
    
    // 发送数据
    for(unsigned char j = 0; j < i; j++)
    {
        UART_SendByte(buffer[j]);
    }
}

/**
  * @brief  定时器0中断服务函数
  * @param  None
  * @retval None
  */
void Timer0_ISR(void) interrupt 1
{
    TH0 = 0xFC;  // 重装初值
    TL0 = 0x66;
    
    // 在这里可以添加定时任务
}

2. DS18B20 驱动 (ds18b20.c)

c 复制代码
/**
  ******************************************************************************
  * @file    ds18b20.c
  * @author  Embedded Developer
  * @version V1.0
  * @date    2024-01-01
  * @brief   DS18B20温度传感器驱动
  ******************************************************************************
  */

#include "ds18b20.h"
#include "delay.h"

// DS18B20引脚定义
sbit DQ = P3^7;  // 单总线引脚

/**
  * @brief  DS18B20延时函数(微秒级)
  * @param  us: 延时微秒数
  * @retval None
  */
void DS18B20_DelayUs(unsigned int us)
{
    while(us--)
    {
        _nop_();
        _nop_();
        _nop_();
        _nop_();
    }
}

/**
  * @brief  DS18B20初始化
  * @param  None
  * @retval 0=成功, 1=失败
  */
unsigned char DS18B20_Init(void)
{
    unsigned char retry = 0;
    
    DQ = 1;
    DS18B20_DelayUs(1);
    DQ = 0;
    DS18B20_DelayUs(480);  // 480us复位脉冲
    DQ = 1;
    DS18B20_DelayUs(60);   // 等待60us
    
    // 检测存在脉冲
    while(DQ && retry < 240)
    {
        retry++;
        DS18B20_DelayUs(1);
    }
    
    if(retry >= 240)
        return 1;  // 初始化失败
    
    DS18B20_DelayUs(420);  // 等待420us
    return 0;  // 初始化成功
}

/**
  * @brief  向DS18B20写入一个字节
  * @param  dat: 要写入的数据
  * @retval None
  */
void DS18B20_WriteByte(unsigned char dat)
{
    unsigned char i;
    
    for(i = 0; i < 8; i++)
    {
        DQ = 0;
        DS18B20_DelayUs(2);  // 2us
        DQ = dat & 0x01;     // 发送最低位
        DS18B20_DelayUs(60); // 60us
        DQ = 1;
        dat >>= 1;
        DS18B20_DelayUs(2);  // 2us恢复时间
    }
}

/**
  * @brief  从DS18B20读取一个字节
  * @param  None
  * @retval 读取的字节
  */
unsigned char DS18B20_ReadByte(void)
{
    unsigned char i, dat = 0;
    
    for(i = 0; i < 8; i++)
    {
        DQ = 0;
        DS18B20_DelayUs(2);  // 2us
        DQ = 1;
        DS18B20_DelayUs(2);  // 2us
        dat >>= 1;
        if(DQ)
            dat |= 0x80;
        DS18B20_DelayUs(60); // 60us
    }
    
    return dat;
}

/**
  * @brief  启动温度转换
  * @param  None
  * @retval None
  */
void DS18B20_StartConvert(void)
{
    DS18B20_Init();
    DS18B20_WriteByte(0xCC);  // 跳过ROM
    DS18B20_WriteByte(0x44);  // 启动温度转换
}

/**
  * @brief  读取温度值
  * @param  None
  * @retval 温度值(摄氏度)
  */
float DS18B20_GetTemp(void)
{
    unsigned char temp_l, temp_h;
    int temp;
    float temperature;
    
    DS18B20_StartConvert();
    Delay_ms(750);  // 等待转换完成(12位精度需要750ms)
    
    DS18B20_Init();
    DS18B20_WriteByte(0xCC);  // 跳过ROM
    DS18B20_WriteByte(0xBE);  // 读取暂存器
    
    temp_l = DS18B20_ReadByte();  // 温度低字节
    temp_h = DS18B20_ReadByte();  // 温度高字节
    
    temp = (temp_h << 8) | temp_l;
    
    if(temp < 0)  // 负温度
    {
        temperature = -((~temp + 1) * 0.0625f);
    }
    else  // 正温度
    {
        temperature = temp * 0.0625f;
    }
    
    return temperature;
}

3. DS18B20 头文件 (ds18b20.h)

c 复制代码
/**
  ******************************************************************************
  * @file    ds18b20.h
  * @author  Embedded Developer
  * @version V1.0
  * @date    2024-01-01
  * @brief   DS18B20温度传感器头文件
  ******************************************************************************
  */

#ifndef __DS18B20_H
#define __DS18B20_H

#include "reg52.h"
#include "delay.h"

// 函数声明
unsigned char DS18B20_Init(void);
void DS18B20_WriteByte(unsigned char dat);
unsigned char DS18B20_ReadByte(void);
void DS18B20_StartConvert(void);
float DS18B20_GetTemp(void);

#endif /* __DS18B20_H */

4. 串口通信驱动 (uart.c)

c 复制代码
/**
  ******************************************************************************
  * @file    uart.c
  * @author  Embedded Developer
  * @version V1.0
  * @date    2024-01-01
  * @brief   串口通信驱动
  ******************************************************************************
  */

#include "uart.h"

/**
  * @brief  串口初始化
  * @param  None
  * @retval None
  */
void UART_Init(void)
{
    TMOD |= 0x20;  // 设置T1为模式2(8位自动重装)
    TH1 = 0xFD;    // 波特率9600@11.0592MHz
    TL1 = 0xFD;
    TR1 = 1;      // 启动T1
    SM0 = 0;      // 设置串口为模式1
    SM1 = 1;
    REN = 1;      // 允许接收
    EA = 1;       // 开启总中断
    ES = 1;       // 开启串口中断
}

/**
  * @brief  发送一个字节
  * @param  dat: 要发送的字节
  * @retval None
  */
void UART_SendByte(unsigned char dat)
{
    SBUF = dat;
    while(!TI);   // 等待发送完成
    TI = 0;       // 清除发送中断标志
}

/**
  * @brief  发送字符串
  * @param  str: 要发送的字符串
  * @retval None
  */
void UART_SendString(char *str)
{
    while(*str)
    {
        UART_SendByte(*str++);
    }
}

/**
  * @brief  串口中断服务函数
  * @param  None
  * @retval None
  */
void UART_ISR(void) interrupt 4
{
    unsigned char receive_data;
    
    if(RI)  // 接收中断
    {
        RI = 0;  // 清除接收中断标志
        receive_data = SBUF;  // 读取接收到的数据
        
        // 回显接收到的数据
        UART_SendByte(receive_data);
    }
}

5. 延时函数 (delay.c)

c 复制代码
/**
  ******************************************************************************
  * @file    delay.c
  * @author  Embedded Developer
  * @version V1.0
  * @date    2024-01-01
  * @brief   延时函数
  ******************************************************************************
  */

#include "delay.h"

/**
  * @brief  毫秒延时
  * @param  ms: 延时毫秒数
  * @retval None
  */
void Delay_ms(unsigned int ms)
{
    unsigned int i, j;
    for(i = ms; i > 0; i--)
        for(j = 110; j > 0; j--);
}

/**
  * @brief  微秒延时
  * @param  us: 延时微秒数
  * @retval None
  */
void Delay_us(unsigned int us)
{
    while(us--)
    {
        _nop_();
        _nop_();
        _nop_();
        _nop_();
    }
}

四、LabVIEW 上位机设计

1. 前面板设计

复制代码
┌─────────────────────────────────────────────────────────────┐
│                   温度检测系统 - 前面板                     │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌─────────────────────┐  ┌─────────────────────────────┐  │
│  │    系统控制面板      │  │      温度显示面板            │  │
│  ├─────────────────────┤  ├─────────────────────────────┤  │
│  │ 串口选择: [COM3 ▼]  │  │  当前温度: 25.50 °C         │  │
│  │ 波特率: [9600 ▼]    │  │  最高温度: 30.20 °C         │  │
│  │ 数据位: [8 ▼]       │  │  最低温度: 22.10 °C         │  │
│  │ 停止位: [1 ▼]       │  │  平均温度: 26.80 °C         │  │
│  │ 校验位: [无 ▼]      │  │                             │  │
│  │                     │  │  ┌─────────────────────┐    │  │
│  │ [连接串口] [断开]   │  │  │    温度趋势图         │    │  │
│  │                     │  │  │                        │    │  │
│  │ [开始采集] [停止]   │  │  │   ↑                  │    │  │
│  │                     │  │  │   │                  │    │  │
│  │ 报警设置:           │  │  │   │                  │    │  │
│  │ 上限: [30.0] °C     │  │  │   └─────────────────┘    │  │
│  │ 下限: [20.0] °C     │  │  │                        │    │  │
│  │ [启用报警]          │  │  └─────────────────────────────┘  │
│  └─────────────────────┘  │                             │
│                             │  ┌─────────────────────────────┐  │
│                             │  │      数据记录面板            │  │
│                             │  ├─────────────────────────────┤  │
│                             │  │ [保存数据] [清空记录]        │  │
│                             │  │                             │  │
│                             │  │ 采集时间: 2024-01-01 10:30  │  │
│                             │  │ 采集点数: 1000              │  │
│                             │  │ 文件路径: C:\temp_data.txt  │  │
│                             │  └─────────────────────────────┘  │
│                                                             │
└─────────────────────────────────────────────────────────────┘

2. 程序框图设计

复制代码
┌─────────────────────────────────────────────────────────────┐
│                   温度检测系统 - 程序框图                    │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌─────────────┐    ┌─────────────┐    ┌─────────────┐    │
│  │  串口配置   │───▶│  串口读取   │───▶│  数据解析   │    │
│  └─────────────┘    └─────────────┘    └─────────────┘    │
│         │                  │                  │          │
│         ▼                  ▼                  ▼          │
│  ┌─────────────┐    ┌─────────────┐    ┌─────────────┐    │
│  │  温度显示   │◀───│  数据处理   │◀───│  报警判断   │    │
│  └─────────────┘    └─────────────┘    └─────────────┘    │
│         │                  │                  │          │
│         ▼                  ▼                  ▼          │
│  ┌─────────────┐    ┌─────────────┐    ┌─────────────┐    │
│  │  曲线绘制   │    │  数据存储   │    │  报警输出   │    │
│  └─────────────┘    └─────────────┘    └─────────────┘    │
│                                                             │
└─────────────────────────────────────────────────────────────┘

3. LabVIEW 核心代码(G语言描述)

3.1 串口初始化子VI
复制代码
┌─────────────────────────────────────┐
│        串口初始化子VI               │
├─────────────────────────────────────┤
│                                     │
│  [VISA Configure Serial Port]       │
│         │                           │
│         ▼                           │
│  [VISA Open]                        │
│         │                           │
│         ▼                           │
│  [VISA Set Timeout]                 │
│         │                           │
│         ▼                           │
│  [输出: VISA资源名]                 │
│                                     │
└─────────────────────────────────────┘

参数设置:

  • 波特率:9600
  • 数据位:8
  • 停止位:1
  • 校验位:None
  • 超时:1000ms
3.2 数据读取与解析子VI
复制代码
┌─────────────────────────────────────┐
│      数据读取与解析子VI             │
├─────────────────────────────────────┤
│                                     │
│  [VISA Read] ──▶ [字符串搜索] ──▶   │
│         │             │             │
│         ▼             ▼             │
│  [截取字符串] ──▶ [十进制数字转换]   │
│         │             │             │
│         ▼             ▼             │
│  [输出: 温度值(°C)] ◀─┘             │
│                                     │
└─────────────────────────────────────┘

数据格式解析:

复制代码
输入字符串: "T:25.50C\r\n"
解析步骤:
1. 搜索 "T:" 位置
2. 截取 ":" 之后的数字部分
3. 转换为浮点数 25.50
3.3 温度显示与报警子VI
复制代码
┌─────────────────────────────────────┐
│    温度显示与报警子VI               │
├─────────────────────────────────────┤
│                                     │
│  温度值 ──▶ [数值显示]              │
│     │       │                       │
│     ├──▶ [温度计显示]               │
│     │       │                       │
│     ├──▶ [柱状图显示]               │
│     │       │                       │
│     └──▶ [报警判断] ──▶ [指示灯]    │
│             │                       │
│             ├── 温度 > 上限 → 红灯  │
│             ├── 温度 < 下限 → 蓝灯  │
│             └── 正常范围 → 绿灯     │
│                                     │
└─────────────────────────────────────┘

4. 完整 LabVIEW 程序代码(文本描述)

由于无法直接提供 .vi 文件,以下是详细的实现步骤:

4.1 创建新VI
  1. 打开 LabVIEW
  2. 新建 VI (File → New VI)
  3. 保存为 Temperature_Monitor.vi
4.2 前面板设计步骤
  1. 添加串口控件

    • Controls Palette → Modern → I/O → VISA Resource Name
    • 放置到前面板,命名为 "串口选择"
  2. 添加数值显示控件

    • Controls Palette → Modern → Numeric → Gauge
    • 放置到前面板,命名为 "当前温度"
  3. 添加波形图表

    • Controls Palette → Modern → Graph → Waveform Chart
    • 放置到前面板,命名为 "温度趋势图"
  4. 添加按钮控件

    • Controls Palette → Modern → Boolean → OK Button
    • 添加 "连接串口"、"开始采集"、"停止采集" 按钮
4.3 程序框图实现步骤

主循环结构:

复制代码
While Loop
  │
  ├── Case Structure (串口连接)
  │     ├── True: VISA Configure Serial Port
  │     └── False: VISA Close
  │
  ├── Case Structure (数据采集)
  │     ├── True: VISA Read → 数据解析 → 显示更新
  │     └── False: 停止采集
  │
  ├── 定时结构 (Wait ms)
  │
  └── 停止条件

数据解析代码:

复制代码
VISA Read (Bytes at Port)
  │
  ├── 字符串 → 字节数组
  │
  ├── 搜索 "T:" 位置
  │
  ├── 截取温度字符串
  │
  └── 字符串 → 数值转换

参考代码 基于LabVIEW和51单片机的温度检测 www.youwenfan.com/contentcsv/112928.html

五、系统测试与调试

1. 硬件测试

步骤1:检查电源

复制代码
用万用表测量:
- VCC 对 GND: 5.0V ± 0.1V
- DS18B20 VDD 对 GND: 5.0V

步骤2:检查DS18B20

复制代码
用示波器观察 P3.7 引脚:
- 初始化时有复位脉冲
- 有数据波形输出

步骤3:检查串口

复制代码
用串口调试助手测试:
- 发送 "AT" 应收到响应
- 波特率设置为 9600

2. 软件测试

51单片机测试程序:

c 复制代码
// 测试程序:发送固定温度值
void Test_UART(void)
{
    UART_SendString("T:25.50C\r\n");
    Delay_ms(1000);
}

LabVIEW测试:

  1. 打开串口调试助手
  2. 设置波特率 9600
  3. 应收到 "T:25.50C\r\n" 数据

3. 常见问题解决

问题 原因 解决方法
无法读取温度 DS18B20接触不良 检查接线,更换传感器
温度读数错误 上拉电阻缺失 添加4.7kΩ上拉电阻
串口通信失败 波特率不匹配 确认11.0592MHz晶振
LabVIEW无数据 VISA驱动未安装 安装NI-VISA驱动
温度波动大 电源干扰 添加电源滤波电容

六、系统扩展功能

1. 多路温度检测

c 复制代码
// 多路DS18B20检测
float temperatures[8];
for(i = 0; i < 8; i++)
{
    DS18B20_SelectSensor(rom_codes[i]);
    temperatures[i] = DS18B20_GetTemp();
}

2. 温度报警功能

c 复制代码
// 温度报警
if(temperature > ALARM_HIGH)
{
    P1_0 = 0;  // 红灯亮
    UART_SendString("ALARM: High Temperature!\r\n");
}
else if(temperature < ALARM_LOW)
{
    P1_1 = 0;  // 蓝灯亮
    UART_SendString("ALARM: Low Temperature!\r\n");
}

3. 数据存储功能

c 复制代码
// 存储到EEPROM
void Save_Temperature_To_EEPROM(float temp)
{
    unsigned int addr = 0x0000;
    EEPROM_Write(addr, (unsigned char*)&temp, sizeof(float));
}

4. 无线传输扩展

c 复制代码
// 通过WiFi模块发送
void Send_To_Cloud(float temp)
{
    ESP8266_SendData("temperature", temp);
}

七、完整项目文件结构

复制代码
Temperature_Monitor/
├── Firmware/
│   ├── main.c
│   ├── ds18b20.c
│   ├── ds18b20.h
│   ├── uart.c
│   ├── uart.h
│   ├── delay.c
│   ├── delay.h
│   └── Temperature_Monitor.hex
├── LabVIEW/
│   ├── Temperature_Monitor.vi
│   ├── SubVIs/
│   │   ├── Serial_Init.vi
│   │   ├── Data_Parse.vi
│   │   ├── Temperature_Display.vi
│   │   └── Alarm_Check.vi
│   └── Config/
│       └── Serial_Config.ini
├── Hardware/
│   ├── Schematic.pdf
│   ├── PCB/
│   │   ├── TopLayer.brd
│   │   └── BottomLayer.brd
│   └── BOM.xlsx
├── Documentation/
│   ├── User_Manual.pdf
│   ├── Technical_Specification.pdf
│   └── Test_Report.pdf
└── README.md

这个系统实现了完整的温度检测功能,具有实时显示、数据存储、报警提示等特点。51单片机负责温度采集,LabVIEW负责数据显示和分析,两者通过串口通信。系统稳定可靠,易于扩展和维护。

相关推荐
三佛科技-187366133972 小时前
GD32F103RCT6兆易创新LQFP64,32 位 ARM Cortex-M3 微控制器芯片解析
单片机·嵌入式硬件
亿道电子Emdoor2 小时前
【Altium】封装焊盘批量命名
单片机·嵌入式硬件
清风6666662 小时前
基于单片机与12864显示屏的多种函数波形信号发生器设计
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
瓢儿菜20182 小时前
51 单片机-LED 点灯程序
单片机·嵌入式硬件
wangduqiang7472 小时前
stm32写sd卡
stm32·单片机·嵌入式硬件
wangduqiang7472 小时前
stm32休眠和唤醒,和内部flash
stm32·单片机·嵌入式硬件
点灯小铭3 小时前
基于51单片机的LED点阵汉字显示系统设计
数据库·单片机·嵌入式硬件·毕业设计·51单片机·课程设计·期末大作业
橡木树的叶子3 小时前
STM32单片机+RGB三色灯模块+七色灯颜色数据发送到串口调试助手+源代码(使用cubuemx+vscode实现操作)
stm32·单片机·计算机外设
踏着七彩祥云的小丑3 小时前
嵌入式测试学习第 30 天:功耗测试、待机电流、工作电流测试
单片机·嵌入式硬件·学习