news 2026/5/11 22:48:04

新手教程:用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/10 18:27:18

git reset撤销操作前听取Fun-ASR风险提示

git reset撤销操作前听取Fun-ASR风险提示 在语音识别技术快速渗透进会议记录、客服系统和智能办公的今天&#xff0c;一个看似简单的命令行操作&#xff0c;可能悄然埋下数据丢失的隐患。比如&#xff0c;在本地部署 Fun-ASR 这类基于大模型的语音识别系统时&#xff0c;一句 g…

作者头像 李华
网站建设 2026/5/8 3:47:13

谷歌翻译API对比Fun-ASR中文识别准确率

谷歌翻译API对比Fun-ASR中文识别准确率 在智能语音应用日益普及的今天&#xff0c;越来越多开发者尝试将语音内容自动转换为文字。然而一个常见的误区是&#xff1a;误以为像谷歌翻译这样的机器翻译服务也能“听懂”语音。尤其是在处理中文语音时&#xff0c;不少项目初期直接调…

作者头像 李华
网站建设 2026/5/6 20:37:18

JavaScript前端如何对接GLM-TTS后端API实现网页语音合成

JavaScript前端如何对接GLM-TTS后端API实现网页语音合成 在智能内容生成&#xff08;AIGC&#xff09;浪潮席卷各行各业的今天&#xff0c;语音合成已不再是实验室里的高冷技术&#xff0c;而是逐渐渗透进我们日常使用的每一个应用中——从有声书平台到虚拟主播直播&#xff0c…

作者头像 李华
网站建设 2026/5/10 14:07:59

网盘回收站恢复误删的Fun-ASR重要文件

网盘回收站恢复误删的Fun-ASR重要文件 在一次例行模型更新中&#xff0c;某企业AI运维团队不小心执行了 rm -rf models/ 命令&#xff0c;导致部署在本地服务器上的 Fun-ASR 语音识别系统瞬间“失声”——所有识别任务报错&#xff0c;历史记录无法加载。更糟的是&#xff0c;他…

作者头像 李华
网站建设 2026/5/10 16:59:35

MathType学生版价格贵?Fun-ASR教育免费用

Fun-ASR&#xff1a;用免费语音识别打破教育技术壁垒 在一所普通中学的英语课堂上&#xff0c;老师刚结束一段听力训练。几个学生举手提问&#xff1a;“老师&#xff0c;刚才那段话里‘global warming’后面说的是‘carbon emissions’还是‘carbon footprint’&#xff1f;”…

作者头像 李华
网站建设 2026/5/3 8:19:23

语音合成中的专业术语发音校正:医学、法律等领域适配

语音合成中的专业术语发音校正&#xff1a;医学、法律等领域适配 在三甲医院的智能导诊系统中&#xff0c;AI语音将“冠心病”读成“gun xīn bng”&#xff0c;而非正确的“guān xīn bng”——这看似微小的偏差&#xff0c;可能让患者误解为“灌注性心脏病”&#xff0c;进而…

作者头像 李华