拓冰建站拓冰建站
首页 / 资讯中心 / 正文

基于STM32的智能婴儿床设计与Proteus仿真实现

简介基于STM32的智能婴儿床完整项目资料面向电子设计与嵌入式开发学习者涵盖温度/湿度监测、尿湿检测、婴儿啼哭安抚、撞击预警及液晶显示与按键操作等典型功能是一套可参考的软硬件结合实训方案。资源包共87个文件以C语言源码、头文件、Keil工程文件、Proteus仿真文件及hex烧录文件为主也包含编译中间文件和备份文件便于对照工程结构理解代码与仿真流程压缩包整体约659KB轻量易用适合课设、毕设或竞赛场景快速上手。已有531人学习下载。资料内代码模块划分清晰仿真运行文件与工程配置齐全可在Proteus中直观验证传感器联动逻辑并参考LCD显示、语音播报与按键交互等外围驱动写法帮助读者建立起从外设驱动到系统联调的整体认知。1. 基于STM32智能婴儿床的设计思路与目标把“智能婴儿床”四个字拆开看核心其实不是床而是“感知—决策—执行”这条嵌入式控制链路宝宝哭了要能识别尿湿了要能报警温度高了要能通风摇篮摆动频率要根据睡眠状态自动调整。STM32在这类项目里之所以被反复选中是因为它不像Arduino那样局限于简单逻辑而是能在 72MHz 主频下同时管理多个定时器、ADC、USART 和 PWM 输出照顾到信号采集的精度和电机控制的实时性。这篇文章就以最常见的 STM32F103C8T6 为例配合 DHT11 温湿度传感器、模拟声音传感器、28BYJ-48 步进电机和 Proteus 仿真环境把从原理图设计到代码调试的完整方案讲清楚。无论你是做毕业设计、准备电子竞赛还是想在手头项目里复用这套传感器控制逻辑都可以按章节直接跟着做。2. STM32智能婴儿床的系统架构与关键硬件选型硬件选型的顺序往往被新手搞反先把传感器买回来再去想怎么接最后发现引脚不够用、驱动电流不足、时钟配置对不上。真正稳的做法是先把功能拆成数据流再从前端到后端逐级确定器件和接口类型最后才画原理图。2.1 婴儿床的功能模块划分与数据流设计智能婴儿床通常需要这几路信号环境温湿度采集、哭声检测、尿湿状态检测、摇篮电机控制、状态指示和可选的数据远传。数据流可以描述为传感器把物理量变成电信号经过 STM32 的 GPIO 或 ADC 采集在定时器中断里完成滤波和阈值判断然后通过 PWM 或 GPIO 序列驱动执行器同时把关键状态通过 USART 或 I2C 输出到显示设备。2.1.1 传感器接口数字单总线与模拟量输出的取舍在成本可控的前提下温湿度测量我一般选 DHT11 而不是 SHT30这纯粹是平衡项目调试复杂度DHT11 用单总线协议一根数据线就能完成双向通信电路上只要一个 4.7kΩ 上拉电阻缺点是时序要求极其严格必须在代码里用微秒级延时或定时器捕获来实现这对理解 STM32 的定时器反而有帮助。声音检测则用带 LM393 比较器的模拟输出模块输出 0~3.3V 的模拟电平接到 STM32 的 ADC 引脚这样后续可以采集波形而不是只判断有无声音如果只用数字输出端口就只能得到一个高低电平无法区分哭声和环境噪音。传感器选型对比表传感器接口类型供电电压占用引脚数据内容典型采样周期DHT11单总线3.3V~5V1 个 GPIO温度湿度1s声音传感器模块模拟电压3.3V~5V1 个 ADC声音强度实时尿湿传感器开关量3.3V1 个 GPIO0 或 1按需DS18B20可选单总线3.3V~5V1 个 GPIO温度750ms2.1.2 执行机构步进电机与直流减速电机的分工摇篮摆动通常有两种实现用 28BYJ-48 步进电机做往复旋转或用直流减速电机加偏心轮产生摆动。步进电机的优势是能精确控制摆角配合 ULN2003 驱动板只需要四个 GPIO缺点是转速慢、噪声大直流电机转速快但无法精确限位。我倾向用 28BYJ-48 步进电机因为它自带 1:64 减速箱堵转电流不会烧驱动而且在仿真里更容易观察到脉冲序列是否正确。夜灯亮度调节则用单独的 PWM 引脚控制一个 NPN 三极管来驱动 LED这部分不占用额外定时器资源。2.2 电源链路与低功耗设计要点婴儿床如果插电使用直接用 5V 适配器给 ULN2003 供电再经 AMS1117-3.3 给 STM32 供电即可。但如果目标是电池供电就必须考虑低功耗STM32F103 的 STOP 模式待机电流在 10μA 级别但 DHT11 上电后空闲电流也有 50μA 左右电机驱动板静态电流更大。常见做法是用一个 P-MOS 管控制传感器和驱动板的电源轨MCU 在进入 STOP 前把负载电源切断只保留 GPIO 唤醒和 RTC 闹钟。测量待机电流时注意要把电流表串在电池正极不要在 Proteus 里看数据仿真模型对功耗的描述并不精确。3. 用Keil5编写STM32婴儿床核心控制代码代码结构直接决定调试效率。建议按main.c、bsp_clock.c、bsp_dht11.c、bsp_motor.c、bsp_usart.c拆文件每个外设模块独立编译。下面三段代码是必须优先跑通的时钟树配置、DHT11 读取、步进电机驱动。先保证这三个模块正常再往上层加逻辑判断。3.1 初始化顺序先配时钟树再开外设时钟不少 5 年以上经验的工程师也会在这里栽跟头GPIO 初始化写在系统时钟配置前面导致外设频率不对USART 波特率偏差 3% 以上。STM32F103 默认使用内部 8MHz HSI要跑到 72MHz 必须打开 HSE 外部晶振并配置 PLL。标准库写法如下void SystemClock_Config(void) { ErrorStatus status; RCC_DeInit(); RCC_HSEConfig(RCC_HSE_ON); // 打开8MHz外部高速晶振 status RCC_WaitForHSEStartUp(); if (status SUCCESS) { RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); // 8MHz * 9 72MHz RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); RCC_HCLKConfig(RCC_SYSCLK_Div1); // AHB 72MHz RCC_PCLK2Config(RCC_HCLK_Div1); // APB2 72MHz RCC_PCLK1Config(RCC_HCLK_Div2); // APB1 36MHzAPB1外设不能超过36MHz RCC_GetClocksFreq(RCC_ClocksStatus); } }这段代码的逻辑是先把 RCC 寄存器恢复到默认值再依次打开 HSE、等待起振、配置 PLL 倍频系数、把 PLLCLK 设为系统时钟源。参数配置时重点检查RCC_PLLMul_9和RCC_PCLK1_Div2前者把 8MHz 倍频到 72MHz后者保证 APB1 总线上的定时器如 TIM3时钟不超过 36MHz。如果外部晶振不起振程序会卡在RCC_WaitForHSEStartUp()循环里仿真时看到 LED 不闪第一反应就应该是换回 HSI 做简化解耦。3.2 DHT11 单总线时序与超时保护DHT11 的一次通信流程是主机拉低总线 18ms然后拉高 20~40μs释放总线等待从机响应。从机随后返回 80μs 低电平、80μs 高电平再输出 40bit 数据。每个 bit 的高电平时间不同26~28μs 表示 070μs 表示 1。读取代码必须基于定时器计数而非for循环因为 Keil 的优化等级会改变循环耗时。下面是基于 TIM2 微秒计数实现的部分读取函数uint8_t DHT11_ReadByte(void) { uint8_t i, byte 0; for (i 0; i 8; i) { while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) 0); // 等待bit起始低电平结束 DelayUs(40); if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) 1) { // 40us后仍为高判定为1 byte | (0x80 i); } while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) 1); // 等待bit结束 } return byte; }DelayUs(40)的实现建议用SysTick或者一个自减循环配合空指令不要直接挪用在正点原子例程里的版本就完事。读取完成后要校验humi temp checksum 0xFF。仿真时如果发现读出的数据始终是 0xFF最常见原因是 GPIO 模式没有从推挽输出切换到浮空输入DHT11 应答信号被引脚拉低。写代码时要在每次通信开始前重新设置GPIOB-CRL寄存器保证双向传输畅通。3.3 步进电机驱动与 PWM 参数计算28BYJ-48 是四相八拍电机半拍模式下节拍顺序为 A-AB-B-BC-C-CD-D-DA。用一个数组按序输出高低电平到 ULN2003 的四个输入即可const uint8_t step_table[8] {0x01, 0x03, 0x02, 0x06, 0x04, 0x0C, 0x08, 0x09}; void Motor_Step(uint8_t dir, uint16_t steps) { uint16_t i; uint8_t index 0; for (i 0; i steps; i) { GPIO_Write(GPIOA, step_table[index]); if (dir 1) index (index 1) % 8; else index (index 7) % 8; DelayMs(2); // 2ms节拍间隔对应约250转/分钟可根据需要调整 } }这个函数把步数转成节拍改DelayMs(2)即可调速但不要小于 1.5ms否则转矩下降明显。如果要让摇篮匀速摆动更优雅的做法是让电机先正转 N 步、停 20ms、再反转 N 步通过调节 N 和停顿时间控制摆幅。夜灯的 PWM 配置则用 TIM3 通道 1输出 1kHz 占空比可变的波形这部分参数建议在运行时用按键实时调整方便观察效果。4. 基于Proteus的STM32婴儿床仿真与单步调试仿真环境的价值不只是省一块开发板钱更重要的是能快速定位代码逻辑错误。Proteus 8.x 以上版本自带 STM32F103C8T6 仿真模型配合 DHT11、ULN2003、MOTOR-STEPPER、VIRTUAL TERMINAL可以直接观察数据总线的时序波形。但要注意仿真模型对引脚复用优先级和开漏模式的模拟是简化过的有些问题在仿真里看不到这部分会在 4.3 节单独说明。4.1 搭建电路从原理图到虚拟终端放置元件后把 STM32F103C8T6 的 PD0/PD1 外接两个电容和晶振晶振频率设为 8MHz并在电源引脚加 100nF 去耦电容。然后将 DHT11 数据脚接 PB0声音传感器输出接 PA1ADC 通道ULN2003 输入接 PA0~PA3电机输出接 MOTOR-STEPPER。最后从 Virtual Instruments 里拖出 VIRTUAL TERMINAL把 TXDPA9接进去用于观察串口输出。电路连接清单模块STM32引脚备注DHT11 DATAPB0接4.7kΩ上拉到3.3V声音模块 AOUTPA1ADC1_IN1ULN2003 IN1~IN4PA0~PA3按顺序接蜂鸣器可选PB1有源蜂鸣器USART1 TXPA9接虚拟终端 RXD4.2 加载HEX文件与信号观测在 Keil 中勾选 Options for Target → Output → Create HEX File编译后在工程目录下生成.hex文件。回到 Proteus双击 MCU 芯片在 Program File 中选择该 HEX设置外部晶振频率为 8MHz点击运行。如果一切正常虚拟终端每 2 秒会打印一次Temp27.0 Humi65.0这样的字符串。如果终端没有输出先用示波器抓 PA9 引脚信号确认有没有波形有波形但终端乱码就是波特率不一致。注意虚拟终端要手动设置相同的波特率值例如 9600、8、N、1还要确保RCC_PCLK2Config正确配置了 APB2 时钟否则 USART 的波特率计算会偏移。4.3 仿真的三个典型问题与排查方法第一个问题是 DHT11 无应答波形一直为高。原因是代码里 GPIO 模式切换后没有做延时数据线状态不稳定在读取前加 10ms 的稳定等待恢复上拉状态。第二步进电机只抖动不转这是节拍数组的相序与 ULN2003 接线不匹配导致的把step_table的数组元素顺序反一下即可比如把0x01,0x03,0x02改成0x09,0x08,0x0C。第三步进电机每走一步退半步原因是脉冲间隔太短电机还没完成机械响应就被下一步覆盖把节拍间隔延长到 3ms 以上并关闭编译器的最高优化等级。这几个问题在实物上也会出现只是原因可能叠加在驱动芯片压降上。5. 进阶加入OLED显示与远程报警以及工程验证技巧完成基础控制后可以向实际产品形态靠拢增加一块 I2C 接口的 0.96 寸 OLED 显示实时数据用按键切换显示页面再用 ESP8266 模块把异常状态报警文本推送到手机。这两个功能对代码结构的影响比想象中小核心是把状态数据封装成结构体供显示和串口共用。5.1 OLED 显示刷新策略OLED 写每个字符都需要通过 I2C 发送显存数据一屏全刷大约耗时 30ms如果放在主循环里频繁刷新会导致步进电机控制中断被推迟。常见做法是把显示更新频率限制在 5Hz并使用局部缓存变量只有数据变化超过阈值才触发刷新。初始化时用I2C_GenerateSTART加I2C_SendData发送控制字节0x3C连续写入初始化寄存器序列之后每次写入即显示不需要额外的显存维护逻辑。5.2 远程报警用USART透传AT指令STM32 通过全串口把报警信息发给 ESP8266ESP8266 设置为透明传输模式。建议把 AT 指令封装成底层函数void ESP8266_SendData(uint8_t *data, uint16_t len) { Usart_SendString(ATCIPSEND, 12); Usart_SendInt(len); Usart_SendString(\r\n, 2); DelayMs(20); Usart_SendBuffer(data, len); DelayMs(100); }这段代码先发送待传数据长度再等待模块返回提示符随后发送数据内容。值得强调的是不要把 TCP 协议栈跑在 STM32 上除非你有意研究 LwIP 移植。数据量小、低频率报警场景直接透明传输是最稳定的。仿真里若要验证这条链路可以省略 ESP8266把报警文本直接输出到虚拟终端逻辑判断正确后再接实物。5.3 实物移植前的验证清单仿真跑通不等于实物能跑差异最大的三处是时钟精度、电机负载和传感器电平。下图清单是我每次从仿真转到实物前的必测项验证项方法与判定标准DHT11 时序示波器抓数据线高电平宽度 26~28μs/70μs 对应 0/1USART 波特率回环测试TX 接 RX自发自收连续 100 字节无错步进电机温升连续运行 10 分钟ULN2003 表面温度不超过 60°C低功耗电流万用表串入电池正极STOP 模式小于 50μA唤醒后恢复正常声控灵敏度用手机播放 80dB 白噪音不误触发拍手声触发报警如果电机在实物上出现失步先测一下电源电压在启动瞬间是否从 5.0V 跌到 4.5V 以下再回头改 PWM 的 ARR 值和分频系数。本文还有配套的精品资源点击获取
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门