简介本资源是一套基于STM32F103系列单片机实现的智能停车场系统完整毕业设计资料面向计算机、电子信息、自动化等专业的本科生适用于毕业设计、课程大作业及嵌入式项目实战训练。系统涵盖车位检测、车辆进出识别、LED状态显示、串口通信与本地数据管理等功能代码经Keil MDK本地编译验证全部源码可直接运行调试充分、稳定性高。压缩包共176个文件含43个头文件.h定义硬件接口与功能模块41个C源文件.c实现核心逻辑辅以.o目标文件、.d依赖文件、.axf/.hex可执行镜像及工程配置文件.uvprojx/.uvoptx整体大小为4.74MB结构规范便于理解STM32标准外设库开发流程。已有202人学习下载资料包含完整工程目录、清晰模块划分、关键注释说明及典型外设驱动如TIM、RCC、ADC、I2C、USART等特别适合嵌入式初学者掌握软硬协同开发与真实项目落地能力。 大学毕业设计这个坎每年都有一大批人栽在选题上。要么题目太简单评委觉得没工作量要么题目太复杂做到一半发现根本推不动。STM32智能停车场系统恰好卡在一个非常舒服的位置——它足够经典涵盖传感器采集、电机控制、显示交互、通信协议这些嵌入式核心知识点又不会难到一个人做不完。换句话说这是一个标准的优秀毕业设计胚子。这套系统的设计思路、代码框架、调试方法包括我当时踩过的那些坑这篇一起讲透。1. 为什么选智能停车场这道题的真实难度与拿分点在哪1.1 从选题到框架一个能撑起论文的题目长什么样先说一个很多人容易误判的点毕设选题并不是越新颖越好而是工作量可见、技术栈清晰、能讲出故事最好。智能停车场系统恰恰满足这三点。从工作量看它天然分成前端检测、中枢控制、终端执行、云端/上位机通信几条线。每一条线都可以展开成论文的一章附录还能放上完整的源代码和电路图。从技术栈看STM32的GPIO、定时器、中断、PWM、ADC、串口、I2C这些外设全部能用上外设覆盖面广在答辩时非常好讲。从故事性看停车场是所有人都见过的场景评委不需要你花五分钟解释项目背景一句模拟真实停车场实现车位检测与引导就足够进入正题。我当时给这套系统的定位是以STM32F103C8T6为主控通过红外对管模拟车位占用检测使用舵机模拟道闸栏杆OLED实时显示车位余量和占用状态再加一个ESP8266模块把数据上传到上位机实现远程监控的雏形。整体系统分四层感知层负责采集车位状态控制层负责逻辑判断与决策执行层负责道闸和显示输出通信层负责与上位机或云平台交互。这个四层架构后来直接变成了论文里的系统总体设计图答辩时讲起来思路特别顺。1.2 系统功能怎么定才不过度也不单薄功能设计是毕设的第一步也是很多人第一步就走歪的地方。我的建议是三个字做减法。不要一开始就想着上摄像头做车牌识别不要想着用地磁传感器阵列更不要想着搞完整的移动端App。STM32F103C8T6是一块M3内核、72MHz主频、64KB Flash的小芯片它的定位是能完成实时控制的单片机不是跑Linux的开发板。功能一旦超出芯片能力上限你的毕设就会从做系统变成调bug。以这套系统为例我最终确定的功能清单是车位检测8个模拟车位采用红外对管传感器检测是否有车占用道闸控制入口和出口各一个舵机模拟车辆进出时的抬杆放行车位引导OLED屏实时显示每个车位的占用状态和剩余车位数量计时计费车辆进入时记录时间戳驶出时根据停留时长计算费用数据上报通过ESP8266模块把车位状态、进出记录打包上传到PC端上位机这五个功能覆盖了检测-控制-显示-通信完整链路代码量大约在1500到2000行一个人从零开始写两到三周能完成主体逻辑剩下时间用来写论文和做联调。更重要的是这些功能每一个都能在答辩现场做实物演示不会出现系统能跑但看不见效果的尴尬局面。2. 硬件平台搭建从元件选型到电路连接的踩坑记录2.1 主控选型为什么锁定STM32F103C8T6现在市面上可选的单片机很多51、Arduino、ESP32、GD32、STM32各有拥趸。但毕设场景下STM32F103C8T6依然是综合性价比最优的选择原因有三。第一是资料密度极高。STM32F103是ST的经典型号网上从寄存器版到标准库版再到HAL库版的教程铺天盖地。而毕设这个东西最怕的不是技术难而是遇到问题搜不到答案。STM32生态下几乎你能遇到的所有问题都有人踩过并留下了解决方案。第二是外设配置对毕业设计而言刚刚好。我用的C8T6有37个GPIO、3个USART、2个SPI、2个I2C、1个12位ADC、4个16位定时器、1个高级定时器做停车场系统绰绰有余。相比之下51单片机的片上资源太紧张加一个OLED屏可能就得软模拟I2C代码写起来非常受限ESP32虽然性能更强但它的开发复杂度也更高而且在嵌入式基础这个维度上使用ESP32容易被评委质疑为什么不选纯单片机。第三是核心竞争力的问题。毕设的评价标准里工作量和技术深度是两个核心指标。STM32的寄存器配置、中断优先级、DMA传输这些知识你在论文里能实打实地写出来答辩时也能回答这个PWM频率是怎么算出来的这类深度问题。如果用Arduino几行代码就能点灯但论文里只能写调用库函数完成初始化拿什么支撑技术章节呢2.2 各功能模块的选型与接线要点硬件选型要遵循一个原则用最成熟的模块不要在新器件的坑里浪费时间。我最终的BOM清单和理由如下。红外对管传感器TCRT5000作为车位检测探头。它的原理是红外发射管持续发射红外光当有物体靠近时反射光增强接收管导通程度变化通过电压比较器输出高/低电平。选它是因为输出是数字信号单片机直接读GPIO就行不需要ADC处理逻辑简单稳定。每个车位用一个8个车位8路输入。SG90舵机作为道闸执行器。9g舵机力矩小但模拟道闸栏杆绰绰有余。它的控制信号是50Hz的PWM波高电平脉宽0.5ms到2.5ms对应0到180度设置两个角度就能实现抬杆和落杆。0.96寸OLED屏SSD1306驱动作为显示终端。I2C接口只占两根线4针接法VCC、GND、SCL、SDA非常简单。显示屏分辨率128x64可以同时显示汉字和数字做车位状态显示正合适。ESP8266-01S作为通信模块。串口透传默认波特率115200通过AT指令配置即可工作。我做的是让STM32通过USART2发送数据帧给ESP8266ESP8266以TCP客户端身份连接电脑上的网络调试助手实现数据上云前的功能验证。接线方面重点提醒几个容易被忽略的细节。红外对管的VCC接5V还是3.3V要看模块说明书很多TCRT5000模块板上自带比较器工作电压是5V但信号输出引脚是TTL电平可以直接接3.3V单片机的GPIO。我一开始把模块的VCC接到了3.3V结果比较器工作不稳定检测距离明显变短后来换成5V供电才恢复正常。舵机的电源必须单独考虑。SG90的堵转电流能到几百毫安如果直接从STM32的3.3V引脚取电芯片会被拉垮甚至复位。我的做法是信号线接PA1TIM2_CH2电源正负极接外部5V电源同时把开发板的GND和外部电源的GND共地。共地是所有外设接线的底线不共地会导致电平参考不一致通信和信号读取全乱套。OLED的I2C上拉电阻大部分模块上已经集成不需要额外加。但如果你用的是裸屏而不是模块记得在SCL和SDA上分别接4.7k欧姆上拉电阻到3.3V否则I2C通信会不稳定出现花屏或者能初始化但刷不出内容的诡异问题。3. 软件代码的分层设计与核心模块实现3.1 整体程序框架状态机比流水账靠谱STM32的开发方式现在主流是HAL库我这套系统用的也是HAL库。很多初学者写代码喜欢在main函数里用一个大while循环从上到下顺序执行所有功能函数看起来直观但一旦功能多起来代码就变成一锅粥。比如检测车位要实时响应舵机控制又不能阻塞OLED刷新还要及时三个需求混在一起顺序执行必然互相拖累。我的做法是把系统拆成两层主循环负责非实时任务中断服务函数负责实时任务。具体来说主循环处理OLED刷新、车位状态检测、计费逻辑更新定时器中断TIM31ms周期维护系统时钟节拍提供时间戳外部中断GPIO下降沿触发检测红外对管信号变化标记车位状态变更USART2接收中断接收上位机下发的控制指令这个框架的本质是时间片轮询加事件驱动。每个1ms节拍递增一个全局变量sysTick所有需要计时的模块都基于这个变量做差而不是用delay函数阻塞等待。车位检测的状态机是整套代码的核心。每个车位定义两种输入状态红外对管检测到车电平为低和没检测到车电平为高。但硬件信号存在抖动直接读取GPIO判断会产生误触发所以我在外部中断里只做一件事——把对应车位的flag置1然后在主循环里调用一个车位移除函数连续读取该GPIO状态20次如果全部为低才确认为占用状态。这就是软件消抖实际效果非常稳。车辆进出的流程我用了一个简单的三段状态机来描述空闲状态等待车辆到达检测到车辆后启动计时车辆离开后结算费用并释放车位。整个状态转移都用switch-case实现逻辑一目了然论文里画一张状态转移图就能说清楚。3.2 车位检测与计时逻辑的细节处理车位检测这部分看似简单实际有很多细节值得展开。红外对管输出是数字信号常态下输出高电平检测到障碍物时输出低电平。所以我用GPIO下降沿触发外部中断检测到下降沿说明有车进入车位范围。但这里有个容易被忽略的坑车辆在车位里并不是静止不动的。实际场景中司机倒车入库可能来回调整车身在红外对管前晃来晃去导致信号在短时间内多次跳变。如果每跳变一次就改变车位状态系统的逻辑就会乱套。我用了一个去抖窗口解决这个问题。具体实现是外部中断触发后记录时间戳主循环中每隔10ms读取一次该GPIO电平连续读取20次如果20次里超过15次为低电平才认定车位被占用。这个15/20的判定阈值可以根据实际环境调整数字越大系统越稳定但响应也越慢。实测下来15到18之间的取值效果最好既不会误判也不会让显示屏上的状态变化显得迟钝。计时逻辑则需要和RTC区分开。STM32F103内部虽然有RTC但在低功耗和精度要求不高的场景下直接用定时器中断维护的sysTick变量就够了。我的实现方式是全局变量sysTick在TIM3中断里每1ms加1车辆进入时记录当时的sysTick值到enterTick车辆离开时用当前sysTick减去enterTick得到停留毫秒数再除以1000得到秒数。收费规则按停留时长阶梯计费比如前1小时免费1到3小时每小时2元超过3小时每小时3元封顶20元。这个规则用几个if判断就能完成。这样做的另一个好处是它把持续时间和绝对时间解耦了。系统不需要关心当前是几点几分只关心车辆停了多少秒逻辑简洁且便于测试。如果你确实需要显示具体的进出时间可以再接一个DS1302时钟模块但这不是核心功能可以放到扩展章节里写。3.3 舵机与OLED这些外设代码的注意事项舵机的控制核心是PWM波形。SG90要求周期20ms频率50Hz高电平脉宽0.5ms对应0度1.5ms对应90度2.5ms对应180度。STM32的TIM2_CH2用于输出PWM定时器时钟来自APB1总线通常是72MHz的一个分频。我配置的分频系数为71得到1MHz的计数频率再设置自动重载值为19999这样得到的PWM周期就是20000微秒正好20ms。关键代码逻辑如下// TIM2 PWM初始化PA1作为PWM输出引脚 TIM_HandleTypeDef htim2; htim2.Instance TIM2; htim2.Init.Period 19999; // 自动重载值决定周期20ms htim2.Init.Prescaler 71; // 72MHz/(711)1MHz每个计数单位1us htim2.Init.CounterMode TIM_COUNTERMODE_UP; HAL_TIM_PWM_Init(htim2); // 设置高电平脉宽单位微秒 // 0度对应500微秒90度对应1500微秒180度对应2500微秒 __HAL_TIM_SET_COMPARE(htim2, TIM_CHANNEL_2, 500); // 抬杆 __HAL_TIM_SET_COMPARE(htim2, TIM_CHANNEL_2, 2500); // 落杆这里有一个新手常见的困惑为什么Period设成19999而不是20000因为定时器的自动重载值是从0开始计数的计数到19999正好是20000个计数单位。如果设成20000实际周期就会变成20001微秒虽然误差只有1微秒但50Hz的舵机控制信号对频率精度要求不高误差累积却会影响多舵机同步的稳定性。既然能在配置阶段消除就没必要留着这个小瑕疵。OLED的部分需要注意初始化顺序。SSD1306驱动上电后需要先发送初始化序列包括关闭显示、设置显示时钟分频、设置多路复用率、设置对比度、开启显示等命令。这些命令官方数据手册里都有网上也有大量的现成代码。我用的就是四线I2C接口接线是VCC接3.3V、GND接GND、SCL接PB6、SDA接PB7这两个引脚是STM32F103的I2C1引脚。实际使用中我用的是软件I2C而不是硬件I2C。原因是STM32F103的硬件I2C在早期版本上存在一些bug比如总线忙标志无法自动清除配置不当会导致通信卡死。软件I2C用两个GPIO模拟时序虽然多占用一点CPU时间但稳定性极高而且代码可移植性强。在OLED这种低速设备上软件I2C完全够用实测刷新一帧数据只需要几毫秒。3.4 基于串口的数据上报与上位机对接数据上报是整套系统里最像产品功能的一环也是答辩时最出彩的部分。我的通信架构是这样的STM32通过USART1连接ESP8266ESP8266以TCP客户端模式连接PC上的网络调试助手。STM32每隔1秒主动向ESP8266发送一帧数据帧格式自定义固定长度便于上位机解析。帧格式我定义成这样0XAA 0X55 0X01 [车位状态字节] [余量] [费用] 0X0D 0X0A0XAA 0X55帧头用于上位机同步0X01数据类型表示这是车位状态帧车位状态字节8位bitmap每一位对应一个车位1表示占用0表示空闲余量剩余车位数一个字节费用当前收费总额两字节的十六进制数0X0D 0X0A帧尾回车换行这个自定义协议的好处是解析简单、不容易出错。上位机那边只需要循环读取串口数据当读到0XAA 0X55后接着读后续字节按固定长度解析即可。如果你不想自己写上位机用现成的串口助手软件配合文本显示就能看到原始数据再用一个小脚本做可视化也行。这里要提醒一个在线调试的小技巧在STM32和ESP8266之间我特意预留了一个测试点就是STM32的PA9USART1_TX。调试时先用USB转TTL模块直接接PA9确认STM32发出的数据帧正确再接通ESP8266的TX和RX做透传测试。这样做的好处是问题定位非常清晰如果直接接PA9数据正确但接上ESP8266后上位机收不到数据那问题一定出在ESP8266的配置上而不是STM32端。4. 联调过程中踩过的坑完整排查链路与修复方案4.1 舵机不动作误以为舵机坏了结果是个低级问题这套系统第一次上电联调时第一个翻车的地方就是舵机。上电后舵机一点反应都没有我第一反应是舵机坏了换了一个新的还是没反应才开始怀疑是控制信号的问题。排查链路如下。用示波器测量PA1引脚发现没有PWM波形输出。检查代码HAL_TIM_PWM_Init返回成功但HAL_TIM_PWM_Start没有调用。这是一个非常典型的错误——HAL库初始化PWM后还需要启动PWM输出通道否则定时器没有实际输出波形。补上启动代码后舵机还是没有反应再次用示波器测量发现波形有了但高电平脉宽是0。检查代码发现我在初始化后设置了0度的占空比也就是500微秒的脉宽而SG90在500微秒高电平下理论上应该转到0度位置。继续排查才发现我把500微秒错写成了500计数单位因为定时器分频后每计数单位是1微秒所以500计数单位就是500微秒这个换算没有错。真正的问题是定时器在初始化后立即执行了一次复位把输出的比较值清零了。修复方法很简单在初始化完成后显式调用一次设置占空比的函数见上面提到的__HAL_TIM_SET_COMPARE并且在主循环中不要再做任何复位操作。这个问题给我最大的教训是调试外设故障时不要一上来就怀疑硬件坏了先用示波器或逻辑分析仪确认控制信号是否到达引脚信号有问题再往代码里查。示波器不是必须的逻辑分析仪几十块钱一个但它是嵌入式联调阶段性价比最高的工具。4.2 OLED花屏/不显示I2C上拉与地址的双重陷阱OLED模块上电后显示白屏就是整个屏幕亮但不显示任何内容这个现象其实代表了两种完全不同的故障一种是屏幕正常但没收到数据另一种是屏幕没正常初始化。我的排查过程是这样的。先测SCL和SDA引脚的波形发现I2C总线有信号说明MCU是在往外发数据的。接着检查OLED模块的I2C地址SSD1306的7位地址通常是0x3C或0x3D由模块上的地址选择电阻决定。我的代码里写的是0x78即0x3C左移一位后的8位地址逐字节核对后发现地址写错了模块实际上是0x7A。修改地址后屏幕还是不显示但这次现象不同——屏幕从白屏变成了闪烁说明数据已经进去了只是初始化序列或显存刷新有问题。后来发现是初始化序列中有一条命令配置错了导致显示方向异常屏幕上显示的内容全部被裁剪到可视区域之外。把扫描方向命令修正后屏正常显示。这类问题排查的核心经验是要区分屏幕完全不工作、能初始化但显示异常、能显示但内容错乱这三种现象。现象不同排查方向完全不同。完全不工作查电源、查I2C地址、查上拉电阻显示异常查时序和初始化序列内容错乱查缓存刷新和坐标映射。4.3 车位检测误触发红外对管受环境光干扰车位检测模块在室内测试时一切正常但搬到窗边光线较强的地方偶尔会出现无车占用却显示有车的误报。用万用表测红外对管模块的信号输出引脚发现环境光强时模块输出端电压出现周期性抖动在高低电平之间跳变。原因是TCRT5000的红外发射管发射的红外线在强光环境下被环境光中的红外成分淹没接收管接收到的反射信号信噪比下降比较器在阈值附近震荡。处理办法有两个方向。硬件方向是调整模块上的电位器把比较器阈值调高一点让只有在红外反射足够强时才能触发。软件方向是加长去抖窗口把之前20次读取的窗口加大到50次同时把判定阈值从15提高到40。两个方向结合后误触发的问题基本消失。这里要特别说明检测类传感器的阈值调节是一个系统级的调试手段不能只在代码层面死磕。传感器输出的信号质量决定了软件消抖的难度。信号质量好软件处理就轻松信号质量差软件写得再精巧也扛不住。好的嵌入式开发者在做硬件选型和布局时就会提前考虑传感器信号质量的问题而不是等软件出问题了再回头改硬件。4.4 系统偶发死机跑一段时间就卡死重启后恢复系统连续运行大概半小时后偶尔会出现整体卡死的现象单片机不再响应任何输入OLED画面定格舵机失去控制。重启后恢复正常但半小时后可能再次出现。这个问题的排查难度比前面几个都高因为它不是必现的而是偶发的。我当时的排查思路是先定位代码是否跑飞再定位是否是硬件原因导致复位。第一步在main函数的主循环末尾加入一个运行指示灯翻转操作用LED闪烁频率来判断主循环是否还在运转。死机时LED不再闪烁说明主循环确实卡死了。第二步用调试器连接SWD接口在死机时暂停程序查看当前执行位置。发现代码停在某个中断服务函数里反复进入这个中断但无法退出。查看该中断的使能标志和触发源发现是外部中断线始终拉低导致的。再进一步排查外部中断引脚连着红外对管的信号输出。用万用表测量该引脚电平确实是低电平。问题变成了什么时候红外对管输出持续低电平答案是当检测到物体时但正常情况下去抖后状态会更新不应该一直触发中断。到这里我想明白了一个机制层面的原因如果物体持续停留在红外对管前方GPIO电平持续为低外部中断在下降沿触发一次后不会再触发因为电平没有变化。但问题是我的外部中断服务函数里做了比较耗时的处理导致中断服务时间过长而主循环里的车位移除函数一直被中断打断无法执行完毕状态机卡在中间状态。这实际上是一种优先级反转和中断负载过高的组合问题。修复方案分两步。第一步把外部中断服务函数精简到极致只做置标志位和记录时间戳这两件事其他一切处理全部放到主循环。第二步在车位移除函数里加入连续读取N次电平一致才更新时间戳的逻辑避免状态机在中间状态停留时时间戳被反复刷新。这个坑值得展开说嵌入式系统里中断服务函数ISR的金科玉律是越短越好。ISR里只做标记、计数、读取数据寄存器这类微秒级操作一切耗时的逻辑处理都放到主循环或任务调度中。很多从裸机编程入门的人习惯在中断里写大量业务代码这在功能简单时没什么问题一旦系统复杂度上来就会触发各种难以排查的偶发故障。我的一个实测数据是一个空的中断服务函数开销大约在几十个时钟周期而如果你在里面跑一个HAL_UART_Transmit同步发送函数在默认超时设置下可能会阻塞几百个甚至几千个时钟周期。这种阻塞对于高速中断来说是致命的。5. 毕设论文的写法与答辩准备的实操建议5.1 论文结构怎么套才不显空洞技术做完了代码能跑了论文却不知道怎么写这是很多人的真实困境。其实一篇毕设论文的逻辑主线非常固定就是把系统是怎么设计出来的讲清楚。你只需要把答辩委员会最关心的几个问题依次回答清楚即可你要做什么、为什么选这个方案、系统怎么设计、每一部分怎么实现、结果怎么样、还能怎么改进。以这套系统为例论文目录可以这样组织第一章 绪论智能停车场的背景与意义、国内外研究现状、本文主要工作第二章 系统总体设计需求分析、总体架构、功能模块划分、技术选型第三章 硬件设计主控最小系统、车位检测模块、道闸控制模块、显示模块、通信模块的电路设计与连接第四章 软件设计开发环境搭建、系统主流程、各功能模块的软件设计与代码实现第五章 系统测试测试环境、功能测试、性能测试、问题分析与改进第六章 总结与展望这里要特别强调第二章和第四章的作用。第二章的技术选型部分你要写清楚为什么选STM32F103C8T6而不是51、为什么选红外对管而不是摄像头、为什么选ESP8266而不是4G模块。每一个选型都是一个可以展开讨论的切入点评委提问时最喜欢从这些地方入手。第四章的软件设计不要只贴代码要把每个模块的处理流程画成流程图或者状态图配合伪代码说明核心逻辑。比如车位检测的去抖处理流程、舵机PWM的占空比计算过程、串口数据帧的组包解析过程这些内容写出来纸面就很充实。5.2 答辩PPT和演示环节怎么设计答辩现场评审最看重的是你能现场演示系统运行效果。但现场演示往往有风险我见过太多人在答辩现场因为串口被占用、显示器不亮、舵机突然失灵而翻车。我的建议是做一个双保险演示方案提前录制一个完整的演示视频视频内容包括系统上电、车辆进入时道闸抬起、OLED刷新车位状态、车辆驶出时计费、上位机收到数据帧的整个过程。现场先放视频再复现关键环节的实物演示。这样即使现场设备出问题也不至于全程尬住。PPT的设计原则是一屏一图少字多图。每页PPT放一张系统框图、电路图或者截图配两三句关键说明。不要让PPT变成Word文档的搬家评委根本不会读你PPT上的大段文字。答辩时最容易的高频问题要提前准备答案为什么选择STM32而不是其他单片机——从性能、外设资源、资料生态回答红外对管的检测距离是多远如何调整——回答传感器原理和阈值调节方法你的系统如果应用到真实停车场还有什么不足——回答摄像头识别、多入口协同、云端管理舵机的角度控制精度是多少如何实现——回答PWM脉宽与角度的对应关系5.3 毕业设计做完之后还能做什么说实话这套系统做完、答辩通过、拿到学位之后我本来是打算把它彻底封存吃灰的。但后来在工作里接触了不少实际的车库管理项目回头看这套毕设系统发现它其实留下了一整条清晰的进阶路线如果你想继续深入可以从这几个方向延伸。一个是把红外对管替换成摄像头用OpenMV或K210做真正的车牌识别。这会引入图像采集、字符识别、算法部署的新话题系统的完整度和技术深度立刻提升一个级别。另一个是把ESP8266换成支持MQTT协议的模组接入主流云平台实现手机App远程查看车位状态。再一个是用FreeRTOS把裸机状态机改造成多任务架构让系统具备实时操作系统的任务调度能力这也是嵌入式行业最关键的技术栈之一。如果你是冲着优秀毕业设计去的我的建议是先把本文这套基础功能吃透、调稳、写明白再挑一到两个扩展点做深做透。做透一个扩展点的价值远大于做十个半成品功能。这个道理不仅适用于毕业设计也适用于你后来在嵌入式领域里面对的每一个项目。6. 最后再说说源码资料和上手顺序很多同学拿到源码第一反应是打开main.c从头读到尾然后发现读不下去。源代码不是小说不需要按顺序看。我给你一个推荐的阅读顺序先读readme和硬件连接说明确认引脚对应关系再打开stm32f1xx_hal_conf.h看一下哪些外设被启用了然后打开main.c只看main函数里的初始化调用顺序和主循环结构最后再逐个模块看adc.c、pwm.c、uart.c这些功能文件。我自己重新理这套系统的源码时也是按照这个顺序从硬件到软件、从整体到局部逐步熟悉的。源码本身只是一个结果真正有价值的是你如何理解它的设计思路以及拿到它之后能不能自己复现、改写、扩展。毕业设计也好日常学习也好都是同一个过程先跑通再理解最后创造。把这三步走完这套STM32智能停车场系统才真正意义上变成了你的东西。本文还有配套的精品资源点击获取