基于STM32的心率血氧手环设计:从硬件到GPS定位的完整实践

📅 发布时间:2026/9/1 2:49:14
基于STM32的心率血氧手环设计:从硬件到GPS定位的完整实践
简介本资源是一套完整的STM32嵌入式毕业设计项目方案面向电子信息、自动化及物联网方向的本科生与初阶开发者解决可穿戴健康监测设备从硬件搭建到多传感器融合应用的全流程开发问题。压缩包含123个文件主体为53个.h头文件与52个.c源码文件覆盖STM32F103底层驱动如I2C、USART、TIM、RCC等、MAX30102血氧心率算法、ADXL345跌倒检测逻辑、DS18B20温度读取、GPS数据解析、OLED界面调度及蓝牙通信协议栈辅以Keil工程配置.uvprojx/.uvoptx、调试配置.dbgconf、阈值设置说明.pdf及元器件清单.xlsx结构清晰模块解耦度高便于分块学习与二次开发。目前已有60人下载学习提供从原理图设计、PCB适配、固件烧录到手机APP联调的完整技术链路支撑是理解多传感器协同、低功耗外设管理与嵌入式人机交互的典型实践案例。 刚把这块板子从嘉立创打样回来烧上固件看到OLED上跳出心率数值和GPS坐标的那一刻悬了两个月的心终于放下来了。这是一个基于STM32的心率血氧手环项目带GPS定位功能整套资料包括源码、电路图和元器件清单。这种项目在设计圈里其实不少见但完整把硬件设计、嵌入式软件、传感器算法串起来还带GPS的确实是毕业设计里的硬骨头。我自己在做这个项目的过程中踩了不少坑从选型到调试从功耗到算法每个环节都有值得记录的东西。这篇文章就把整个项目的核心内容拆开揉碎了讲从硬件电路到软件实现再到问题排查给正在做类似东西或者想入坑可穿戴设备的朋友一个完整的参考。老规矩先看整体方案再逐个击破。1. 项目整体设计与方案选型1.1 核心需求拆解做毕业设计跟做产品不一样产品追求成本和可量产性毕业设计追求的是完整性和技术覆盖面。我当时拿到这个题目时先做了需求分析列出来必须有这几个功能模块心率检测利用光电容积脉搏波描记法PPG采集脉搏信号计算实时心率血氧检测通过红光和红外光的吸收差异计算血氧饱和度GPS定位获取经纬度、时间、速度等定位信息显示在手环屏幕上数据展示OLED屏幕实时显示健康数据和定位信息数据存储与回放支持历史数据保存方便后续分析基于这个需求整个系统可以拆成几个子模块主控核心、传感器采集、定位模块、人机交互、电源管理。每个模块独立设计最后统一集成这种模块化的思路能大幅降低调试难度。1.2 主控芯片选型分析主控方面题目点名用STM32系列但STM32家族庞大选型要考虑性价比和开发资源。我当时对比过几款芯片型号内核主频Flash/RAM主要优势典型应用STM32F103C8T6Cortex-M372MHz64KB/20KB资料丰富例程多入门首选STM32F401CCU6Cortex-M484MHz256KB/64KB带FPU功耗低可穿戴设备STM32L431CCT6Cortex-M480MHz256KB/64KB超低功耗适合电池供电高端手环STM32G431CBT6Cortex-M4170MHz128KB/32KB性能强新增CORDIC和数学加速器电机控制综合下来我选的是STM32F103C8T6也就是大家常说的“Blue Pill”核心板用的那款芯片。理由有几个资料最多网上随便一搜就是几百篇教程外设齐全I2C、USART、SPI、ADC都有能满足全部需求成本低一颗芯片几块钱打板做坏了也不心疼。另外一个重要原因是这款芯片的封装是LQFP48手工焊接完全可行不需要热风枪也能搞定。你可能觉得F103有点老但对于这种以学习和展示为主的毕业设计它完全够用3.3V供电、丰富的GPIO、成熟的HAL库支持学习曲线平坦调试工具便宜。真要说性能不够的地方就是心率算法里的FFT计算在F103上跑有点吃力不过后面我会讲怎么处理。1.3 传感器与定位模块选型心率血氧传感器市面上主要有两种选择MAX30100和MAX30102。MAX30100是老款I2C接口缺点是红光和红外光的LED驱动电流不可独立配置在实际测量血氧时精度受影响。MAX30102是升级版同样是I2C接口但两个LED通道可以独立设置驱动电流而且封装更小抗干扰能力也更好。MAX30105则在MAX30102的基础上多了绿光LED可以测心率变异性但对血氧检测没有帮助。GPS模块的选择也有讲究。常用的有u-blox NEO-6M、NEO-7M、NEO-8M以及国产的中科微ATGM336H。NEO-6M是经典款价格便宜十几块钱就能拿到模块网上资料也多但属于老一代产品冷启动时间较长。NEO-8M定位速度更快功耗略高。ATGM336H国产模块性价比很高性能不输u-blox而且支持北斗只是资料相对少一些。我最终选了NEO-6M因为它的资料最好找串口输出NMEA 0183协议接上就能用。如果你手头预算多直接上NEO-8M支持GPS北斗双模定位速度会快不少。这个项目的GPS模块负责输出定位数据通过串口与STM32通信只要解析出$GPRMC和$GGA这两条报文就能拿到经纬度、UTC时间、定位状态和速度信息。屏幕选型上0.96寸的I2C接口OLED是最合适的四根线就能驱动显示效果也不错功耗还低。有人用TFT彩屏显示信息更多但SPI接口占用引脚多刷新率上来了功耗也跟着上来了在低功耗场景下不如OLED实用。2. 硬件电路设计与PCB布局要点2.1 电源系统设计手环是电池供电设备电源设计是整个硬件部分的重中之重。我的方案是采用单节3.7V锂电池供电通过LDO稳压到3.3V给系统供电。选LDO而不是DCDC因为手环这种小负载场景下LDO的纹波更小对传感器的模拟信号采集更友好而且静态电流低整体方案简单可靠。型号用的是XC6206P332MR这是一颗经典的低功耗LDO输出3.3V最大输出电流300mA静态电流只有1uA左右封装是SOT-23体积小非常适合可穿戴设备。具体的电路接法是电池正极接LDO的Vin电池负极接GNDLDO的Vout输出3.3V输入输出各加一个10uF陶瓷电容做去耦输出端再加一个0.1uF的小电容滤高频噪声。电池充电电路用TP4056模块这是一颗线性充电管理IC最大充电电流1A带充电状态指示引脚。我在PCB上预留了TP4056的焊盘充电电流通过外部电阻设置一般用10K电阻对应1A充电电流但对于小容量电池比如400mAh建议把充电电流降到500mA保护电池寿命。考虑到来实验室的同学们基本都是Type-C的线了我就把充电接口设计成Type-C虽然TP4056本身不支持C口协议但只是取电的话完全没问题。电源设计里面最容易忽略的是电池电压检测。手环这种设备必须知道电池还剩多少电我用两个电阻100K和47K组成分压电路把电池电压分压后送进STM32的ADC引脚。理论上分压比是100/(10047)约等于0.68所以ADC读取的电压除以0.68就是实际电池电压再根据锂电池的放电曲线估算电量百分比。注意锂电池的放电截止电压不要低于3.0V过放会损坏电池甚至引发安全问题。固件里要设置低电量告警当电池电压低于3.3V时提示充电低于3.0V时自动关机。2.2 心率血氧传感器电路设计MAX30102的电路设计有几个细节值得说。首先是I2C上拉电阻MAX30102的数据手册要求I2C总线上拉电阻的阻值在2K到4.7K之间我选了4.7K兼顾功耗和通信速率。其次是去耦电容传感器的电源引脚旁边要放一个0.1uF的小电容和一个4.7uF的大电容分别滤高频和低频噪声。MAX30102的INT引脚是中断输出可以配置成数据准备好时触发中断这样主控就不用一直轮询传感器可以释放CPU去做其他事情或者进入睡眠模式。我在电路里把INT引脚接到了STM32的PA1配置成下降沿触发的外部中断。传感器与皮肤的接触方式直接决定信号质量。MAX30102芯片需要贴在PCB背面或者侧面让LED和光电二极管朝向皮肤方向而且PCB对应位置要开窗不能有阻焊油墨遮挡。我在PCB上做了一个导光槽的设计用黑色的遮光泡棉把LED和光电二极管之间的光路隔开防止光线直接从内部串扰到接收端这样做出来的信号质量会好很多。2.3 GPS模块接口设计GPS模块的供电电压是3.3V串口输出也是3.3V电平可以直接和STM32的USART对接。但要注意NEO-6M模块的串口波特率默认是9600这个要和固件里的配置保持一致。GPS模块的天线接口有两种一种是陶瓷贴片天线直接焊在模块上适合室外空旷环境另一种是外置天线通过IPEX座连接信号接收能力更强适合在室内或者遮挡较多的地方测试。我选的是带陶瓷天线的模块因为手环本来就是在户外用的场景外置天线反而不好固定。GPS模块的备份电源引脚V_BCKP需要接一个小电池或者大电容用来在掉电时维持RTC和星历数据。我用了法拉电容容量是0.1F充满电能维持大概一周的星历保存这样二次开机定位速度会快很多。2.4 显示与交互电路OLED模块选的是经典的0.96寸SSD1306驱动方案I2C接口默认地址0x3C。电路上只需要接VCC、GND、SCL、SDA四根线两根信号线上拉电阻也要接上。不过很多成品OLED模块已经板载了上拉电阻做PCB的时候要注意不要重复加上拉否则上拉电阻并联后阻值太小I2C信号可能会变形。实测下来两个4.7K上拉并在一起变成2.35K大概率还能正常工作但信号质量会下降传输距离稍微远一点就容易出错。按键部分我设计了一个唤醒按键和一个功能切换按键。唤醒按键接在PA0上配置成外部中断唤醒模式平时系统睡眠时按一下就能唤醒。功能按键接在PB5上用来切换显示界面。按键电路加一个100nF的电容做硬件消抖同时在固件里也做软件消抖双重保险。震动马达我选了扁平振动马达就是手机里常用的那种圆柱形或者扁平形马达工作电压3V驱动电流在80mA左右。用NPN三极管S8050做开关驱动PB7输出高电平时三极管导通马达振动。三极管基极串联1K限流电阻马达两端并联一个1N4148续流二极管防止断电瞬间的反向电动势打坏三极管。3. 固件开发与核心算法实现3.1 软件工程结构规划固件用STM32CubeIDE开发基于HAL库。整个工程按功能模块划分文件夹结构如下Core/ Inc/ // 头文件 Src/ main.c // 主函数系统初始化主循环 gpio.c // GPIO初始化 i2c.c // I2C初始化 usart.c // 串口初始化GPS数据接收 adc.c // ADC初始化电池电压检测 exti.c // 外部中断配置 tim.c // 定时器初始化 Drivers/ BSP/ max30102.c // MAX30102底层驱动 oled.c // OLED显示驱动 gps.c // GPS数据解析 buzzer.c // 蜂鸣器控制 motor.c // 马达控制 APP/ heart_rate.c // 心率算法 spo2.c // 血氧算法 display.c // 显示界面管理 power_manage.c // 电源管理睡眠/唤醒这个结构的好处是每个模块都独立方便调试时单独验证。比如心率算法有问题只需要替换heart_rate.c不会影响其他模块。另外模块化结构对毕业设计论文的阐述和答辩也很有帮助代码可读性高评委一目了然。3.2 MAX30102驱动与数据采集MAX30102的寄存器配置是这个项目的核心。初始化的关键参数有采样率默认50Hz我配置成100Hz提高信号的时间分辨率LED电流红光LED设置成6.4mA红外LED设置成6.4mA这是一个比较折中的值ADC量程设置为2048nA即满量程对应2048nA的光电流这个值适合大部分肤色采样平均设置为4次平均等效降低噪声初始化完成后主循环通过轮询中断状态寄存器判断是否有新数据。读取数据的时候有两个FIFO数据寄存器一个是红光的一个是红外的每读一次拿到的是上次采样的数据。要注意的是FIFO是环形缓冲区如果读取不及时新数据会覆盖旧数据所以读取频率必须大于采样率。我把我自己封装好的MAX30102初始化代码放了上来这段代码可以直接用void MAX30102_Init(void) { uint8_t reg_val; // 复位传感器 MAX30102_WriteReg(REG_MODE_CONFIG, 0x40); HAL_Delay(100); // 中断使能FIFO数据准备好中断 MAX30102_WriteReg(REG_INTR_ENABLE_1, 0xC0); MAX30102_WriteReg(REG_INTR_ENABLE_2, 0x00); // 设置FIFO水位线为15 MAX30102_WriteReg(REG_FIFO_WR_PTR, 0x00); MAX30102_WriteReg(REG_FIFO_OVF_PTR, 0x00); MAX30102_WriteReg(REG_FIFO_RD_PTR, 0x00); MAX30102_WriteReg(REG_FIFO_CONFIG, 0x4F); // 采样平均4次FIFO水位线15 // 模式配置多模式红光红外 MAX30102_WriteReg(REG_SPO2_CONFIG, 0x67); // 100Hz采样率ADC 2048nALED脉宽411us // LED电流配置 MAX30102_WriteReg(REG_LED1_PA, 0x24); // 红光LED电流 6.4mA MAX30102_WriteReg(REG_LED2_PA, 0x24); // 红外LED电流 6.4mA // 开启心率和血氧模式 MAX30102_WriteReg(REG_MODE_CONFIG, 0x03); }数据采集的部分通过FIFO读数据寄存器获取红红光和红外AD值。两个值是有内在关联的红光在血液中吸收系数高波动明显红外光受血氧影响小波动稳定。两者配合才能算出SPO2。3.3 心率算法实现心率计算的核心是处理PPG波形从中找出心跳周期。这里面有几个关键点一个都不能马虎。第一是滤波。MAX30102采集到的原始信号里有大量噪声包括基线漂移身体运动引起、工频干扰50Hz、高频毛刺环境光变化。我用的是滑动平均滤波加一阶高通滤波的组合方案。滑动窗口设置成10个采样点相当于100Hz采样率下做了100ms的平滑能有效滤掉高频噪声。高通滤波截止频率设置在0.5Hz左右去除基线漂移。第二是峰值检测。滤波后的PPG波形是光滑的周期信号心跳的时候会出现一个主波峰。我用的方法是自适应阈值法首先计算一段时间内波形的最大值和最小值阈值设为(max - min) * 0.7 min只有高于阈值的极值点才算心跳峰值。两个连续峰值之间的时间间隔换算成心率公式是心率 60 / 峰值间隔秒数。第三是抗干扰。运动时波形会严重变形峰值检测很容易误判。我的策略是加入滑动窗口心率有效性判断如果前后两次心率差值超过20bpm就认为数据不可靠用上一次的稳定值继续输出同时标记数据质量异常。这个简单的策略在轻微运动下能把误判率降低不少。简单版的心率计算方法可以这样写uint16_t calc_heart_rate(uint32_t ir_value) { static uint16_t ir_buffer[BUFFER_SIZE]; static uint8_t buf_index 0; static uint16_t valid_hr 0; ir_buffer[buf_index] ir_value; buf_index (buf_index 1) % BUFFER_SIZE; // 滤波处理 uint16_t filtered moving_average_filter(ir_value); // 阈值判断 if (filtered threshold filtered - last_peak MIN_PEAK_INTERVAL) { // 找到峰 uint16_t hr 6000 / (filtered_peak_index - last_peak_index); if (hr 50 hr 200) { valid_hr hr; } last_peak_index filtered_peak_index; } return valid_hr; }这段代码的写法比较简略实际项目中要考虑的东西更多比如动态更新阈值、异常峰值剔除、心率数值的平滑输出等但核心思路就是这样滤波 - 寻峰 - 算周期。3.4 血氧算法实现血氧饱和度SpO2的计算原理是朗伯-比尔定律。血液中氧合血红蛋白和脱氧血红蛋白对红光660nm和红外光940nm的吸收系数不同通过计算两种光信号的交流成分和直流成分之比再拟合经验公式就能得到SpO2值。具体实现上需要同时处理红光和红外两路信号分别计算它们的AC分量和DC分量R (AC_red / DC_red) / (AC_ir / DC_ir) SpO2 A * R BMAX30102的官方驱动里给了一组拟合系数A -45.060B 30.354。这组系数来自大规模的临床实验数据但在实际使用中因为个体差异、肤色差异、传感器佩戴方式不同直接套用误差会比较大。我当时烧录固件后发现测量值和医用血氧仪对比误差在正负3%以内这个精度对于毕业设计来说已经可以接受了。注意所有基于PPG反射式测量原理的血氧算法都不是医疗器械级精度只能用于健康监测参考不能作为医学诊断依据。这一点在论文的结论部分一定要写明。3.5 GPS数据解析GPS模块通过串口输出的NMEA 0183协议数据帧格式是纯文本示例$GPRMC,083559.00,A,3103.4223,N,12122.6578,E,0.5,104.2,240324,,,A*5F解析的时候只需要关注两类报文$GPRMC推荐最小定位信息和$GGA全球定位系统固定数据。$GPRMC里有经纬度、速度、日期$GGA里有海拔和定位质量。定位质量那一栏的数字非常关键0表示无效定位1表示GPS定位有效2表示差分定位有效。GPS数据解析的框架大致是这样void GPS_Parse(uint8_t byte) { static char buffer[128]; static uint8_t index 0; if (byte $) { index 0; memset(buffer, 0, sizeof(buffer)); } if (index sizeof(buffer) - 1) { buffer[index] byte; } if (byte \n) { buffer[index] \0; if (strstr(buffer, $GPRMC)) { parse_GPRMC(buffer); } else if (strstr(buffer, $GGA)) { parse_GGA(buffer); } index 0; } }解析出来的经纬度是度分格式比如3103.4223表示31度03.4223分需要转换成十进制度数格式才能显示和记录31 03.4223 / 60 31.057038。这个转换很容易忘我一开始调试的时候直接显示原始数据怎么看怎么不对后来反应过来是格式问题。GPS冷启动时间一般在30到60秒热启动在1到5秒。在固件里要加一个超时处理如果90秒内没有获取到有效定位就显示定位中...而不是显示无效的坐标数据。3.6 低功耗设计手环是电池供电功耗控制是整个项目能否真正用起来的关键。我的方案分三档功耗模式正常模式系统全速运行此时GPS模块开启、传感器开启、OLED开启。实测电流在80mA到120mA之间主要功耗来源是GPS模块和OLED。省电模式关闭GPS模块和OLED传感器降低采样率到25Hz主控进入睡眠状态只保留RTC定时唤醒。这个模式下功耗可以降到10mA以下。深度睡眠模式所有外设关闭主控进入STOP模式待机电流在20uA左右。只有唤醒按键或者RTC中断能把系统拉起来。STM32进入STOP模式的代码实现很简洁void Enter_Stop_Mode(void) { // 关闭外设 HAL_UART_DeInit(huart1); // GPS串口 HAL_ADC_Stop(hadc1); // ADC MAX30102_Shutdown(); // 传感器掉电模式 // 配置唤醒源 HAL_SuspendTick(); // 暂停系统滴答定时器 HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); // 唤醒后恢复 HAL_ResumeTick(); SystemClock_Config(); // 重新配置系统时钟 }需要注意的是从STOP模式唤醒后系统时钟需要重新初始化否则外设时钟配置会乱掉。我一开始漏了这一步唤醒后传感器数据全是乱码排查了半天才发现是时钟问题。4. 联调测试与问题排查记录4.1 测试环境与工具准备硬件调试必备的工具有ST-Link V2下载器、数字万用表、USB转TTL模块、示波器没有的话逻辑分析仪也行、医用血氧仪用于对比测量精度。调试顺序有讲究从易到难先下载LED闪烁程序验证主控最小系统然后调OLED能显示字符就说明I2C总线没问题接着接MAX30102读原始数据用串口发到上位机看波形再调试GPS解析到窗边搜星最后做电源管理和低功耗。4.2 典型问题排查与解决方案这个项目做下来遇到的坑真不少整理成表格方便大家对照排查问题现象可能原因解决方案OLED显示花屏或无显示I2C地址错误、电源电压不足、初始化时序不对用I2C扫描程序确认地址检查OLED供电是否稳定初始化前延时100ms心率数值波动大或为0传感器佩戴过松、LED电流过小、环境光干扰调整LED电流加遮光泡棉采样时紧贴皮肤GPS一直显示定位中天线朝向问题、所在位置遮挡严重、波特率不匹配拿到窗边或户外测试确认波特率是9600等待时间加长到两分钟ST-Link下载提示找不到设备引脚被占用、NRST线未连接、设备供电不足检查PA13/PA14是否被代码设置为普通IO连上NRST线改用外部供电电池电压ADC读数偏低分压电阻精度不足、基准电压不准确使用1%精度电阻用万用表实测分压值校准系统睡眠后无法唤醒唤醒引脚配置错误、GPIO模式设成模拟输入确认唤醒引脚配置为外部中断模式且使能了EXTI线4.3 心率传感器调试的独家心得心率传感器是这里面最难调试的部分信号质量的判断直接影响算法效果。我调试时的方法是通过串口把红光和红外的原始ADC值发送到上位机用串口绘图工具实时看波形。波形正常的样子应该是有规律的脉动每个心跳周期出现一个明显的波峰波峰与波谷的幅度差在100到500个ADC计数之间。如果波形很平、没有脉动说明传感器没有贴合皮肤或者LED电流太小如果波形大幅波动、形态不规则说明传感器在晃动或者环境光干扰严重如果波形有周期性的大漂移说明用户的呼吸动作造成了传感器位移。有个细节值得拿出来说传感器模块贴皮肤的位置选择。我一开始把传感器装在PCB正面手环戴上后传感器朝外完全测不到信号。后来改成PCB背面安装利用PCB的镂空窗口朝向手腕内侧的桡动脉区域信号一下就出来了。这属于硬件结构设计上的关键细节很多新手在做原理图的时候根本不会想到这一步。其实PPG信号的原理有点类似于把一个手电筒贴在手指上透过手指看透射光强变化。心率血氧手环用的是反射式LED发的光进入皮肤组织后一部分被血液吸收另一部分散射回来被光电二极管探测到血液在脉搏作用下体积周期性变化散射光的强度也跟着波动。采集到这个波动信号剩下的就是信号处理和数学计算了。4.4 GPS调试的注意事项GPS调试有一个很容易被忽略的点手机、电脑的电磁辐射会影响GPS信号的接收质量。我在实验室调试GPS时发现定位速度特别慢后来发现是因为旁边放着一台高频烙铁断开后定位速度快了很多。还有GPS模块要和STM32主板分开布局不要压在主控芯片正上方否则主控产生的电磁干扰会影响GPS的信号接收。另外GPS模块第一次使用前要完成完整的冷启动定位流程之后的星历数据才有效。简单说就是首次上电后拿到户外空旷处让模块连续工作10分钟以上完成一次完整定位和星历下载。之后如果电路板重新上电定位速度会快很多。5. 项目打包与毕业设计答辩准备资料包里除了源码和电路图还应该包含一些对毕设答辩有帮助的东西。我当时整理了一套完整的项目文档包括需求分析文档明确各个功能指标比如心率测量范围30-200bpm精度±5%硬件设计文档包括系统框图、原理图说明、PCB布局截图软件设计文档包括程序流程图、模块说明、关键算法讲解测试报告实测数据与医用设备的对比结果如果你准备拿这个项目去答辩评委大概率会问这几个问题为什么选MAX30102和MAX30100比优势在哪心率算法的原理是什么怎么处理运动伪迹GPS的定位精度是多少在城市峡谷环境表现如何功耗是多少续航多久做过哪些低功耗优化血氧算法中的拟合系数是怎么来的可靠吗每个问题都要准备3分钟左右的回答核心是讲清楚为什么这么做和做了之后效果如何。算法部分的回答要重点讲原理而不是只讲实现代码。元件清单这部分我把主要的BOM成本列一下STM32F103C8T6大约8块钱MAX30102大约9块钱NEO-6M模块大约18块钱OLED屏大约8块钱加上电阻电容、锂电池、Type-C座、按键、马达、PCB打样费整套硬件成本控制在100块以内。这个成本对于毕设来说完全可以接受。PCB打样建议走嘉立创5块钱能打10片两三天就发货。元器件在立创商城下单基本上一天到货。两个平台配合起来从画板到拿到实物一周时间就能搞定。如果不想自己焊接也可以找嘉立创的SMT贴片服务不过对于这种小批量手环板子手焊完全够用顺便还能练练焊接技术。最后再分享一个心得。我在做这个项目的过程中最大的收获不是代码能跑、板子能亮而是体会到了软硬结合这种工作方式的节奏。写算法的时候要考虑硬件的能力限制画板子的时候要想着软件怎么控制和读取两边互相约束又互相成就。刚开始会觉得很折腾但一旦系统打通那种整个设备都在你的掌控之中的感觉是单纯做软件或者单纯做硬件都体验不到的。这个项目做完你会发现自己对嵌入式系统的理解会上升一个台阶这也是为什么我建议你从零开始做一遍而不是直接拿别人的源码看一遍就完事。本文还有配套的精品资源点击获取