news 2026/5/1 5:55:35

新手教程:用51单片机和LCD1602制作简易压力表

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
新手教程:用51单片机和LCD1602制作简易压力表

从零开始做一个简易压力表:51单片机 + LCD1602 实战教学

你有没有想过,一块小小的电路板,加上几根导线和一个液晶屏,就能变成一个能“感知”世界的小设备?今天我们就来动手实现这样一个项目——用最经典的51单片机和LCD1602,做一个可以显示实时压力的简易压力表

这个项目不依赖复杂的开发环境或昂贵的芯片,成本低、原理清晰、调试方便,特别适合电子类专业学生、嵌入式初学者或者想亲手做点小玩意儿的DIY爱好者。更重要的是,它完整地走通了“采集—处理—显示”这一嵌入式系统的核心链路。


为什么选51单片机和LCD1602?

尽管现在有STM32、ESP32等性能强大的MCU,但对于刚入门的同学来说,51单片机依然是最好的起点之一。它的架构简单、资源明确、资料丰富,而且Keil C51编译器成熟稳定,STC系列还支持串口直接下载程序,免去了仿真器的麻烦。

LCD1602作为上世纪就广泛应用的经典字符型液晶模块,至今仍活跃在各种教学实验和工业仪表中。它不需要图形库、不用写显存操作,只要发送ASCII码就能显示文字,非常适合学习基础的IO控制与通信时序。

更重要的是:
✅ 学得懂
✅ 买得起(整套材料不到30元)
✅ 焊得动(DIP封装,手焊无压力)
✅ 调得出(现象直观,出错容易排查)

我们这次要做的压力表,结构如下:

[压力传感器] → [ADC0832] → [STC89C52RC] → [LCD1602] ↑ ↓ (模拟电压) (数字显示)

整个系统由三部分组成:
-感知层:压力传感器 + ADC模数转换
-控制层:51单片机进行数据处理
-输出层:LCD1602实时显示压力值

下面我们就一步步拆解,带你把这块“会说话”的压力表做出来。


第一步:搞清楚你的“大脑”——STC89C52怎么用

我们选用的是STC89C52RC,这是一款增强型51内核的8位单片机,40引脚DIP封装,工作电压5V,主频通常使用11.0592MHz晶振(为了串口通信准确)。

关键资源一览:

参数
Flash程序存储8KB
RAM数据存储512B
I/O端口P0~P3,共32个可编程IO
定时器3个(T0/T1/T2)
串口1个全双工UART
中断源6个(外部中断0/1、定时器0/1/2、串口中断)

虽然性能比不上现代MCU,但足够应付本项目的需求了。

最基本的操作:点亮LED

在接入复杂外设之前,先验证最小系统是否正常。我们可以从最简单的GPIO操作开始:

#include <reg52.h> sbit LED = P1^0; // 将P1.0定义为LED控制脚 void delay_ms(unsigned int ms) { unsigned int i, j; for (i = ms; i > 0; i--) for (j = 110; j > 0; j--); // 约等于1ms延时(基于12MHz) } void main() { while (1) { LED = 0; // 拉低电平,点亮LED(共阳接法) delay_ms(500); LED = 1; // 拉高电平,熄灭LED delay_ms(500); } }

💡 提示:51单片机P0口没有内部上拉电阻,驱动能力弱,建议用于数据总线或配合上拉电阻使用;P1/P2/P3都有内部弱上拉,更适合做通用IO。

这短短十几行代码,其实包含了三个关键知识点:
- 头文件包含(reg52.h提供寄存器映射)
- 位操作宏(sbit定义单个引脚)
- 软件延时函数(靠循环空转实现时间等待)

掌握这些,你就已经迈过了第一个门槛。


第二步:让屏幕“说话”——LCD1602怎么驱动

LCD1602能显示两行、每行16个字符,比如你想让它第一行显示“Pressure:”,第二行显示“45.6 kPa”,就得学会怎么给它下命令。

接口方式选择:4位模式更省IO

