基于STC89C52的温度采集与监控系统设计与实现

一、项目概述

本项目基于 STC89C52 单片机,实现了一个温度采集与监控系统。上位机通过串口与单片机通信,可以实现以下功能:

  • 读取 DS18B20 采集的温度
  • 控制 LED 灯和蜂鸣器
  • 设置温度上下限阈值
  • 切换手动/自动工作模式
  • 自动模式下超限告警

这个项目适合 51 单片机入门进阶,涉及单总线通信、串口协议、定时器中断、数码管动态扫描等知识点。

二、硬件清单

器件 型号/参数 数量
单片机 STC89C52RC 1
温度传感器 DS18B20 1
数码管 4位共阴 1
LED 普通发光二极管 2
蜂鸣器 无源蜂鸣器 1
晶振 11.0592MHz 1
USB转TTL CH340 1
电阻 4.7kΩ(DS18B20上拉) 1

三、硬件连接

1. DS18B20

DS18B20 单片机
GND GND
DQ P3.7(并接4.7kΩ上拉到VCC)
VCC VCC

注意:DQ 必须接 4.7kΩ 上拉电阻,否则读不到数据。

2. 数码管(普中51-MS开发板)

数码管 单片机
位选 P1.0 ~ P1.3
段选 P0

3. LED 与蜂鸣器

外设 引脚 有效电平
LED1 P2.0 低电平亮
蜂鸣器 P2.1 方波驱动(无源)

4. 串口

单片机 USB转TTL
P3.1 (TXD) RXD
P3.0 (RXD) TXD
GND GND

波特率 2400,8 数据位,1 停止位,无校验。

四、通信协议设计

1. 上位机 → 单片机(7字节定长帧)

text 复制代码
AA 01 CMD P1 P2 SUM BB
字节 含义
AA 帧头
01 地址
CMD 命令码
P1 参数1
P2 参数2
SUM 校验和(前5字节之和)
BB 帧尾

命令码定义:

CMD 功能 P1 P2
0x01 读温度 - -
0x02 控制外设 设备号 状态
0x03 设阈值 上限 下限
0x04 设为自动 - -
0x05 设为手动 - -

设备号:

设备号 设备
0x01 LED
0x02 蜂鸣器

状态:0x00=关,0x01=开

2. 单片机 → 上位机(7字节应答帧)

text 复制代码
AA 01 CMD DATA_H DATA_L SUM BB

五、软件架构

工程共 3 个文件:

text 复制代码
项目/
├── ds18b20.c    (主文件,含 main 函数 + DS18B20 驱动 + 串口)
├── timer.c      (数码管扫描 + 蜂鸣器方波 + 1s 计时)
└── timer.h      (头文件,声明共用变量和函数)

模块划分:

模块 功能
串口收发 收 7 字节命令,回 7 字节应答
DS18B20 驱动 复位、读写字节、读温度
数码管 定时器中断动态扫描
蜂鸣器 定时器中断输出方波
命令解析 根据命令码执行对应动作
自动控制 1s 定时读温度,超限告警

六、关键代码解析

1. 串口接收中断

c 复制代码
void UartHandler(void) interrupt 4
{
    if (RI)
    {
        RI = 0;
        if (RecvLen < sizeof(RecvBuff))
        {
            RecvBuff[RecvLen] = SBUF;
            RecvLen++;
            if (7 == RecvLen)
            {
                IsCommandLine = 1;
            }
        }
        else
        {
            RecvLen = 0;
        }
    }
}

要点:

  • 用 RI 判断接收中断
  • 收满 7 字节置标志,主循环处理
  • 加越界保护

2. DS18B20 读温度

c 复制代码
int ReadTemp(void)
{
    unsigned char LSBVal = 0;
    unsigned char MSBVal = 0;
    int Val = 0;

    DQ = 1;
    Delay480us();
    Delay480us();

    EA = 0;              // ★ 关中断,保护时序
    DQReset();
    ReadDQRespone();
    SendByte(0xCC);
    SendByte(0x44);
    EA = 1;

    Delay800ms();

    EA = 0;
    DQReset();
    ReadDQRespone();
    SendByte(0xCC);
    SendByte(0xBE);
    LSBVal = RecvByte();
    MSBVal = RecvByte();
    EA = 1;

    Val = (MSBVal << 8) | LSBVal;
    Val >>= 4;           // 取整数摄氏度
    return Val;
}

要点:

  • 读写时关中断 EA = 0,防止定时器打断时序
  • 读回后右移 4 位,得到整数°C
  • 加超时防止死循环

