1. 项目缘起与整体设计思路1.1 为什么会想到做鸽子驯养系统养鸽子这件事外行看热闹内行看门道。我接触赛鸽和观赏鸽驯养差不多有六七年时间最开始全靠人工几点喂食、几点开笼、几点归巢登记全凭脑子记和手写本子。鸽子数量一多问题就来了——喂食时间不固定导致鸽子抢食打架环境温度波动大了幼鸽容易生病归巢时间靠人眼盯着根本记不准。尤其是做赛鸽训放的时候每一秒的归巢时间差都可能影响后续训练计划的调整。市面上确实有成品鸽舍环境监测设备但要么功能太单一只测温湿度要么价格贵得离谱而且没法按照自己的驯养逻辑去定制自动化流程。我本身就是做嵌入式开发的STM32手头一堆干脆自己搭一套。这个项目从最初画原理图到最终实物跑通前后断断续续花了将近三个月中间踩了不少坑也积累了一些在常规教程里看不到的经验。这套系统最终实现的功能包括定时自动投喂可设多个时段、鸽舍温湿度实时监测与超限报警、饮水槽水位检测、归巢入口红外计数、光照自动补光、以及通过串口屏做本地交互。所有数据可以通过USB虚拟串口上传到上位机做记录。整套硬件成本控制在两百元以内对于个人鸽舍来说非常实用。1.2 方案选型的几个关键决策主控选STM32F103C8T6这个没什么好纠结的。原因很简单第一价格便宜最小系统板十块钱出头第二资料多到泛滥任何一个外设都有现成的例程可以参考第三外设资源对于这个项目绰绰有余——我们需要至少3个定时器一个做系统时基、一个做PWM驱动蜂鸣器、一个做输入捕获测红外信号、2个USART一个接串口屏、一个做USB虚拟串口、多个GPIO做继电器和传感器接口。F103C8T6有3个通用定时器加1个高级定时器2个USART加2个SPI加2个I2C完全够用。这里要特别说一下很多人做STM32项目喜欢一上来就选F4或者H7系列觉得性能强。但对于这种控制类项目F103的72MHz主频处理这些任务绰绰有余而且F103的5V容忍IO在接一些5V传感器时省去了电平转换的麻烦。我实测下来整个系统跑起来CPU占用率不到15%用F4纯属浪费。投喂机构的设计我改了三次。最初想用舵机直接推料但舵机的扭矩不够饲料卡住就堵转。后来换成28BYJ-48步进电机加ULN2003驱动板扭矩够了但噪音大而且步进电机在堵转时发热严重。最终方案是用一个12V直流减速电机配合BTS7960半桥驱动模块通过一个偏心轮机构做振动下料。这个方案的好处是电机只在投喂的几秒钟内通电平时完全断电不发热偏心轮振动下料不容易卡料BTS7960模块自带过流保护堵转也不会烧。温湿度传感器选了SHT30而不是DHT11。DHT11便宜是便宜但精度太差湿度±5%RH温度±2℃而且响应慢在鸽舍这种湿度变化大的环境里读数经常跳。SHT30是I2C接口精度±2%RH和±0.3℃响应快而且有防水封装版本。虽然贵了几块钱但对于需要精确控制鸽舍环境的场景来说这个钱不能省。1.3 系统整体架构整个系统按功能划分为四个模块主控核心板、传感器采集模块、执行机构驱动模块、人机交互模块。主控核心板就是STM32最小系统包含复位电路、晶振电路、SWD调试接口和电源电路。传感器模块包括SHT30温湿度传感器、HC-SR04超声波水位检测、红外对管归巢计数。执行机构包括继电器控制的补光灯、BTS7960驱动的投喂电机、无源蜂鸣器报警。人机交互用了一块2.4寸的串口屏通过USART1通信。电源部分需要特别说明。整个系统用12V/2A的直流电源适配器供电然后通过LM2596降压模块降到5V给继电器和电机驱动供电再通过AMS1117-3.3降到3.3V给STM32和传感器供电。这里有个坑LM2596是buck电路开关频率150kHz如果布局不好会干扰SHT30的I2C通信。我的解决办法是在LM2596输出端加了一个π型LC滤波电路100μF电解电容10μH电感100nF陶瓷电容把开关纹波压到了10mV以内之后I2C通信再没出过问题。2. 核心电路设计与关键细节2.1 STM32最小系统板设计要点虽然可以直接买现成的最小系统板但为了把整个系统集成到一块PCB上我还是自己画了STM32的最小系统部分。核心电路包括8MHz无源晶振配合两个22pF负载电容构成HSE时钟源32.768kHz晶振配合两个12pF电容构成LSE时钟源用于RTC走时复位电路用10k上拉电阻加100nF电容构成经典的RC复位BOOT0通过10k电阻下拉到地BOOT1通过10k电阻下拉到地。这里重点说一下复位电路。很多人画STM32最小系统时复位电路就随便放一个10k电阻和100nF电容但实际调试时发现复位不可靠。问题出在RC时间常数上10k×100nF1ms这个时间对于STM32来说偏短。我实测下来把电容换成1μF时间常数变成10ms复位就非常稳定了。另外在复位按键两端并联一个0.1μF电容做防抖效果更好。晶振电路的布局非常关键。8MHz晶振和负载电容必须尽可能靠近STM32的OSC_IN和OSC_OUT引脚走线长度控制在10mm以内并且晶振下方要铺地铜皮做屏蔽。我第一版PCB没注意这个晶振走线绕了半个板子结果系统时不时起振失败。后来重新布局把晶振紧贴芯片放置问题彻底解决。SWD调试接口用了标准的4针排针3.3V、SWDIO、SWCLK、GND。这里有个细节SWDIO和SWCLK各串了一个100Ω电阻做阻抗匹配同时在靠近排针端各加了一个100pF电容到地做滤波。这个做法是从ST官方评估板上学来的可以有效抑制调试时的信号振铃提高ST-Link连接的稳定性。2.2 电源电路与抗干扰设计电源部分的设计直接决定了整个系统的稳定性。我的方案是12V输入经过一个SS34肖特基二极管做防反接保护然后进入LM2596-5.0降压到5V。LM2596的外围电路包括输入电容100μF/25V电解电容加100nF陶瓷电容输出电容220μF/16V电解电容加100nF陶瓷电容续流二极管用SS34电感用33μH/3A的功率电感。反馈电阻用两个精密电阻分压输出精确的5.0V。5V再经过AMS1117-3.3降到3.3V给STM32和传感器供电。AMS1117的输入输出各加一个10μF钽电容和一个100nF陶瓷电容。这里要注意AMS1117的压差是1.1V左右5V降到3.3V有1.7V压差在负载电流200mA时功耗约0.34WAMS1117的SOT-223封装加一小块铺铜散热就够了。抗干扰方面我在PCB布局上做了几个关键处理模拟地和数字地分开走最后在电源入口处单点连接每个IC的电源引脚旁边都放一个100nF去耦电容距离不超过5mm电机驱动部分和MCU部分在PCB上物理隔离中间用地线隔开所有对外接口传感器接口、电机接口都加了TVS二极管做浪涌保护。这些措施看起来繁琐但实际调试时省去了大量排查干扰问题的时间。2.3 传感器接口电路SHT30温湿度传感器通过I2C接口连接STM32的PB6SCL和PB7SDA。I2C总线上需要接4.7k上拉电阻到3.3V。这里有个坑SHT30的I2C地址是0x44ADDR引脚接地或0x45ADDR接VCC我第一版把ADDR悬空了结果通信时好时坏。后来查数据手册才发现ADDR引脚不能悬空必须明确接高或接低。改成接地后通信稳定。HC-SR04超声波模块用来检测饮水槽水位。模块的Trig引脚接STM32的PA0Echo引脚接PA1。Echo引脚输出的是5V电平而STM32的IO是3.3V虽然F103的IO有5V容忍但为了保险起见我在Echo线上串了一个1k电阻再加一个3.3V稳压二极管做钳位。实测这个做法比直接用电平转换芯片更简单可靠。红外对管用于归巢计数安装在归巢入口两侧。红外发射管通过一个220Ω限流电阻接5V接收管集电极接3.3V发射极通过一个10k电阻接地发射极电压信号送到STM32的PA2。当鸽子通过时遮挡红外光接收管截止PA2电压从低变高触发外部中断计数。这里要注意红外对管的安装间距太近容易受环境光干扰太远灵敏度不够。我实测间距在3cm左右比较合适同时接收管要加黑色热缩管做遮光处理。2.4 执行机构驱动电路投喂电机用的是12V直流减速电机额定电流0.6A堵转电流2A。驱动方案选了BTS7960半桥驱动模块这个模块内部集成了两个半桥可以驱动一个直流电机做正反转。模块的使能引脚和方向引脚分别接STM32的PB0和PB1PWM调速引脚接PB2TIM3_CH3。BTS7960的逻辑供电是5V功率供电是12V逻辑地和功率地在模块内部是隔离的接线时要注意共地。补光灯用继电器控制。继电器选了松乐SRD-05VDC-SL-C线圈额定电压5V触点容量10A/250VAC。驱动电路用了一个S8050三极管做开关基极通过1k电阻接STM32的PB3集电极接继电器线圈发射极接地。继电器线圈两端并联了一个1N4148续流二极管防止断电时线圈产生的反向电动势击穿三极管。这个续流二极管绝对不能省我第一版忘了加结果三极管烧了好几个。无源蜂鸣器用于报警提示。驱动电路用了一个S8550三极管做开关基极通过1k电阻接STM32的PB4发射极接3.3V集电极接蜂鸣器正极蜂鸣器负极接地。蜂鸣器两端并联了一个1k电阻做阻尼可以改善音质。PWM信号通过TIM3_CH1输出频率设置在2kHz左右这个频率下蜂鸣器声音最响亮。3. 软件架构与核心代码实现3.1 系统时钟配置与定时器规划STM32F103的时钟树配置是整个软件的基础。我的配置是HSE 8MHz经过PLL 9倍频到72MHz作为SYSCLKAHB不分频APB1二分频到36MHzAPB2不分频到72MHz。这样配置的原因是APB1上的定时器TIM2、TIM3、TIM4时钟是72MHz因为APB1预分频系数不为1时定时器时钟是APB1时钟的2倍APB2上的外设USART1、SPI1直接跑72MHz。定时器分配如下TIM1作为系统时基配置为1ms中断一次用于任务调度和软件延时TIM2配置为输入捕获模式用于测量红外信号的脉冲宽度TIM3_CH1输出PWM驱动蜂鸣器TIM3_CH3输出PWM驱动电机调速TIM4配置为编码器接口模式预留后续扩展用。这里重点说一下TIM1的配置。系统时基用1ms中断中断服务函数里维护一个全局的tick计数器。所有需要定时执行的任务都基于这个tick做时间片轮询而不是用delay函数阻塞。我见过很多初学者在中断里用delay结果整个系统时序全乱。正确的做法是中断里只做标志位设置和计数器递增具体任务在主循环里根据标志位执行。3.2 温湿度采集与I2C通信SHT30的驱动我写了一个简单的状态机。SHT30的测量命令是0x2C06高重复性测量发送命令后需要等待15ms才能读取结果。读取的6个字节分别是温度高8位、温度低8位、温度CRC、湿度高8位、湿度低8位、湿度CRC。温度换算公式是T -45 175 × (raw / 65535)湿度换算公式是RH 100 × (raw / 65535)。I2C通信我用的是软件模拟I2C而不是硬件I2C。原因很简单STM32F103的硬件I2C有已知的errata在某些情况下会死锁虽然可以通过各种workaround解决但软件模拟I2C更简单可靠而且速率要求不高SHT30最大1MHz我跑100kHz绰绰有余。软件I2C的引脚定义SCL接PB6SDA接PB7都配置为开漏输出模式外部接4.7k上拉电阻。这里分享一个调试技巧如果I2C通信失败先用逻辑分析仪抓波形看SCL和SDA的时序是否正确。常见问题包括上拉电阻太大导致上升沿太慢、从机地址错误、ACK位没有正确释放SDA线。我遇到过一次SHT30不响应的情况查了半天发现是PCB上SDA和SCL走线太近产生了串扰后来在两根线之间加了一根地线隔离就好了。3.3 电机驱动与PWM调速投喂电机的控制逻辑是收到投喂指令后电机正转3秒下料停1秒再反转1秒复位偏心轮然后停止。PWM频率设置在20kHz这个频率高于人耳听觉范围电机运行时的啸叫声最小。PWM占空比在正转时设为80%反转时设为60%这样既有足够的扭矩又不会因为全速运行导致饲料飞溅。BTS7960的控制逻辑使能引脚拉高使能模块方向引脚控制正反转PWM引脚控制速度。注意BTS7960的使能引脚是低电平有效还是高电平有效取决于具体模块我用的这个模块是高电平使能。另外BTS7960在电机停止时如果使能引脚仍然拉高模块会进入刹车状态而不是滑行状态这个特性在需要快速停止的场合很有用。电机驱动部分的代码要注意死区时间。虽然BTS7960内部有死区控制但在方向切换时最好还是加一个短暂的延时我用了10ms等电机完全停止后再切换方向避免瞬间反向电流过大触发过流保护。3.4 串口屏交互与USB虚拟串口串口屏用的是大彩的2.4寸屏通过USART1通信波特率115200。屏幕的界面包括主界面显示温湿度和归巢计数设置界面可以调整投喂时间和报警阈值。串口屏的通信协议是简单的帧格式帧头0xEE、指令、数据长度、数据、校验和、帧尾0xFF。我写了一个发送函数和一个接收解析状态机接收用USART1的接收中断加环形缓冲区实现。USB虚拟串口用的是STM32F103自带的USB外设配置为CDC类设备。需要在STM32CubeMX里使能USB外设并选择CDC模式然后生成代码。USB虚拟串口的发送函数是CDC_Transmit_FS()接收用CDC_Receive_FS()回调。这里要注意USB虚拟串口的发送是阻塞的如果上位机没有打开串口发送函数会一直等待。我的解决办法是在发送前检查USB连接状态如果未连接就跳过发送。USB虚拟串口的数据格式我定义了一个简单的协议每帧以0xAA 0x55开头然后是温度2字节、湿度2字节、归巢计数2字节、水位状态1字节、校验和1字节。上位机用Python写了一个简单的解析脚本用pyserial库读取数据并存入CSV文件方便后续分析。4. 实操调试与常见问题排查4.1 硬件调试步骤与工具使用硬件调试我遵循“先电源后信号、先静态后动态”的原则。第一步不焊MCU只焊电源部分上电测量各路电压是否正常。5V输出应该在4.9V到5.1V之间3.3V输出应该在3.2V到3.4V之间。如果电压不对先检查反馈电阻是否焊接正确、电感是否虚焊。第二步焊上MCU和晶振用ST-Link Utility连接芯片看能否识别到设备。如果识别不到检查SWD接口接线是否正确、BOOT0是否接地、复位电路是否正常。我遇到过一次ST-Link识别不到芯片的情况查了半天发现是SWDIO和SWCLK接反了调换后正常。第三步烧录一个最简单的LED闪烁程序确认MCU能正常运行。然后用示波器测量晶振引脚看是否有8MHz的正弦波。如果没有起振检查负载电容是否匹配、晶振是否损坏。第四步逐个焊接传感器模块每焊一个就写一段测试代码验证功能。不要一次性全部焊完再调试那样出了问题很难定位。4.2 常见问题速查表问题现象可能原因排查方法解决方案ST-Link无法识别芯片SWD接线错误、BOOT0未接地、芯片未供电万用表测3.3V和GND之间电压检查接线、确认BOOT0接地、测量供电晶振不起振负载电容不匹配、晶振损坏、走线太长示波器测OSC引脚波形更换负载电容、缩短走线、更换晶振I2C通信失败上拉电阻缺失、地址错误、时序不对逻辑分析仪抓波形加4.7k上拉、确认从机地址、调整时序电机不转驱动模块使能引脚未拉高、PWM占空比为0万用表测电机两端电压检查使能引脚、确认PWM输出蜂鸣器不响三极管极性接反、PWM频率不对示波器测三极管基极波形更换三极管、调整PWM频率到2kHz串口屏无显示波特率不匹配、接线错误示波器测TX引脚波形确认波特率115200、TX和RX交叉连接USB虚拟串口识别不到USB DP上拉电阻缺失、驱动未安装设备管理器查看加1.5k上拉电阻到3.3V、安装STM32虚拟串口驱动系统复位频繁电源纹波太大、看门狗误触发示波器测3.3V纹波加大滤波电容、调整看门狗溢出时间4.3 抗干扰与稳定性优化经验系统联调阶段遇到的最头疼的问题是电机启动时STM32会复位。用示波器抓3.3V电源纹波发现电机启动瞬间3.3V上出现了高达500mV的尖峰。原因是电机启动电流大导致12V电源电压瞬间跌落进而影响5V和3.3V输出。解决办法分三步第一在12V输入端并联一个1000μF/25V的大电解电容提供瞬态电流缓冲第二在电机两端并联一个100nF陶瓷电容和一个100Ω电阻串联的RC吸收电路抑制电机换向时产生的尖峰第三在软件上让电机启动时先以20%占空比运行200ms做预励磁然后再升到80%避免直接全速启动。这三招下去电机启动时电源纹波降到了50mV以内复位问题彻底解决。另一个问题是红外计数误触发。鸽子通过时计数正常但有时候没有鸽子经过也会计数。排查发现是阳光直射到接收管上导致的。解决办法给接收管套上黑色热缩管只留一个3mm的小孔让红外光通过同时在软件上加了一个50ms的消抖延时只有红外信号持续低电平超过50ms才计数。这两个措施加上后误触发率降到了零。4.4 低功耗与看门狗配置虽然这个系统是市电供电不存在电池续航问题但看门狗还是必须开的。我配置的是独立看门狗IWDG时钟源是LSI约40kHz预分频系数64重装载值625溢出时间约1秒。主循环里每500ms喂一次狗如果程序跑飞超过1秒没有喂狗系统自动复位。这里有个细节IWDG一旦启动就无法关闭调试时如果程序停在断点超过1秒看门狗就会复位。解决办法是在调试时先不启动看门狗等程序调试稳定后再使能。或者在调试时把重装载值设大一些比如4095溢出时间约6.5秒给调试留出足够时间。低功耗方面如果后续要加电池供电可以把系统配置为睡眠模式主循环里如果没有任务就调用__WFI()指令进入睡眠由定时器中断唤醒。实测这样可以把运行电流从45mA降到12mA左右。不过对于市电供电的场景这个优化不是必须的。5. 驯养逻辑与自动化策略5.1 投喂策略的设计与调整投喂策略直接关系到鸽子的健康和驯养效果。我设计的投喂逻辑是每天固定三个时段投喂早上7点、中午12点、下午5点每个时段投喂量通过串口屏设置以电机运行时间计1秒约出料15克。这个策略是基于鸽子消化周期制定的鸽子进食后约4-6小时消化完毕三个时段间隔5小时左右符合鸽子的自然进食节律。但实际使用中发现一个问题夏天鸽子的食欲下降固定投喂量会导致饲料剩余发霉。后来我加了一个逻辑如果SHT30检测到温度超过30℃投喂量自动减少20%。这个调整通过软件实现在投喂函数里根据温度值动态调整电机运行时间。另一个经验是投喂时间不要设得太死。我最初设的是精确到分钟结果发现鸽子会在投喂前就聚集在料槽旁等待形成条件反射后反而增加了打斗。后来改成投喂时间在设定值前后随机浮动5分钟鸽子的焦虑行为明显减少。5.2 环境监测与报警阈值设定温湿度监测的报警阈值我设的是温度低于5℃或高于35℃报警湿度高于85%RH报警。这两个阈值是根据鸽子的生理耐受范围定的。鸽子适宜温度是10-30℃低于5℃容易感冒高于35℃容易中暑。湿度高于85%时鸽舍内容易滋生霉菌对鸽子呼吸道有害。报警方式分两级一级报警是蜂鸣器间歇鸣叫响1秒停2秒同时串口屏上对应数值变红二级报警是蜂鸣器持续鸣叫同时通过USB虚拟串口向上位机发送报警信息。一级报警用于温湿度轻微超限二级报警用于严重超限比如温度超过40℃。这里有个细节报警阈值要有回差。比如温度报警阈值是35℃如果设成35℃报警、34.9℃解除那温度在35℃附近波动时蜂鸣器会频繁启停。我的做法是设5℃回差35℃报警降到30℃才解除报警。湿度设10%RH回差。这个做法在工业控制里叫滞环控制可以避免执行机构频繁动作。5.3 归巢训练数据记录与分析归巢计数功能对于赛鸽训练特别有用。红外对管安装在归巢入口每有一只鸽子通过就计数一次同时记录通过时间。数据通过USB虚拟串口上传到上位机Python脚本把数据存入CSV文件格式是时间戳、温度、湿度、归巢计数。训练时我会把鸽子拉到不同距离放飞记录每只鸽子的归巢时间。通过分析这些数据可以判断哪些鸽子归巢能力强、哪些需要加强训练。比如有只鸽子在50公里训放时归巢时间比平均慢了20分钟后来发现是配对后恋巢性下降调整配对后成绩明显提升。这个数据分析功能是我最初没想到的后来在实际使用中才发现它的价值。现在我的鸽舍里每只鸽子都有独立的训练档案这在以前靠手写记录的时代是不可想象的。5.4 系统扩展与后续升级方向这套系统目前跑得很稳定但还有几个可以扩展的方向。第一个是加WiFi模块做远程监控用ESP8266通过串口和STM32通信把数据上传到云平台手机就能随时查看鸽舍状态。第二个是加摄像头做归巢抓拍用OV7670摄像头模块当红外计数触发时拍一张照片存到SD卡可以记录归巢瞬间的状态。第三个是加自动饮水系统用电磁阀控制饮水槽的进水和排水保持水质新鲜。不过这些扩展都要在现有系统稳定运行的基础上做。我的原则是先把核心功能做扎实再考虑锦上添花。很多初学者一上来就想做全功能结果每个功能都半吊子最后整个系统跑不起来。嵌入式开发最忌讳贪多嚼不烂。6. 个人实操心得与避坑建议6.1 元器件选型的几个原则第一不要贪便宜买拆机件。我最初为了省钱买了一批拆机的STM32芯片结果十片里有三片是坏的还有两片USB外设有问题。后来全部换成全新原装虽然贵了一倍但再没出过问题。拆机件的隐性成本太高排查故障的时间成本远超省下的那点钱。第二电容要选对类型。电解电容用于大容量滤波陶瓷电容用于高频去耦钽电容用于中等容量且要求低ESR的场合。我见过有人用陶瓷电容做电源滤波结果容量不够导致纹波大。也见过有人用钽电容做高频去耦结果ESR太高效果差。每种电容有它的适用场景不能混用。第三接插件要选质量好的。XH2.54接插件比杜邦线可靠得多尤其是电机和电源这种大电流场合。杜邦线接触电阻大电流稍大就会发热时间长了还会氧化导致接触不良。我现在的原则是凡是需要反复插拔或者电流超过500mA的接口一律用XH2.54或VH3.96接插件。6.2 PCB布局布线的经验教训第一版PCB我犯了一个经典错误把晶振放在了板子边缘而且走线绕了很远。结果系统时不时起振失败。第二版我把晶振紧贴MCU放置走线长度控制在8mm以内并且在晶振下方铺了完整的地铜皮问题解决。另一个教训是电机驱动部分的布局。第一版我把BTS7960和MCU放在同一块铺铜区域结果电机启动时MCU频繁复位。第二版我把电机驱动部分单独划了一块区域和MCU区域之间用2mm宽的地线隔开并且在电机驱动区域的电源入口加了LC滤波。这个改动效果立竿见影。还有一点丝印要清晰。我第一版PCB的丝印太小焊接时根本看不清元件标号导致焊错了好几个电阻。第二版把丝印字号加大到1mm并且每个元件都标了极性和参数焊接效率提高了一倍。6.3 软件调试的实用技巧第一个技巧用SWO输出调试信息。STM32的SWO引脚可以输出printf信息不需要占用串口。在Keil里配置好ITM端口后用Debug Viewer就能看到打印信息。这个功能在调试时序问题时特别有用因为SWO输出不影响程序运行。第二个技巧用GPIO翻转做时间测量。在关键代码段的开头和结尾各翻转一个GPIO然后用示波器测量脉冲宽度就能精确知道这段代码的执行时间。这个方法比用定时器计时更直观而且不需要修改代码逻辑。第三个技巧看门狗调试时先禁用。前面提过IWDG一旦启动就无法关闭调试时程序停在断点会被复位。我的做法是在调试阶段用条件编译把看门狗初始化代码屏蔽掉等程序稳定后再打开。第四个技巧串口屏的通信协议要加超时重传。串口屏偶尔会因为干扰丢帧如果发送后不检查应答界面就会卡住。我的做法是发送指令后等待100ms如果没有收到应答就重发重发三次仍失败就报错。这个机制加上后串口屏再没出现过卡死。6.4 关于成本控制的一些实话这套系统最终物料成本大约180元其中STM32最小系统板12元、SHT30传感器15元、串口屏45元、BTS7960模块18元、继电器模块8元、电源适配器15元、PCB打样10元5片、其他元器件和接插件约57元。如果批量做的话成本可以压到120元左右。但我要说的是不要为了省钱而牺牲可靠性。比如SHT30比DHT11贵了10块钱但省去了大量调试时间。BTS7960比L298N贵了8块钱但发热小、效率高、自带保护。这些钱花得值。嵌入式项目最大的成本是时间不是元器件。另外PCB打样现在很便宜5片10×10cm的板子只要10块钱。但要注意打样前一定要仔细检查原理图和PCB我第一版因为一个电阻封装画错导致整批板子报废白白浪费了一周时间。现在我的习惯是发板前把原理图和PCB打印出来用红笔逐个核对元件封装和网络连接确认无误再发。6.5 给初学者的入门建议如果你刚接触STM32想复现这个项目我的建议是分阶段进行。第一阶段先点亮一个LED把GPIO输出搞明白。第二阶段用定时器做一个呼吸灯把PWM搞明白。第三阶段用串口打印温湿度数据把UART和I2C搞明白。第四阶段加继电器控制把GPIO输入输出和中断搞明白。第五阶段把所有模块整合起来做完整的系统联调。每个阶段都要自己动手写代码不要直接抄例程。抄来的代码能跑但你不知道为什么能跑。自己写的代码哪怕有bug调试的过程就是学习的过程。我见过太多人直接拿现成的工程来用结果出了问题完全不知道从哪里下手排查。最后说一句嵌入式开发没有捷径就是多动手、多踩坑、多总结。我做了这么多年现在遇到新问题也还是要查数据手册、抓波形、一步步排查。但这个过程中积累的经验是看多少教程都换不来的。