51单片机IO有限,所以我们采用4位数据模式,只用D4~D7四条数据线,配合三条控制线(RS、RW、E),总共只需6个IO口。

引脚功能连接建议
RS寄存器选择(0=命令,1=数据)P2^0
RW读写控制(0=写,1=读)P2^1(固定接地也可,只写不读)
E使能信号(下降沿触发)P2^2
D4~D7数据输入(高4位)P0^4~P0^7

此外,VL脚接一个10kΩ电位器用来调节对比度,背光LED需串联220Ω限流电阻。

初始化是关键

LCD1602上电后不能立刻写数据,必须按照特定时序发送初始化指令。以下是标准流程:

#include <reg52.h> #define LCD_DATA_PORT P0 // 使用P0口高四位传输数据 sbit RS = P2^0; sbit RW = P2^1; sbit EN = P2^2; void lcd_enable() { EN = 1; delay_ms(1); EN = 0; // 下降沿锁存 } // 写命令函数(4位模式) void lcd_write_cmd(unsigned char cmd) { RS = 0; // 写命令 RW = 0; LCD_DATA_PORT = (cmd >> 4) & 0x0F; // 发送高4位 lcd_enable(); LCD_DATA_PORT = cmd & 0x0F; // 发送低4位 lcd_enable(); delay_ms(2); // 等待命令执行 } // 写数据函数 void lcd_write_data(unsigned char dat) { RS = 1; // 写数据 RW = 0; LCD_DATA_PORT = (dat >> 4) & 0x0F; lcd_enable(); LCD_DATA_PORT = dat & 0x0F; lcd_enable(); delay_ms(1); } // 初始化函数 void lcd_init() { delay_ms(15); // 上电延迟 lcd_write_cmd(0x28); // 4位模式,2行显示,5x7字体 lcd_write_cmd(0x0C); // 开显示,关光标,不闪烁 lcd_write_cmd(0x06); // 自动增量地址,不移屏 lcd_write_cmd(0x01); // 清屏 delay_ms(2); }

初始化完成后,就可以往指定位置写字符串了。例如:

