找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6|回复: 0
打印 上一主题 下一主题
收起左侧

[原创设计]51单片机DS18B20温度采集+LCD1602显示(完整代码+仿真)

[复制链接]
跳转到指定楼层
楼主
ID:842146 发表于 2026-7-7 11:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
一、前言
DS18B20是Dallas公司生产的一线式数字温度传感器,具有体积小、精度高、抗干扰能力强等特点,可直接将被测温度转换为数字信号输出,广泛用于工业控制、环境监测等场合。

本文将详细介绍如何使用51单片机(STC89C52)读取DS18B20温度数据,并通过LCD1602液晶显示屏实时显示,同时附带完整的C语言源代码和Proteus仿真电路说明。

二、硬件清单
1. STC89C52RC 单片机 x1
2. DS18B20 数字温度传感器 x1
3. LCD1602 字符液晶屏 x1
4. 4.7KΩ 上拉电阻 x1
5. 10KΩ 可调电阻 x1
6. 12MHz 晶振 x1
7. 30pF 瓷片电容 x2
8. 10μF 电解电容 x1
9. 按键 x1
10. 面包板及杜邦线若干

三、硬件接线

DS18B20 连接(单总线):
DS18B20 → 51单片机
GND    → GND
DQ     → P3.7(接4.7KΩ上拉到VCC)
VDD    → +5V

LCD1602 连接(8位并行):
LCD1602 → 51单片机
VSS     → GND
VDD     → +5V
V0      → 10K可调电阻中间抽头
RS      → P1.0
RW      → P1.1
E       → P1.2
D0~D7   → P0.0~P0.7
LED+    → +5V(串100Ω电阻)
LED-    → GND

四、工作原理

DS18B20采用一线通信协议(1-Wire),所有指令和数据都在一根数据线上完成传输。

温度读取流程:
1. 复位DS18B20
2. 发送跳过ROM指令(0xCC)
3. 发送启动温度转换指令(0x44)
4. 等待转换完成(约750ms)
5. 复位DS18B20
6. 发送跳过ROM指令(0xCC)
7. 发送读取暂存器指令(0xBE)
8. 读取LSB和MSB温度数据
9. 将数据合并计算实际温度值

