在Proteus中“骗过”MCU:用虚拟雨滴点亮真实逻辑 💧💡
你有没有遇到过这种情况——项目急着要验证雨滴传感器的采集代码,结果快递还在路上,板子没到手,进度卡死?或者学生做课程设计,实验室器材有限,几个人抢一个黄山派开发板?
别慌。我们完全可以 在没有一块真实硬件的情况下,把整个传感-控制闭环跑通 。
今天,我就带你用 Proteus + GD32(或STM32) 搞一场“虚拟降雨”,让仿真里的LED随着你滑动鼠标而亮灭——就像真的下雨了一样。🌧️➡️🟢
这不是简单的“点灯教程”,而是一次 从物理原理建模到ADC采样、再到状态判断与输出响应的全链路打通 。你会发现:原来仿真不仅能“看起来像”,还能“逻辑上真”。
雨滴传感器的本质是什么?别被名字唬住了 🤔
先来拆个谜题:“黄山派雨滴传感器”听起来很玄乎,但它干的事其实特别朴素。
它本质上就是一个 湿敏电阻 + 信号调理电路 。当水落在那块裸露的PCB叉指电极上时,水分子把两个原本绝缘的金属条连了起来,相当于并联了一个可变电阻。雨水越多,导电越好,阻值越低。
这个变化的电阻,通常会被接成一个 分压电路 :
VCC (3.3V)
|
[R_fixed] 上拉电阻(比如10kΩ)
|
+-----> AO 输出 → 连接到MCU的ADC引脚
|
[R_wet] 湿敏部分(受雨水影响)
|
GND
所以,当没雨时,
R_wet
很大(可能几MΩ),AO接近GND(0V);
当下小雨时,
R_wet
下降到几十kΩ,AO电压上升;
暴雨时,
R_wet
可能只有几kΩ,AO接近VCC。
看到没?这不就是个 随环境变化的电位器 吗?
所以在Proteus里,我们根本不需要什么“黄山派原厂模型”——只要能模拟出这样一个 可调电压输出 ,就能完美替代!
如何在Proteus里造一场“人工雨”?🌧️⚡
打开Proteus ISIS,你会发现库里面压根搜不到“黄山派”。很正常,这种国产教学模块基本不会进官方元件库。但我们有三种方式“无中生有”。
方式一:手动电压源 —— 快速静态测试首选
最简单粗暴的方法:直接拖一个
DC_VOLTAGE_SOURCE
,设成0~5V之间某个值,接到MCU的PA0。
比如:
- 设为0.5V → 相当于晴天干燥状态
- 设为2.8V → 表示中到大雨
优点是 配置极简 ,适合调试阈值判断逻辑。缺点也很明显:不能动态变,每次想换“雨量”都得暂停仿真、改参数、重启——太麻烦。
小技巧:你可以多放几个不同电压的source,用开关切换,模拟“突降暴雨”的场景。
方式二:电位器分压电路 —— 教学演示神器 🎯
这才是我最推荐的方式,尤其适合课堂讲解或视频录制。
构建如下电路:
+5V
|
[10KΩ 固定电阻]
|
+-----> 连接到 MCU 的 PA0 (ADC输入)
|
[POT-HG 可调电阻 10KΩ] ← 在Proteus里叫这个名字
|
GND
在运行仿真时,点击这个电位器,会出现一个滑块条!你可以用鼠标实时调节它的阻值比例,从而改变中间节点的电压。
想象一下这个画面:你在讲课,一边说“现在开始下雨了”,一边慢慢向右拖动滑块,台下的学生看着屏幕上的LED从灭变亮——那种“哇”的瞬间就来了。😎
而且这种方式更贴近实际硬件行为,连非线性特性都能体现出来(毕竟真实传感器也不是完全线性的)。
方式三:PWM+RC滤波 —— 动态模拟高手玩法 🔁
如果你想要更高级的效果,比如模拟“雨势渐强→骤停→再下”的过程,可以用另一个单片机输出PWM波,经过RC低通滤波后生成类模拟电压。
例如:
- PWM占空比0% → 输出0V(晴天)
- 占空比50% → 输出约1.65V(小雨)
- 占空比90% → 输出约4.5V(暴雨)
然后把这个电压送给主控MCU的ADC口。
虽然多了一个MCU,但好处是可以编程控制“降雨曲线”,甚至加入随机扰动模拟噪声,测试系统的鲁棒性。
不过对于初学者来说,这有点杀鸡用牛刀了。先掌握前两种就够了。
ADC采集不是“读个数”那么简单 ⚖️
很多人以为ADC就是
read_adc()
返回一个数字完事。但如果你不去理解背后的机制,很容易踩坑。
我们以GD32F303为例(和STM32几乎一模一样),来看看关键点。
分辨率和参考电压决定精度
GD32的ADC一般是12位,意味着它可以将0~Vref之间的电压分成4096份。
假设供电是3.3V,那么每一份就是:
$$
\frac{3.3}{4096} \approx 0.805\text{mV}
$$
也就是说,理论上你能分辨出0.8毫伏的变化。听起来很牛?但前提是:
- Vref稳定
- 前端信号干净
- 采样时间足够长
否则,读出来的数据跳来跳去,根本没法用。
实际接线要注意这些细节 🔍
我在仿真中经常看到学生犯这几个错误:
- 把PA0接成了GPIO推挽输出(应该设为AIN模拟输入)
- 忘记开启ADC时钟(RCU enable)
- 使用了错误的通道编号(ADC_CHANNEL_0 ≠ PA0?其实是对的,但得确认映射关系)
还有电源去耦问题:虽然仿真里看不出噪声,但在真实世界中,一定要在VDDA和VSSA之间加一个0.1μF陶瓷电容,否则ADC结果会飘。
💡 经验分享:如果你发现ADC值波动大,优先检查三点:接地是否良好、电源是否干净、采样时间是否够长。
写代码之前,先想清楚你要判断什么 🧠
回到最初的问题:我们为什么要检测雨滴?
是为了关窗?晾衣架收回?还是温室大棚遮雨?
不同的应用场景,决定了你的 判断策略完全不同 。
简单阈值法:够用但容易误判
最常见的做法就是设个固定阈值:
#define RAIN_THRESHOLD 2048 // 对应约1.65V
然后:
if (adc_value > RAIN_THRESHOLD) {
gpio_bit_set(GPIOB, GPIO_PIN_0); // 开灯
} else {
gpio_bit_reset(GPIOB, GPIO_PIN_0); // 关灯
}
这当然可以工作。但现实中的问题是:
- 刚下完雨,板子还没干,电阻恢复慢;
- 空气湿度高,露水凝结导致误触发;
- 电压轻微波动就来回闪灯……
这就引出了一个重要概念: 软件滤波 。
加一层滤波,系统立马稳如老狗 🐶
最简单的改进是加个“迟滞比较器”思维:
#define RAIN_START 2200 // 大于才认为开始下雨
#define RAIN_STOP 2000 // 小于才认为雨停
这样就不会因为一点点波动反复开关。
还可以做移动平均:
#define SAMPLES 5
uint16_t buffer[SAMPLES];
int index = 0;
uint16_t get_filtered_adc() {
uint32_t sum = 0;
buffer[index++] = read_rain_sensor();
if (index >= SAMPLES) index = 0;
for (int i = 0; i < SAMPLES; i++) {
sum += buffer[i];
}
return sum / SAMPLES;
}
或者更进一步,用中值滤波抗突发干扰。
🛠️ 实战建议:在仿真阶段就把滤波逻辑写进去!不要等到实物才发现“怎么老是乱报警”。
完整工程结构长什么样?📦
下面是我常用的Proteus仿真模板结构:
Project/
│
├── rain_sensor_sim.pdsprj ← Proteus主文件
├── Source/
│ └── main.c ← C源码
├── Output/
│ └── firmware.hex ← 编译生成的HEX文件
└── Docs/
└── schematic.pdf ← 电路图打印版
在Keil MDK中编译好代码后,右键MCU元件 → Edit Properties → Program File,选择
.hex
文件加载进去。
推荐使用的MCU模型:
-
GD32F303CCT6
-
STM32F103C8T6
两者在Proteus中支持良好,外设齐全,且都有VSM模型可供仿真。
让它不只是“亮灯”:扩展更多功能 💡🔊
你以为只能点个LED?Too young.
接个蜂鸣器,搞个声光报警 🚨
很简单,在PB1上接个有源蜂鸣器(通过NPN三极管驱动更好),然后:
if (adc_value > RAIN_THRESHOLD) {
gpio_bit_set(GPIOB, GPIO_PIN_0); // LED亮
gpio_bit_set(GPIOB, GPIO_PIN_1); // 蜂鸣器响
} else {
gpio_bit_reset(GPIOB, GPIO_PIN_0);
gpio_bit_reset(GPIOB, GPIO_PIN_1);
}
瞬间就有了“气象站”的感觉。
数字输出DO也能用:中断唤醒模式 ⚡
别忘了,黄山派模块还有一个DO引脚,可以直接输出高低电平。
在Proteus里你可以额外加一个
COMPARATOR
,比如LM393,把AO输入和一个参考电压比较,生成数字信号。
然后把这个DO接到MCU的外部中断引脚(比如PA4),设置上升沿触发:
// 初始化EXTI
exti_init(EXTI_4, EXTI_INTERRUPT, EXTI_TRIG_RISING);
nvic_irq_enable(EXTI4_IRQn, 0, 0);
这样主循环可以休眠,靠中断唤醒,省电又高效。
✅ 特别适合电池供电的户外监测设备。
学生党福利:这是我给学生的标准作业模板 📄
每年带课设,我都发这么一套资料包:
✅
Proteus电路图
- 包含GD32最小系统(晶振、复位、BOOT)
- 电位器模拟雨滴传感器
- LED、蜂鸣器、串口调试接口预留
✅
Keil工程模板
- 已配置好启动文件、链接脚本、头文件路径
- 提供
delay.h
、
adc.h
、
gpio.h
基础封装
✅
任务清单
1. 实现ADC轮询采集
2. 添加移动平均滤波
3. 设置合理阈值控制LED
4. (加分项)通过串口打印当前ADC值
5. (挑战项)实现雨强分级(小雨/中雨/大雨)
效果立竿见影:以前学生花三天搭环境调硬件,现在第一天就能跑通逻辑,剩下两天优化算法。
为什么我说这是“国产MCU教育的好帮手”?🇨🇳
“黄山派”这类基于GD32的开源平台,最大的优势是什么?
不是性能多强,也不是价格多低,而是 生态友好 + 教学适配度高 。
- 引脚兼容STM32,学习成本低
- 社区教程丰富,百度能搜到答案
- 配合Proteus仿真,实现“零硬件启动”
更重要的是,它让我们有机会在教学中强调一点:
技术的本质不是依赖特定工具,而是解决问题的能力。
你没有黄山派?没关系,用STM32也行。
你没有雨滴传感器?没关系,用电位器代替。
你没有示波器?没关系,用串口打印观察波形。
这才是工程师该有的思维方式。
最后一个小彩蛋:如何假装自己有个“智能雨量计”?🎉
想不想让你的仿真看起来更专业一点?
试试这样做:
-
在Proteus里添加一个
VIRTUAL TERMINAL(虚拟终端) - 通过USART1连接到MCU的TX引脚
- 在代码里加上串口初始化,并定期发送ADC值:
printf("Rain ADC: %d (%.2fV)\r\n", adc_value, adc_value * 3.3 / 4096);
- 启动仿真,打开虚拟终端窗口
你会看到一行行数据刷出来:
Rain ADC: 1024 (0.82V)
Rain ADC: 1031 (0.83V)
Rain ADC: 2056 (1.65V) ← 开始下雨!
Rain ADC: 3120 (2.50V)
配上旁边慢慢变亮的LED,谁看了不说一句:“这系统真灵敏!” 😎
结束语?
不,这只是开始。
当你能在仿真中搞定雨滴检测,下一步就可以尝试:
- 温湿度传感器(DHT11/SHT30)仿真
- 光照强度(BH1750)I2C通信模拟
- OLED显示驱动
- 甚至WiFi模块(ESP8266)串口透传
最终拼成一个完整的“智慧农业监测站”仿真系统。
而这一切,只需要一台电脑 + 一份好奇心。
所以,还等什么?赶紧打开Proteus,拉个电位器,给自己下场雨吧。☔💻
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
2521

被折叠的 条评论
为什么被折叠?