void lcd_show_str(unsigned char x, unsigned char y, char *str) { if (y == 0) lcd_write_cmd(0x80 + x); // 第一行 else if (y == 1) lcd_write_cmd(0xC0 + x); // 第二行 while (*str) { lcd_write_data(*str++); } } // 调用示例 lcd_show_str(0, 0, "Pressure:");

屏幕上就会出现我们熟悉的提示语啦!


第三步:让机器“感知”压力——ADC+传感器怎么配合

51单片机本身没有内置ADC模块(少数增强型号除外),所以我们需要外接一个模数转换芯片。这里推荐使用ADC0832,它是8位分辨率、双通道、串行输出的ADC,价格便宜、接口简单,非常适合本项目。

传感器选型建议

常见的模拟输出型压力传感器包括:
- MPX5700AP(0~100kPa,输出0.2~4.7V)
- BMP180/BMP280(数字I2C接口,不适合本项目)
- HX711(专用于称重,需桥式激励)
- 或者使用压阻式压力模块(带放大电路,输出0~5V线性电压)

我们假设使用一种线性输出的压力传感器,满量程对应5V。

ADC0832连接方式

引脚说明连接到
CS片选(低有效)P3^2
CLK时钟输入P3^0
DI输入(配置通道)P3^1
DO输出(读取数据)P3^1(复用)
VCC/GND电源5V / GND
IN+模拟输入正极传感器输出

注意:DI和DO可以共用一根线,因为ADC0832是半双工通信。

读取ADC值的代码实现

sbit ADC_CS = P3^2; sbit ADC_CLK = P3^0; sbit ADC_DIO = P3^1; unsigned char adc_read(char channel) { unsigned char i, val = 0; ADC_CS = 0; // 选中芯片 // 起始位 + 配置 ADC_DIO = 1; ADC_CLK = 1; _nop_(); ADC_CLK = 0; ADC_DIO = 1; ADC_CLK = 1; _nop_(); ADC_CLK = 0; // 选择通道(CH0=0, CH1=1) ADC_DIO = channel & 0x01; ADC_CLK = 1; _nop_(); ADC_CLK = 0; // 单端输入模式(下一个bit为1) ADC_DIO = 1; ADC_CLK = 1; _nop_(); ADC_CLK = 0; // 读取8位数据(高位在前) for (i = 0; i < 8; i++) { ADC_CLK = 1; _nop_(); val <<= 1; if (ADC_DIO) val |= 0x01; ADC_CLK = 0; _nop_(); } ADC_CS = 1; // 取消片选 return val; }

调用adc_value = adc_read(0);即可获取当前通道的ADC值(范围0~255)。

把数字变成真实压力

由于ADC是8位,参考电压为5V,则每个LSB代表约19.5mV。若传感器输出电压与压力成线性关系:

$$
V_{out} = \frac{P}{P_{max}} \times 5V
\Rightarrow P = \frac{V_{out}}{5} \times P_{max}
$$

而 $ V_{out} = \frac{adc_value}{255} \times 5 $

所以最终公式为:

float pressure_kpa = (float)adc_value * 100.0 / 255.0; // 假设Pmax=100kPa

你可以根据实际传感器参数调整比例系数。


第四步:整合系统,实现完整功能

现在所有模块都准备好了,接下来就是主程序逻辑的设计。

主流程设计

void main() { unsigned char adc_val; float pressure; char buffer[16]; // 初始化 lcd_init(); lcd_show_str(0, 0, "Pressure:"); while (1) { // 读取ADC adc_val = adc_read(0); // 转换为压力值 pressure = (float)adc_val * 100.0 / 255.0; // 格式化为字符串 sprintf(buffer, "%.1f kPa", pressure); // 显示到第二行 lcd_show_str(0, 1, " "); // 先清空旧数据 lcd_show_str(0, 1, buffer); delay_ms(500); // 刷新间隔500ms } }

⚠️ 注意:sprintf需要包含<stdio.h>,并在Keil中开启“Use MicroLIB”以减小程序体积。

这样,LCD上就会动态显示出类似“45.6 kPa”的实时压力值了!


常见问题与调试技巧

❌ 屏幕黑屏或乱码?

  • 检查VL脚电压是否在0.8~1.2V之间(可用万用表测)
  • 确保EN引脚有下降沿触发
  • 初始化顺序不能错,尤其是第一次进入4位模式的那几步

❌ ADC读数跳变严重?

  • 在传感器输出端并联一个0.1μF陶瓷电容滤波
  • 改进软件算法:连续采样5次,去掉最大最小值后求平均
unsigned char get_filtered_adc() { unsigned char samples[5], temp, i, j; unsigned int sum = 0; for (i = 0; i < 5; i++) { samples[i] = adc_read(0); delay_ms(10); } // 冒泡排序 for (i = 0; i < 4; i++) for (j = 0; j < 4 - i; j++) if (samples[j] > samples[j+1]) { temp = samples[j]; samples[j] = samples[j+1]; samples[j+1] = temp; } // 取中间三个求平均 for (i = 1; i <= 3; i++) sum += samples[i]; return (unsigned char)(sum / 3); }

❌ 显示刷新慢?

  • 减少不必要的延时
  • 可改用定时器中断驱动采集,主循环只负责显示更新

设计优化建议

  1. 增加零点校准功能
    加一个按键,在无压力状态下按下即可将当前值设为“0”,消除零漂误差。

  2. 加入超限报警
    当压力超过设定阈值时,驱动蜂鸣器或LED报警。

  3. 预留通信接口
    利用51单片机的UART,通过MAX232或CH340上传数据到电脑,便于记录分析。

  4. 升级为电池供电+低功耗设计
    使用LM1117-3.3V稳压,搭配休眠模式延长续航。


结语:这不是终点,而是起点

当你看到LCD上那个不断跳动的“压力值”时,别忘了,这背后是一整套嵌入式系统的缩影:
- 传感器在“看”
- ADC在“听”
- 单片机在“思考”
- 液晶屏在“说”

你亲手搭建的不只是一个压力表,而是一个微型智能终端的原型。掌握了这套方法论,下一步你完全可以去做:
- 数字温度计(DS18B20 + LCD)
- 电子秤(HX711 + LCD)
- 湿度监测仪(DHT11 + LCD)
甚至未来过渡到STM32平台,加入WiFi、蓝牙、云平台也不再遥远。

🔧 工具清单(供参考):
- STC89C52最小系统板 ×1
- LCD1602模块 ×1
- ADC0832芯片 ×1
- 模拟压力传感器模块 ×1
- 5V电源(USB或适配器)×1
- 面包板 + 杜邦线若干
- Keil uVision5 + STC-ISP下载工具

如果你正在学单片机,不妨今晚就动手试试。有时候,真正让你入门的不是书本,而是一块亮起来的屏幕

欢迎在评论区分享你的制作过程和遇到的问题,我们一起解决!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 5:53:44

MathType公式库扩充计划引入语音录入方式

MathType公式库扩充计划引入语音录入方式 在数学教学、科研写作和数字出版的日常实践中&#xff0c;输入复杂的数学表达式始终是一项繁琐且技术门槛较高的任务。传统的键盘输入依赖LaTeX语法或图形化编辑器的点选操作&#xff0c;对教师、学生尤其是非专业用户而言&#xff0c;…

作者头像 李华
网站建设 2026/5/1 5:54:34

PyCharm社区版用户成功运行Fun-ASR后端

PyCharm社区版用户成功运行Fun-ASR后端 在如今AI模型动辄需要云服务器、专业IDE和复杂部署流程的背景下&#xff0c;一个看似“不可能”的任务正在悄然成为现实&#xff1a;使用免费的PyCharm社区版&#xff0c;在一台普通笔记本上完整运行通义实验室与钉钉联合推出的Fun-ASR语…

作者头像 李华
网站建设 2026/4/24 3:17:13

进度条可视化:实时显示长文本合成剩余时间

进度条可视化&#xff1a;实时显示长文本合成剩余时间 在有声读物平台的后台&#xff0c;一位编辑上传了一段三万字的小说章节&#xff0c;点击“语音合成”后&#xff0c;页面陷入长达数分钟的静默。没有进度提示、没有时间预估&#xff0c;只有浏览器标签上缓慢旋转的加载图标…

作者头像 李华
网站建设 2026/5/1 5:54:52

数字电路实验与工业传感器接口设计:系统学习

从实验室到工厂现场&#xff1a;数字电路与工业传感器接口的实战之路你有没有遇到过这样的情况&#xff1f;在实验室里调试得好好的传感器系统&#xff0c;一搬到工厂现场就“水土不服”——数据跳变、通信中断、偶尔死机。明明代码没改&#xff0c;硬件也没动&#xff0c;问题…

作者头像 李华
网站建设 2026/4/26 18:22:56

微pe驱动加载确保GPU正常工作支持GLM-TTS

微PE驱动加载确保GPU正常工作支持GLM-TTS 在边缘计算与现场部署日益普及的今天&#xff0c;如何让复杂的生成式AI模型在资源受限、无盘或快速启动的环境中稳定运行&#xff0c;已成为一个关键挑战。设想这样一个场景&#xff1a;你需要在一台没有硬盘的工控机上&#xff0c;仅通…

作者头像 李华
网站建设 2026/4/23 18:50:05

Discord社群运营:打造全球化GLM-TTS爱好者交流空间

Discord社群运营&#xff1a;打造全球化GLM-TTS爱好者交流空间 在AI语音技术飞速发展的今天&#xff0c;我们不再满足于“能说话”的机器声音。无论是为动画角色赋予灵魂&#xff0c;还是让有声书朗读充满情感起伏&#xff0c;亦或是构建个性化的虚拟助手&#xff0c;用户对语音…

作者头像 李华