3. 定时器中断(数码管 + 蜂鸣器 + 1s计时)

c 复制代码
void Timer0Handler(void) interrupt 1
{
    static unsigned char scan = 0;
    static unsigned char buzzCnt = 0;
    
    TH0 = 0xFF;
    TL0 = 0x48;          // 200us

    if (BuzzerOn)
        BEEP = ~BEEP;    // 蜂鸣器方波
    else
        BEEP = 0;

    buzzCnt++;
    if (buzzCnt >= 4)    // 800us 扫一位
    {
        buzzCnt = 0;
        DisplayNum(scan);
        scan++;
        if (4 == scan) scan = 0;
    }

    Timer1msCnt++;
    if (Timer1msCnt >= 5000)   // 1s
    {
        Timer1msCnt = 0;
        AutoFlag = 1;
    }
}

要点:

  • 200us 中断一次
  • 蜂鸣器每次中断翻转 → 2.5kHz 方波
  • 每 4 次中断扫一位数码管
  • 5000 次中断 = 1s

4. 命令解析

c 复制代码
if (RecvBuff[2] == 0x01)        // 读温度
{
    CurTemp = ReadTemp();
    SetDisplayNum(CurTemp);
    SendResponse(0x01, CurTemp);
}
else if (RecvBuff[2] == 0x02)   // 控制外设
{
    if (RecvBuff[3] == 0x01) SetLed(RecvBuff[4]);
    else if (RecvBuff[3] == 0x02) SetBuzzer(RecvBuff[4]);
    SendResponse(0x02, 0x0000);
}
else if (RecvBuff[2] == 0x03)   // 设阈值
{
    TempHighLimit = RecvBuff[3];
    TempLowLimit  = RecvBuff[4];
    SendResponse(0x03, 0x0000);
}
else if (RecvBuff[2] == 0x04)   // 自动模式
{
    WorkMode = 1;
    SendResponse(0x04, 0x0000);
}
else if (RecvBuff[2] == 0x05)   // 手动模式
{
    WorkMode = 0;
    SetLed(0);
    SetBuzzer(0);
    SendResponse(0x05, 0x0000);
}

5. 自动控制逻辑

c 复制代码
if (WorkMode == 1 && AutoFlag)
{
    AutoFlag = 0;

    CurTemp = ReadTemp();
    SetDisplayNum(CurTemp);

    if (CurTemp > TempHighLimit)          // 超上限
    {
        SetLed(1);
        SetBuzzer(0);
    }
    else if (CurTemp < TempLowLimit)      // 低于下限
    {
        SetLed(1);
        SetBuzzer(1);
    }
    else                                   // 范围内
    {
        SetLed(0);
        SetBuzzer(0);
    }
}

七、完整工作流程

flowchart TD A[上电] --> B[UartInit + Timer0Init 数码管显示 0] B --> C{while 1} C --> D{收到命令?} C --> E{自动模式+1s到?} D -- 是 --> F[解析命令并执行] E -- 是 --> G[读温度并超限告警] F --> C G --> C
相关推荐
H_oRIZoN_1 小时前
Linux入门DAY42【51 单片机】DS18B20 数字温度传感器完整解析(单总线原理 + 时序 + 读取流程)
linux·单片机·linux应用编程
智购无人售货机厂家2 小时前
2026自动售货机品类拓展逻辑:从饮料零食到鲜食药品文创的工程实践~YH
服务器·人工智能·单片机·线性代数·矩阵
ElfBoard2 小时前
作品展示|基于RK3588的复杂空间下自主导航无人机与多传感器 AI 融合环境监测分析
大数据·人工智能·单片机·嵌入式硬件·团队开发
星源~3 小时前
MCU-OTA升级的flash分散加载应用
单片机·嵌入式·ota·flash分散加载
单片机仿真设计3 小时前
【proteus仿真】基于 STM32 单片机农业灾害监测系统(仿真图+程序)
stm32·单片机·嵌入式硬件·proteus
Rocker-Chen4 小时前
应广科技MCU使用注意事项
单片机·嵌入式硬件
HRTOS4 小时前
HRTOS Debug 正式发布:为 8051 实时系统提供可观测、可诊断的运行状态监控能力
单片机·嵌入式硬件·51单片机
llilian_164 小时前
PTP时钟服务器时间溢出隐患解决方案 1588时钟服务器 ptp服务器
大数据·网络·单片机·嵌入式硬件·51单片机
女神下凡6 小时前
带NPU的电脑 和不带NPU的电脑 在使用上有什么不样
arm开发·单片机·pcm