五、完整源代码(main.c)
  1. #include <reg51.h>
  2. #include <stdio.h>
  3. #include <string.h>

  4. #define uchar unsigned char
  5. #define uint  unsigned int

  6. sbit DQ = P3^7;
  7. sbit LCD_RS = P1^0;
  8. sbit LCD_RW = P1^1;
  9. sbit LCD_E  = P1^2;

  10. uchar temp_buf[16];
  11. bit negative_flag = 0;

  12. void delay_us(uint us) { while(--us); }

  13. void delay_ms(uint ms)
  14. {
  15.     uint i, j;
  16.     for(i = 0; i < ms; i++)
  17.         for(j = 0; j < 120; j++);
  18. }

  19. bit DS18B20_Init(void)
  20. {
  21.     bit presence;
  22.     DQ = 1; delay_us(8);
  23.     DQ = 0; delay_us(600);
  24.     DQ = 1; delay_us(80);
  25.     presence = DQ;
  26.     delay_us(400);
  27.     return presence;
  28. }

  29. void DS18B20_WriteByte(uchar dat)
  30. {
  31.     uchar i;
  32.     for(i = 0; i < 8; i++)
  33.     {
  34.         DQ = 0; delay_us(2);
  35.         DQ = dat & 0x01;
  36.         delay_us(60); DQ = 1;
  37.         dat >>= 1;
  38.     }
  39. }

  40. uchar DS18B20_ReadByte(void)
  41. {
  42.     uchar i, dat = 0;
  43.     for(i = 0; i < 8; i++)
  44.     {
  45.         dat >>= 1; DQ = 0;
  46.         delay_us(2); DQ = 1;
  47.         delay_us(2);
  48.         if(DQ) dat |= 0x80;
  49.         delay_us(60);
  50.     }
  51.     return dat;
  52. }

  53. int DS18B20_GetTemp(void)
  54. {
  55.     uchar LSB, MSB;
  56.     int temp;

  57.     DS18B20_Init();
  58.     DS18B20_WriteByte(0xCC);
  59.     DS18B20_WriteByte(0x44);
  60.     delay_ms(750);

  61.     DS18B20_Init();
  62.     DS18B20_WriteByte(0xCC);
  63.     DS18B20_WriteByte(0xBE);

  64.     LSB = DS18B20_ReadByte();
  65.     MSB = DS18B20_ReadByte();

  66.     temp = (MSB << 8) | LSB;
  67.     if(temp & 0x8000)
  68.     {
  69.         temp = (~temp) + 1;
  70.         negative_flag = 1;
  71.     }
  72.     else
  73.     {
  74.         negative_flag = 0;
  75.     }

  76.     temp = temp * 100 / 16;
  77.     return temp;
  78. }

  79. void LCD_CheckBusy(void)
  80. {
  81.     uchar status;
  82.     LCD_RS = 0; LCD_RW = 1;
  83.     do {
  84.         LCD_E = 1; delay_us(5);
  85.         status = P0; LCD_E = 0;
  86.         delay_us(5);
  87.     } while(status & 0x80);
  88. }

  89. void LCD_WriteCmd(uchar cmd)
  90. {
  91.     LCD_CheckBusy();
  92.     LCD_RS = 0; LCD_RW = 0;
  93.     P0 = cmd; LCD_E = 1;
  94.     delay_us(5); LCD_E = 0;
  95.     delay_ms(2);
  96. }

  97. void LCD_WriteData(uchar dat)
  98. {
  99.     LCD_CheckBusy();
  100.     LCD_RS = 1; LCD_RW = 0;
  101.     P0 = dat; LCD_E = 1;
  102.     delay_us(5); LCD_E = 0;
  103.     delay_ms(2);
  104. }

  105. void LCD_Init(void)
  106. {
  107.     delay_ms(15);
  108.     LCD_WriteCmd(0x38);
  109.     LCD_WriteCmd(0x0C);
  110.     LCD_WriteCmd(0x06);
  111.     LCD_WriteCmd(0x01);
  112.     delay_ms(2);
  113. }

  114. void LCD_SetPos(uchar row, uchar col)
  115. {
  116.     uchar addr;
  117.     if(row == 0) addr = 0x80 + col;
  118.     else addr = 0xC0 + col;
  119.     LCD_WriteCmd(addr);
  120. }

  121. void LCD_ShowString(uchar row, uchar col, uchar *str)
  122. {
  123.     LCD_SetPos(row, col);
  124.     while(*str) LCD_WriteData(*str++);
  125. }

  126. void Display_Temperature(int temp)
  127. {
  128.     uchar i = 0;
  129.     int integer_part, decimal_part;

  130.     integer_part = temp / 100;
  131.     decimal_part = temp % 100;

  132.     if(negative_flag) temp_buf[i++] = '-';

  133.     if(integer_part >= 100)
  134.         temp_buf[i++] = '0' + integer_part / 100;
  135.     if(integer_part >= 10)
  136.         temp_buf[i++] = '0' + (integer_part % 100) / 10;
  137.     temp_buf[i++] = '0' + integer_part % 10;
  138.     temp_buf[i++] = '.';
  139.     temp_buf[i++] = '0' + decimal_part / 10;
  140.     temp_buf[i++] = 0xDF;
  141.     temp_buf[i++] = 'C';
  142.     temp_buf[i] = '\0';

  143.     LCD_ShowString(1, 4, temp_buf);
  144. }

  145. void main(void)
  146. {
  147.     int temperature;
  148.     LCD_Init();
  149.     LCD_ShowString(0, 0, "Temp Monitor");
  150.     LCD_ShowString(1, 0, "Temp: ");

  151.     while(1)
  152.     {
  153.         temperature = DS18B20_GetTemp();
  154.         Display_Temperature(temperature);
  155.         delay_ms(500);
  156.     }
  157. }
复制代码

六、Keil工程配置
1. 新建工程,选择AT89C52或STC89C52RC
2. 创建main.c,粘贴代码
3. 晶振频率设为12MHz
4. 勾选生成HEX文件
5. 编译通过后生成.hex文件

七、Proteus仿真搭建
1. 放置AT89C52、DS18B20、LCD1602、RESPACK-8排阻
2. 晶振电路:12MHz晶振+30pF电容x2
3. 复位电路:10μF+10KΩ
4. 按接线图连接
5. 加载.hex文件到单片机
6. 运行仿真

八、注意事项
1. DS18B20数据线必须接4.7KΩ上拉电阻
2. 温度转换时间最长750ms,读取间隔不能小于此值
3. LCD1602的V0需电位器调节对比度
4. STC系列注意IRC频率与代码延时匹配

九、扩展方向
1. 加蜂鸣器+LED实现温度报警
2. 加EEPROM存储温度记录
3. 加按键设置温度阈值
4. 串口发送温度到PC
5. 加DS1302实现带时间戳的温度记录仪

十、总结
本文介绍了51单片机+DS18B20+LCD1602温度采集系统的硬件设计、工作原理和完整代码。系统结构简单、成本低廉,适合初学者作为综合练习。代码在Keil C51编译通过,Proteus 8.9仿真验证。

如有问题欢迎回帖交流!

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表