ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

STM32智能输液监控系统:滴速检测与闭环控制实战

STM32智能输液监控系统:滴速检测与闭环控制实战 1. 项目整体设计与方案拆解智能医疗输液点滴系统这几年在嵌入式毕设和医疗电子项目里一直很火。原因不复杂传统输液全靠护士人工盯梢病床一多就容易顾此失彼滴速快了慢了、液体空了都没人及时发现。这个项目的核心思路就是让单片机替人“盯梢”——用传感器检测每一滴药液的滴落时刻计算出实时滴速再根据预设范围自动调速、报警、上报信息把输液这件事从“人工巡检”变成“智能监控”。先说我拿到这个项目时的第一反应它非常适合作为STM32的综合性练手项目因为它的技术栈覆盖很全——GPIO操作、外部中断、定时器输入捕获、PWM输出、串口通信、I2C/SPI驱动外设、PID闭环控制基本把STM32F103系列的主流外设都过了一遍。你做完这个项目再回头去看那些零零散散的单点例程会觉得整个知识体系一下子串起来了。再聊方案选型。整个系统的核心链路大概是这样的液滴传感器负责“感知”STM32作为“大脑”负责计算和控制步进电机驱动的蠕动泵负责“执行”OLED或LCD屏幕负责“显示”再加上按键输入、蜂鸣器/无线模块报警组成一个完整闭环。这里最需要斟酌的是检测方案和调速方案各有两个典型路线可以走。液滴检测方案对比方案原理优点缺点红外对管对射式液滴滴落瞬间遮挡红外光束接收端电平跳变结构简单、成本极低、响应快对安装位置敏感易受环境光干扰电容式/压电式检测液滴接触传感器产生电容变化或微小形变抗干扰强、精度高成本较高、与液体接触存在卫生问题红外反射式红外发射管照射滴壶接收反射光强度变化非接触、安装灵活信号较弱需要精密放大电路我最终选择了红外对管对射式。原因很直接医疗项目讲卫生隔离接触式方案再准也不适合实际场景而反射式的信号调理电路对新手不太友好对射式则可以直接通过比较器整形输出标准方波几块钱就能搞定稳定性也足够。调速方案对比方案原理优点缺点夹紧式调节器步进电机推动滚轮压紧/放松输液管结构直观、成本低力度控制不好容易压断管路安全性一般蠕动泵步进电机驱动滚轮挤压软管靠蠕动推进液体流速稳定、不接触药液、卫生安全对软管材质有要求结构略复杂做过实物的朋友应该都有同感蠕动泵方案才是医疗场景的正确打开方式。它跟药液完全不接触只挤压管路外壁既卫生又能精确控制流量。配合步进电机每转一圈的输液量是固定的只要控制转速就能控制滴速非常适合闭环控制。整体设计思路理清之后项目的开发流程也就清晰了先画硬件原理图再搭建最小系统板验证传感器和电机驱动接着写底层驱动和外设逻辑然后调通核心的滴速检测算法最后做闭环控制和上位机联动。下面逐个环节拆开讲。2. 硬件原理图设计与关键器件选型这个项目的原理图说难不难说简单也不算简单主要是外围模块比较多。但拆开看其实就三大块最小系统电路、传感器信号调理电路、执行机构驱动电路。只要把这三块搞定剩下就是接线和布局的功夫。2.1 主控选型为什么是STM32F103C8T6主控我用的是STM32F103C8T6也就是大家常说的“蓝丸”核心板用的那颗芯片。选它有几个原因一是价格便宜几块钱一片打样做板子也不心疼二是资源够用——64KB Flash、20KB RAM跑这个项目绰绰有余三是网上资料极其丰富不管是寄存器版还是HAL库版出了任何问题都能搜到解决方案对新手极其友好。F103C8T6的关键资源分配我这样规划功能模块使用的引脚/外设说明液滴传感器信号PA0外部中断EXTI0液滴触发下降沿中断步进电机驱动PA1-PA4GPIO输出四拍/八拍控制信号OLED显示PB8-PB9I2C1显示滴速、累计量、报警状态按键输入PB0-PB3设置/加/减/确认蜂鸣器报警PB4低电平触发无线上报预留PA9-PA10USART1预留ESP8266/SIM800接口或TTL串口需要提醒一句PB2、PB3、PB4这几个引脚在F103上默认是复用功能BOOT1、JTDO、NJTRST用作普通GPIO之前要先在代码里配置AFIO关闭调试端口。这个坑我在第一次打板时踩过后面会细说。2.2 液滴传感器红外对管与比较器整形传感器部分是整个硬件设计的核心。红外对管我用的是直径3mm的发射管和接收管理由很简单——体积小好安装。发射管串一个限流电阻100-220Ω左右实测取150Ω比较合适接收管光敏三极管接成“集电极上拉、发射极接地”的形式这样接收管导通时输出低电平遮挡时输出高电平。但有个现实问题接收管输出的模拟量变化幅度并不大直接进单片机引脚判断容易误触发。所以中间加一级比较器整形是必须的我用的是LM393双电压比较器电路是这样的红外接收管输出 → 比较器同相输入端3脚 参考电压电位器分压 → 比较器反相输入端2脚 比较器输出1脚 → 上拉10K电阻 → 接STM32 PA0电位器用来调节触发电平在哪些环节最有用我强烈建议在硬件调试时把它引出来——每一批次的红外对管参数都有离散性而且滴壶的壁厚、颜色也不一样没有这个旋钮你后面调灵敏度就得天天改代码。这是那些“看似多余、实则救命”的设计之一。比较器输出还要加一个100nF的滤波电容到地滤掉高频毛刺避免单片机的EXTI被反复触发。这个电容不加你会看到滴速数值在那边乱跳以为是自己算法写得有问题其实是硬件在捣鬼。2.3 步进电机驱动ULN2003还是A4988蠕动泵配的电机我用的是28BYJ-48步进电机48步/转自带减速箱力矩足够挤压输液管。驱动芯片方面ULN2003是经典之选达林顿管阵列专门驱动这种小电流步进电机一根直插芯片加几个引脚就搞定价格不到一块钱。ULN2003内部每个通道就是一个达林顿管输入高电平时输出低电平把电机的公共端通常是红色线接VCC5V四个相线接ULN2003的输出端。工作时给四相线圈按顺序导通电机就能一步一步转。接线图很简单STM32 PA1 → ULN2003 IN1 → 电机蓝线A相 STM32 PA2 → ULN2003 IN2 → 电机粉线B相 STM32 PA3 → ULN2003 IN3 → 电机黄线C相 STM32 PA4 → ULN2003 IN4 → 电机橙线D相 电机红线 → 5V用ULN2003的好处是接口简单、不怕烧芯片缺点是比较“肉”——驱动电流有限电机转速上不去。如果后续你想换更大扭矩的蠕动泵可以考虑用A4988但那个需要搭配细分设置和电流调节硬件复杂度会上去不少。对于这个项目ULN2003完全够用。2.4 其他外围电路的设计要点显示模块我用的是0.96寸I2C接口OLEDSSD1306驱动芯片。选I2C版本纯粹是省引脚F103的硬件I2C虽然网上吐槽多但用HAL库调通问题不大实在不行也可以用软件模拟I2C稳定得很。电源电路这块容易被忽略但它恰恰是硬件的灵魂。整个系统有5V电机、传感器和3.3V单片机、OLED两个电压轨我用了AMS1117-3.3做线性降压同时在电源输入端并联了100μF电解电容和100nF陶瓷电容去耦。特别注意电机启动瞬间电流会波动必须在电机电源引脚旁边单独加一个100μF的电容做“动力储能”否则电机会把主控的电压拉垮导致单片机莫名其妙复位。这是我在调试中真实遇到过的“灵异事件”后来加电容才解决。3. 嵌入式软件架构与滴速检测算法硬件是骨架软件才是灵魂。这个项目的代码结构我建议按模块化来组织不然后期调PID、加功能的时候会痛不欲生。我当时的文件结构是这样的User/ ├── main.c # 主循环 ├── sys_init.c # 时钟、GPIO、外设初始化 ├── liquid_detect.c # 液滴检测与滴速计算 ├── motor_control.c # 步进电机驱动 ├── pid_control.c # 闭环调速 ├── oled_display.c # OLED显示 ├── key_scan.c # 按键扫描 ├── alarm.c # 报警管理 └── usart_report.c # 串口/无线数据上报这样拆的好处是每个模块只干一件事出了问题能快速定位。下面重点讲两个核心模块的实现思路。3.1 滴速检测外部中断 定时器时间戳滴速检测的原理一句话就能说清在液滴滴落的瞬间记录当前时间然后用前后两次滴落的时间差算出瞬时滴速。但真要写好还是有不少讲究的。我采用外部中断定时器时间戳的方式。STM32的TIM2配置为1ms向上计数溢出中断里对溢出次数计数这样就能得到一个32位的毫秒级时间戳。液滴触发PA0的外部中断时在中断回调函数里读取当前时间戳两次时间戳相减就是滴落间隔。有了滴落间隔interval_ms瞬时滴速就是滴速(滴/分钟) 60000 / interval_ms举个例子如果两次液滴滴落的间隔是1000ms那滴速就是60滴/分钟正好是临床上常说的“一分钟60滴”。这个算法看起来简单但实际运行中会碰到几个问题需要加保护逻辑。问题一偶发漏检或误检。如果某次滴落没被检测到传感器位置偏了、气泡挡住光路间隔直接翻倍计算出的滴速会瞬间掉一半。解决思路是用窗口平均法——不是用前后两滴的间隔算瞬时速度而是统计最近N滴比如取10滴的时间跨度然后用(N-1)*60000 / (T_last - T_first)计算平均滴速。这样就平滑多了。问题二输液刚开始或结束时的异常间隔。液滴刚启动时不均匀间隔忽大忽小拔针后传感器又检测不到滴落。我的做法是加一个“有效间隔过滤”——间隔大于3秒或小于100ms的数据直接丢弃不参与计算。这样既避免了误报也不会在停顿时算出荒唐的速度。// 滴速计算核心代码简化版 #define WINDOW_SIZE 10 #define VALID_MIN_MS 100 #define VALID_MAX_MS 3000 uint32_t drop_timestamp[WINDOW_SIZE]; uint8_t drop_index 0; uint8_t drop_count 0; void EXTI0_IRQHandler(void) { if (EXTI_GetITStatus(EXTI_Line0) ! RESET) { // 读取当前毫秒时间戳 uint32_t now get_tick_ms(); uint32_t interval now - drop_timestamp[(drop_index - 1 WINDOW_SIZE) % WINDOW_SIZE]; // 有效间隔过滤 if (interval VALID_MIN_MS interval VALID_MAX_MS) { drop_timestamp[drop_index] now; drop_index (drop_index 1) % WINDOW_SIZE; if (drop_count WINDOW_SIZE) drop_count; } EXTI_ClearITPendingBit(EXTI_Line0); } } float calc_speed(void) { if (drop_count 2) return 0; uint8_t idx (drop_index - 1 WINDOW_SIZE) % WINDOW_SIZE; uint32_t elapsed drop_timestamp[idx] - drop_timestamp[(idx - drop_count 1 WINDOW_SIZE) % WINDOW_SIZE]; float avg_speed (float)(drop_count - 1) * 60000.0f / (float)elapsed; return avg_speed; }这段代码的边界条件处理比较绕特别是环形缓冲区的索引计算建议自己画个图捋一遍理解了以后写其他循环队列类型的算法都会顺手很多。3.2 步进电机调速PWM脉冲控制与细分驱动28BYJ-48步进电机的控制常见有两种方式一种是直接GPIO翻转实现四拍或八拍时序另一种是生成PWM脉冲控制电机速度。四拍时序就是按A-B-C-D顺序给四相绕组通电八拍时序则是A-AB-B-BC-C-CD-D-DA八拍的优点是步距角更小、电机运行更平滑缺点是频率需要更高。实际项目中我用的是八拍时序步距角大约0.0875度配合出厂减速比64换算下来步进电机转一圈大约需要4096个脉冲。这里有一个关键问题蠕动泵的转速由PWM频率决定而PWM频率又直接影响电机每一步的间隔所以脉冲频率和滴速之间是有一个近似线性关系的。我的做法是在代码里把目标滴速映射到PWM频率上先做开环粗调再用PID闭环修正。// 八拍时序表 const uint8_t motor_phase[8] { 0x01, 0x03, 0x02, 0x06, 0x04, 0x0C, 0x08, 0x09 }; // 对应 PA1-PA4 输出 void motor_step(uint8_t step) { GPIO_WriteBit(GPIOA, GPIO_Pin_1, (step 0x01) ? Bit_SET : Bit_RESET); GPIO_WriteBit(GPIOA, GPIO_Pin_2, (step 0x02) ? Bit_SET : Bit_RESET); GPIO_WriteBit(GPIOA, GPIO_Pin_3, (step 0x04) ? Bit_SET : Bit_RESET); GPIO_WriteBit(GPIOA, GPIO_Pin_4, (step 0x08) ? Bit_SET : Bit_RESET); } // 使用TIM3的PWM输出中断来驱动步进 void TIM3_IRQHandler(void) { if (TIM_GetITStatus(TIM3, TIM_IT_Update) ! RESET) { step_index (step_index 1) % 8; motor_step(motor_phase[step_index]); TIM_ClearITPendingBit(TIM3, TIM_IT_Update); } }3.3 PID闭环控制让滴速稳定在设定值光靠开环映射还不够——输液管的安装松紧、药液的高度差、滴壶内的压力变化都会导致同样的电机转速产生不同的实际滴速。所以我在系统中加了一个增量式PID控制器传感器测得的实时滴速作为反馈设定值由用户通过按键设定输出量用来调整PWM的频率。增量式PID的核心思想是只计算当前时刻相对于上一时刻的控制量增量而不是直接给绝对值好处是输出稳定、不容易产生大的系统冲击。公式是这样的E(k) 设定滴速 - 当前滴速 P Kp * [E(k) - E(k-1)] I Ki * E(k) D Kd * [E(k) - 2*E(k-1) E(k-2)] 输出增量 P I D 新的PWM频率 原来的PWM频率 输出增量参数整定方面我建议先用纯比例调试把Ki和Kd设为0从Kp0.5开始观察滴速的响应曲线如果出现振荡就减小如果响应太慢就加大。比例先稳定之后再加一点积分消除静差微分项在滴速这种惯性系统里用的很少一般Kd设0都能跑得很好。有一点务必注意PID输出的PWM频率必须做限幅防止电机转速突变导致蠕动泵损坏或者管子挤压过度。我在代码里设定的频率范围是200Hz-2000Hz低于200Hz直接停机高于2000Hz就封顶。这个限幅既是对硬件的保护也是输液安全的基本保障。3.4 报警与看门狗机制输液项目毕竟是医疗相关安全机制不能少。我设计了三级报警报警等级触发条件动作提示滴速偏差超过设定值10%屏幕闪烁提示警告滴速偏差超过设定值30%蜂鸣器间歇鸣叫紧急传感器超过8秒未检测到滴落蜂鸣器连续鸣叫电机停转看门狗也是必须要加的。我用的是STM32内部的独立看门狗IWDG主循环每500ms喂一次狗如果程序死循环或者跑飞看门狗能在1秒左右强制复位系统。别小看这个功能在实际长时间运行测试中它救过我至少三次。4. 仿真环境搭建Proteus与STM32CubeMX的配合说完了硬件和软件再聊聊仿真。很多同学拿到这种项目第一时间就问“能不能先仿真跑起来再做实物” 答案是肯定的——用Proteus仿真这个系统不仅完全可行而且能在打板之前就把逻辑验证个七七八八。但仿真的方法有讲究不是把原理图画一遍然后点运行那么简单。4.1 Proteus仿真搭建步骤我用的是Proteus 8 Professional版本搭配STM32F103C8T6模型。Proteus对STM32的支持没有AVR那么成熟所以有几个细节要特别注意。第一步建立原理图并放置元件。元件库中找到STM32F103C8T6、LM393、ULN2003、28BYJ-48有的版本叫MOTOR-STEPPER、LED、电阻、电容这些元件。Proteus的元件库搜索有点陈旧建议直接搜型号前几位然后用方向键调整方向放好。第二步配置STM32的时钟与调试接口。这是仿真中最容易出问题的一环。双击STM32芯片在“Program File”里加载你编译好的hex文件然后在“Clock Frequency”里填72000000也就是72MHz。如果你不填这个时钟仿真时外设时序会乱七八糟定时器算出来的延时全都对不上。第三步搭建液滴传感器模拟电路。Proteus里没有现成的“滴液传感器”元件我用的替代方案是一个按钮开关操作时手动点击模拟液滴滴落或者用一个脉冲发生器定时输出脉冲信号来表示液滴触发。后者的好处是能模拟一个稳定的滴速输入调试PID时特别方便。设置脉冲发生器的频率为1Hz就相当于每秒滴一滴也就是60滴/分钟的滴速。这样你就可以在仿真里观察到滴速显示是否稳定在预期值附近。第四步观察与调试。仿真跑起来后通过OLED模型观察显示内容调节电位器模拟传感器阈值变化观察电机模型的转动情况。Proteus的OLED模型支持I2C通信能直接显示实时数据这已经是比较理想的效果。4.2 仿真的局限与注意事项说实话Proteus仿真这个项目算法验证的用途大于硬件验证的用途。有些东西它是模拟不了的红外对管的实际光路变化、步进电机的带载特性、电源纹波对逻辑电路的影响、真实液体的滴落规律——这些只能在实物上测。所以我的建议是仿真用来跑通逻辑、验证PID参数的范围、检查状态机跳转是否正确但千万不要以为仿真没问题实物就一定能跑。另外一个容易踩的坑Proteus里的STM32外设模型对HAL库的支持有好有坏。如果你用HAL库写的代码在仿真里死活跑不起来可以先试试用标准外设库重新编译一版很多时候问题就出在CubeMX生成的初始化代码里有些寄存器的配置与Proteus模型不完全兼容。我自己的经验是仿真工程用标准库实物工程用HAL库各取所长。如果你手头没有现成开发板又想快速看效果还有一个轻量级的替代方案——Wokwi在线仿真平台它支持STM32F103的模型网页版就能跑不需要装任何软件而且对HAL库的兼容性比Proteus好不少。用来跑滴速计算和PID逻辑测试非常方便。4.3 STM32CubeMX配置要点无论仿真还是实物第一步都用STM32CubeMX生成工程框架我的初始化配置是外设配置项参数RCCHSECrystal/Ceramic Resonator时钟树SYSCLK72MHzGPIOPA0EXTI0下降沿触发上拉TIM2预分频72-1计数周期1000-1输出1kHz时基TIM3PWM Generation CH1输出比较预分频72-1频率可调I2C1标准模式100kHzUSART1异步模式115200-8-N-1IWDG预分频40重装载值4095约1秒超时这里特别注意TIM2的时基配置72MHz主频预分频72-1后定时器计数频率是1MHz再设自动重装载值1000-1就得到1ms的定时器请求。这是滴速时间戳的基础误差直接影响最终滴速计算的精度务必确认无误。5. 常见问题与排查实录这个项目从仿真到实物我踩了不少坑有些问题折腾了整整一个周末才找到根因。整理成清单希望后来者少走弯路。5.1 滴速数值乱跳一会儿60一会儿120现象传感器明明只检测到规律的滴落但OLED上显示的滴速在乱跳有时候甚至翻倍。排查过程我先怀疑是代码问题把窗口平均的代码检查了一遍又一遍逻辑没毛病。然后用逻辑分析仪抓PA0的波形发现一个液滴触发了多次下降沿中断——原因是传感器的输出信号没有整形干净在下降沿附近有几十微秒的抖动单片机把一次滴落当成了多次触发。解决方案硬件上在比较器输出端加了一个100nF的电容到地做低通滤波同时代码里加了“消抖锁定”——进入中断后屏蔽外部中断延时50ms再重新使能。双管齐下之后滴速数值就稳定了。这个问题的核心经验是传感器信号进来先过消抖不要在中断里做复杂计算中断只负责打时间戳其他事情丢到主循环。5.2 步进电机低速时疯狂抖动现象电机转速慢的时候蠕动泵不是匀速转动而是一顿一顿地抖手感跳动感明显。排查过程起初以为是电流不够但换成更大功率的电源也没解决。后来意识到是步进电机的固有特性——低频振动尤其在低速段步进步距带来的顿挫感会被放大。解决方案用八拍时序替代四拍时序并且让PWM频率保持在一个不至于过低的范围。如果必须极低速运行可以给UART命令加“细分”逻辑让电机每走一步中间插入微步。此外在机械结构上让蠕动泵的滚轮和软管之间保持合适的预紧力也能明显减少抖动传递。5.3 程序跑了一会儿就“死机”看门狗疯狂复位现象系统运行几分钟后滴速显示变成0然后自动重启再过几分钟又重复。看起来像随机死机。排查过程一开始以为是看门狗设置太短延长喂狗时间也没用。后来用示波器测3.3V电源轨发现电机启动瞬间电压跌落接近0.5V而STM32的复位阈值大约在2.9V左右虽然没触发复位但已经让片上外设状态错乱。解决方案在电机电源输入端加了一个470μF的大电容做储能同时对电机驱动板的电源和单片机电源做了物理隔离两者各走各的电源树。问题彻底消失。这个案例也说明了为什么原理图阶段就要考虑电源设计而不是等出了问题再补救。5.4 Proteus仿真能跑实物一上电就黑屏现象仿真里OLED正常显示烧到实物上屏幕不亮或者亮一下又灭了。排查过程OLED不亮的原因不外乎几个I2C地址不对、SDA/SCL接反、上拉电阻缺失。仿真里I2C总线默认带上了拉不会暴露问题实物如果用的是STM32内部上拉在快速I2C模式下可能不够强导致通信不稳定。解决方案在SDA和SCL上分别接了4.7K的外部上拉电阻到3.3V同时把I2C速度从快速模式400kHz降到标准模式100kHz问题解决。这也是一个典型的“仿真掩盖硬件问题”的教训。5.5 快速排查清单症状可能原因优先级检查项滴速乱跳传感器信号抖动 / 消抖不足用逻辑分析仪或示波器抓波形滴速一直显示0传感器阈值没调好 / 信号没进中断检查PA0电平是否有跳变步进电机不转驱动芯片供电不足 / 接线错误 / 时序反了万用表测电机四相电压OLED白屏I2C地址 / 上拉电阻 / 接线错误扫I2C地址确认设备在位系统周期性复位电源跌落 / 看门狗超时示波器测复位期间电源波形串口数据乱码波特率不匹配 / 晶振频率异常检查CubeMX时钟树配置6. 开源资源获取与后续功能扩展拿到这个项目的开源资料包之后怎么高效使用也是有讲究的。一般解压出来会有这几个文件夹Hardware原理图和PCB、Firmware源码工程、SimulationProteus仿真文件、Doc文档和说明。我的建议是别急着打开仿真工程跑先按这个顺序来先看原理图对照本文前面讲的关键电路理解每个模块为什么这样接自己尝试在纸上重新画一遍。再打开源码工程从main.c开始逐行阅读理清楚初始化顺序、主循环的状态机、中断回调的关系。然后跑Proteus仿真用脉冲发生器模拟滴落信号验证PID控制是否能把滴速稳定到设定值。最后动手做实物——打板、焊接、烧录、调试。这样做的好处是每一步都在前面的基础上递进知识是自己“长”出来的而不是囫囵吞枣地“背”下来的。这个项目后续的扩展空间非常大。如果你想让它在毕业设计或者实际应用中更有竞争力可以从几个方向入手无线化在USART1预留接口上接ESP8266或HC-08蓝牙模块把滴速、剩余量、报警状态实时推送到手机或PC端上位机。配合一个简单的Qt或Python上位机就能实现远程监护功能这也更贴合智能医疗的应用场景。多路化一台STM32同时监控多路输液。F103的资源够用的话可以实现单机四路监控共享一个OLED菜单系统用按键切换查看不同通路的状态。数据记录与追溯用外部Flash存储历史滴速数据掉电不丢失配合上位机导出成曲线图。这在医疗场景下对于输液过程的复盘和追溯很有价值。输液剩余量估算通过累计滴数乘以单滴体积估算剩余药液量当剩余量低于阈值时提前预警而不是等到滴壶空了才响应。我个人在实际开发中的体会是做这种综合项目最值钱的部分不是把某个功能跑通而是把传感器信号处理、闭环控制调参、电源完整性设计、可靠性机制这条链路完整地走一遍。这些在单个外设例程里很难学到只有把它们拼在一起互相“打架”的过程才是真正长本事的地方。还有一个制作与发布层面的大实话开源出来的资料尽量保证“拿到就能编译、编译就能烧录、烧录就能跑”。源码里的路径、芯片型号、引脚配置、工程文件版本都要和文档保持一致避免那种“代码明明是好的但别人打开就报错”的情况。我见过太多项目因为一个路径问题卡住最后口碑稀碎。上传到Gitee或GitHub的时候连README带图文教程一起写清楚这份开源资料的价值才会真正体现出来。
返回列表