项目编号
X504291| 主控 STM32F103C8T6 | 车位检测 红外感应模块 ×4(三路车位 + 一路禁停) | 身份识别 MFRC522(13.56 MHz) | 本地显示 OLED12864(I2C) | 执行 SG90 舵机 + 有源蜂鸣器 | 通信 ESP-01S + MQTT | 服务端 jeesite + SpringBoot + MySQL
摘要:本文介绍一套面向校园非机动车的车位监测与刷卡管理系统。硬件侧以 STM32F103C8T6 为主控,四路红外感应模块分别监测三个车位与一处禁停区域,MFRC522 读卡器读取校园卡 UID,OLED12864 就地显示学号、剩余车位数与出入时间,SG90 舵机承担道闸方向指示,有源蜂鸣器在无效卡与禁停告警时发声;ESP-01S 模组经 USART1 接入,以 MQTT 客户端的身份与上位机交换数据。服务端基于 jeesite 平台与 SpringBoot 框架构建,以 MySQL 完成数据持久化,并实现 MQTT 客户端与业务接口两侧的收发;网页端承担实时状态显示、车场地图标注、用户管理、停车记录查询、闸机管理与系统配置,把车位监测、刷卡识别、违规告警与远程开闸整合进同一套闭环。
一、技术栈速览
| 层次 | 技术选型 | 职责 |
|---|---|---|
| 主控 MCU | STM32F103C8T6(ARM Cortex-M3,最小系统板) | 四路车位状态采集、读卡时序、执行驱动与上报,Keil 5 固件开发 |
| 车位检测 | 红外感应模块 ×4(图纸位号 U5 / U6 / U8 / U9) | 三路装车位(DO 接 PA0 / PA2 / PA3),一路装禁停区(DO 接 PB0) |
| 身份识别 | MFRC522 射频读卡模块(ISO/IEC 14443 Type A) | SDA 接 PA7、SCK 接 PA6、MOSI 接 PA5、MISO 接 PA4、RST 接 PA1,IRQ 悬空 |
| 本地显示 | OLED12864 点阵屏(128×64,IIC 接口) | SCL 接 PB6、SDA 接 PB7,按预先取好的字模显示学号等固定内容 |
| 方向执行 | SG90 舵机(PWM 摆角 0~180°) | SIGNAL 接 PA8,按上位机下发的指令摆动,作道闸方向指示 |
| 声学提示 | 有源蜂鸣器(BUZZER1) | 信号端接 PB1,另一端接地;无效卡与禁停告警时鸣响 |
| 通信 | ESP8266(ESP-01S,USART1) | RX 接 PA9、TX 接 PA10,3V3 接 3.3 V,MQTT 发布与订阅 |
| 消息中转 | MQTT 服务器(broker-cn.emqx.io:1883) | EMQX 中国区提供的免费公共中转节点,按主题转发上下行报文 |
| 服务端 | jeesite + Java + SpringBoot + MySQL + Bootstrap | 业务接口、MQTT 客户端、人脸/卡号绑定判定与数据持久化 |
| 网页端 | 实时数据、车场地图、用户管理、停车记录、闸机与系统配置 | 1920×1040 桌面页面,地图用于标注各停车点位 |
二、系统架构设计
系统自下而上划分为感知执行层、控制层、网络层、服务层与应用层,层间以明确的接口解耦。这里的分层逻辑是:能在硬件就地完成的判定(禁停告警、无效卡提示)留在主控内,需要数据支撑的判定(绑卡还是出入库、停车时长)放在服务端。

图 1 系统总体架构图

图 2 系统功能结构图
从功能边界看,设备侧只做「采集 + 读卡 + 执行」三件事,卡片绑定关系、停车记录与车场参数全部集中在服务端。这样后续增加一个车位、或换用别的读卡器时,改动都落在设备侧与接口约定上,网页端照旧。
三、硬件系统设计

图 3 硬件系统原理框图
3.1 引脚分配
各外设与主控的连接关系由硬件原理图确定(嘉立创 EDA 绘制,同目录另附源文件与 PDF,PDF 版带完整文字层),一处值得留意的地方是:四路红外的四个数字输出端分散在 PA0 / PA2 / PA3 / PB0 上,并没有并到同一条中断线上。
| 连接对象 | 信号 | 引脚 | 说明 |
|---|---|---|---|
| 红外感应模块(车位1) | DO(数字输出) | `PA0` | 模块 VCC 接 5 V、GND 接地;车位占用时输出低电平。PA0 同时是 EXTI0 中断线 |
| 红外感应模块(车位2) | DO(数字输出) | `PA2` | 接线方式与车位1 相同,四路模块并不同用一条中断线 |
| 红外感应模块(车位3) | DO(数字输出) | `PA3` | 同上;三路车位状态共同决定「空闲车位」这一计数 |
| 红外感应模块(禁停区) | DO(数字输出) | `PB0` | 方案导图写明禁停区模块独立触发中断;PB0 同样是 EXTI0 的候选端口 |
| MFRC522 读卡 | SDA(片选)/ SCK / MOSI / MISO | `PA7 / PA6 / PA5 / PA4` | 四脚都落在硬件 SPI1 的引脚组里,但角色整体错位,详见第四章的逐线判断 |
| MFRC522 读卡 | RST(复位) | `PA1` | 按普通 GPIO 使用;IRQ 脚在本图中未连接 |
| OLED12864 | SCL / SDA | `PB6 / PB7` | 与硬件 I2C1 的默认分配完全一致,具备直接调用片上 I2C 外设的条件 |
| ESP8266 通信 | RX / TX(模组侧收发) | `PA9 / PA10` | 对应 USART1;模组 V 接 3.3 V、G 接地 |
| SG90 舵机 | SIGNAL(信号) | `PA8` | 另两端接 5 V 与 GND;PA8 默认映射即 TIM1 通道 1,具备硬件 PWM 条件 |
| 有源蜂鸣器 | 信号端 | `PB1` | 另一端接地,由主控 GPIO 直接驱动 |
作为二次开发时的速查,可直接复制下面这段引脚映射:
# X504291 校园非机动车管理系统 · 引脚映射(取自嘉立创 EDA 原理图,位号按图纸标注)
红外感应模块 车位1 DO=PA0 VCC=5V GND=GND # 占用时输出低电平
车位2 DO=PA2 # 接线方式与车位1 相同
车位3 DO=PA3 # 三路共同决定「空闲车位」计数
违停 DO=PB0 # 禁停区独立触发,与车位1 冲突见下
MFRC522 SDA=PA7 SCK=PA6 MOSI=PA5 MISO=PA4 RST=PA1
IRQ=未连接 # 3.3V 供电,13.56 MHz
# 注意:PA7/PA6/PA5/PA4 都落在硬件 SPI1 的引脚组里,
# 但 SPI1 默认是 NSS=PA4 / SCK=PA5 / MISO=PA6 / MOSI=PA7
# => 四路角色整体错位,读卡走 GPIO 模拟 SPI 时序
OLED12864 SCL=PB6 SDA=PB7 # 与硬件 I2C1 的默认分配完全一致
VCC=3V3 GND=GND # => 具备直接调用片上 I2C 的条件
ESP-01S RX=PA9 TX=PA10 # 对应 USART1,与模组 RX/TX 交叉
3V3=3.3V GND=GND
SG90 舵机 SIGNAL=PA8 # 另两端 5V / GND
# PA8 默认复用功能即 TIM1_CH1(高级定时器)
# => 舵机所需的 50 Hz PWM 可由硬件定时器直接产生,不必软件延时
有源蜂鸣器 1=PB1 2=GND # PB1 即 TIM3_CH4,各占一路定时器
# 四路红外落点的一处资源冲突
# PA0 与 PB0 同属 EXTI0 这一条外部中断线
# STM32 的外部中断按「线号」复用,同一条线上同一时刻只能挂一个端口引脚
# => 既然方案写明禁停区模块要独立触发中断,车位1 这一路只能走定时轮询
# 供电轨:3.3V —— MFRC522 / OLED12864 / ESP-01S
# 5V —— 四路红外模块 / SG90 舵机
3.2 原理图与实物

图 4 硬件原理图

图 5 硬件实物总览

图 6 板载器件与接线特写
装配采用扩展板加杜邦线,而非定制 PCB。样机阶段这一取舍降低了迭代成本:增减红外模块或调整舵机安装位置时只需调整插接位置。OLED 上显示的两帧内容值得一提:左图为刷卡瞬间的欢迎信息、卡号与学号,右图为出场瞬间的学号、出入时间与停车时长 ------ 汉字是提前取模固化的,所以屏幕只能显示预先取好的这几组内容。
一处素材情况需要如实说明:需要如实说明三处素材情况。第一,LED 灯未在原理图中绘制:项目名称的器件清单、方案导图的「传感器」一栏以及《项目介绍》都提到了 LED 灯(方案图写作「led 灯(若干)」,介绍里还描述了「车位占用时对应 LED 亮红灯,空闲亮绿灯」的规则),但本项目原理图上并没有任何 LED 器件 ------ 对导出图纸做全文检索,「LED」「灯」两个词只命中 OLED12864 这一处,元件清单里也只有主控、读卡器、显示屏、无线模组、舵机、蜂鸣器与四路红外模块。本文的硬件描述以原理图为依据,因此不列 LED 这一项。第二,蜂鸣器的驱动方式存在口径差异:图纸把该器件标注为「有源蜂鸣器」,而《项目介绍》写的是「蜂鸣器通过 PWM 驱动」。有源蜂鸣器内部自带振荡电路,通常给出电平即可发声,本文按图纸标注记名,按介绍记录驱动描述,两者并列而不强求统一。第三,主控主频的表述:《项目介绍》提到主控「支持 16 MHz 主频」,而 STM32F103C8T6 的 Cortex-M3 内核最高可运行在 72 MHz,16 MHz 更接近外部高速晶振(HSE)的常见取值;本文按「主控运行于 STM32F103C8T6 平台」表述,不引用该频率数值。
四、通信链路设计
设备与上位端之间不建立直连,全部经 MQTT 服务器中转:设备侧订阅一条主题等待指令,向另一条主题发布采集结果;服务端以 MQTT 客户端身份做同样的两件事。双方互不知道对方地址,只按主题收发。

图 7 系统数据交互时序图
| 链路 | 协议 / 方式 | 说明 |
|---|---|---|
| 无线承载 | Wi-Fi 2.4 GHz(STA 模式) | 默认热点名 8266wifi、密码 123456789;可用电脑或手机开热点接入 |
| 应用层协议 | MQTT 发布 / 订阅 | 网页端与硬件之间不直连,全部经 MQTT 服务器中转,双方各自维护一条长连接 |
| MQTT 服务器 | broker-cn.emqx.io | EMQX 中国区提供的免费公共中转节点;方案里注明也可改用自建 EMQX |
| 数据上报主题 | mybs/bsdata/2462AB65F2F2 | 硬件向该主题发布车位状态、刷卡记录与禁停告警,网页端订阅后刷新界面 |
| 指令下发主题 | mybs/bsctr/2462AB65F2F2 | 网页端向该主题发布指令,硬件订阅后执行;两条主题仅中段一词不同 |
| 设备标识 | 主题末段即设备标识 2462AB65F2F2 | 主题前缀固定为 mybs,末段换成另一块板子的标识即可并存多套设备 |
| 调试观测 | MQTTX 等 MQTT 客户端 | 在电脑端订阅同一主题即可完整观察「下发---执行---上报」的交互过程 |
4.1 主题命名与配网
两条主题名只差中间一个词:bsdata 用于上报、bsctr 用于下发,末段是设备标识;前缀 mybs 为项目命名前缀。同一台服务器因此可以挂载多套车场而互不串扰;排查问题时只要知道设备标识,就能单独订阅它的两条主题观察数据流。下面这段是配网说明里的原始参数,可逐字对照:
# X504291 校园非机动车管理系统 · MQTT 与配网参数(原文抄录)
1、mqtt服务器 使用的是 broker-cn.emqx.io
该地址为 EMQX 中国区提供的免费 mqtt 中转服务器;稳定性尚可;
可用 MQTTX 等客户端进行数据通信过程监控。
2、默认 wifi 信息
SSID : 8266wifi
密码 : 123456789
-- 可使用电脑开热点
-- 也可使用手机开热点(名称改为 8266wifi,密码改为 123456789)
3、订阅的主题
上位机向硬件下发指令:mybs/bsctr/2462AB65F2F2
硬件向上位机上报数据:mybs/bsdata/2462AB65F2F2
# 主题命名规律
# 前缀 mybs 固定;中段 bsctr / bsdata 区分方向;末段为设备标识
# => 换成另一块板子的标识即可并存多套设备
# 调试观测
# 可在电脑端用 MQTT 客户端工具订阅上述两条主题,实时查看数据通信过程。
4.2 一次刷卡入场的完整往返
以「刷一次卡进出车棚」为例,把学生、网页端、服务端、MQTT 服务器与主控五个节点之间的往返拆开,可以得到十二步时序:
1 STM32 红外模块检测到车位被占用,DO 由高变低
2 STM32 读卡器读到校园卡 UID(示例 A95FB105),缓存在主控
3 STM32 -> ESP-01S 组装报文,向 mybs/bsdata/<标识> 发布卡号与车位状态
4 ESP-01S -> MQTT 按订阅关系把上行报文推给服务端
5 服务端 MQTT 客户端收报:写进出记录,判定本次是绑卡还是出入库
6 服务端 -> Web 页面刷新:实时状态卡片与停车记录列表同步更新
7 Web 车场地图上对应点位与记录表出现这一条,供人工核对
8 服务端 -> MQTT 判定结果转成指令,向 mybs/bsctr/<标识> 发布
9 MQTT -> ESP-01S 按订阅关系把下行报文推给设备
10 STM32 主控解析指令:驱动 SG90 舵机摆动开闸,OLED 刷新显示
11 STM32 若为未绑定卡:蜂鸣器鸣响,屏幕提示「无效卡,请联系管理员」
12 STM32 禁停区被占用:蜂鸣器告警并上传告警数据,不等网络确认
其中第 5、11、12 三步值得单独说明:「是绑卡还是出入库」必须由服务端判定,因为卡片里不存任何身份信息;而无效卡提示与禁停告警这两件事由主控就地完成,与上行链路在时间上没有依赖关系,即便此刻网络不通,禁停区被占用时仍会就地鸣响。
4.3 现有固件的四处接口特征
把嘉立创 EDA 源文件里的网络标号提取出来、按坐标还原成「引脚号---引脚名---网络标号」的对应关系,再与导出的 PDF 文字层和图像交叉核对,可以确认四处与常规写法不同的地方:
# 特征一:读卡走 GPIO 模拟 SPI 时序,而非片上 SPI1 外设
MFRC522 的 SDA(片选) / SCK / MOSI / MISO 分别接在 PA7 / PA6 / PA5 / PA4 上。
而 STM32F103 的硬件 SPI1 默认功能分配是 NSS=PA4、SCK=PA5、MISO=PA6、MOSI=PA7 ——
四个脚虽然都落在 SPI1 的引脚组里,但各自承担的是另一根线的角色,四路整体错位。
硬件外设的引脚功能是固定的,无法这样接线后照常工作,
# => 读卡采用通用 IO 逐位模拟 SPI 时序的写法。
# 另有两点佐证:RST 独占 PA1 当普通 IO 用,IRQ 则悬空未接。
# 特征二:显示屏接线恰好与硬件 I2C1 的默认分配吻合
OLED12864 的 SCL 接 PB6、SDA 接 PB7,而 STM32F103 的硬件 I2C1 默认功能分配
正是 SCL=PB6、SDA=PB7,两者完全一致。
# => 这块屏具备直接调用片上 I2C1 外设的条件,不必再用通用 IO 模拟时序。
# 同一块主控上,I2C 走硬件通道、SPI 走软件时序,两条总线取向不同。
# 特征三:舵机信号脚落在高级定时器的通道 1 上
SG90 的 SIGNAL 接 PA8,PA8 的默认复用功能就是 TIM1 的通道 1;
TIM1 属于 STM32F103 上的高级定时器,本身就是为电机与舵机这类波形输出准备的。
# => 产生舵机所需的 50 Hz 脉宽调制波形不必依赖软件延时翻转电平。
# 蜂鸣器接 PB1(TIM3_CH4),两者各占一路定时器,互不挤占。
# 特征四:四路红外的落点埋着一处外部中断线冲突
四路红外模块的数字输出分别接 PA0、PA2、PA3、PB0。
其中 PA0 与 PB0 同属 EXTI0 这一条外部中断线 ——
STM32 的外部中断按「线号」复用,同一条线上同一时刻只能挂一个端口的引脚,
所以这两路不可能同时以中断方式工作。
# => 既然方案写明禁停区模块要独立触发中断,车位1 这一路只能走定时轮询。
五、业务数据模型
以下字段均取自系统实际运行界面,可作为二次开发时的建表参考。
# 用户管理(实测字段)
姓名 电话 RFID 学号 班级 更新时间
-- 实测:冯军 / (手机号,本文已遮蔽) / A95FB105 / 21020829 / 通信2101
-- RFID 一栏即校园卡 UID,是绑卡与出入库共用的主键
-- 查询条件为姓名与电话,支持模糊检索
# 车场闸机管理(实测字段)
闸机编号 闸机名称 安装地址 车位1 车位2 车位3 禁停区域 online 更新时间 操作
-- 实测:ZDBH01 / 停车场出入闸A / 常州工学院图书馆
-- 空闲 / 空闲 / 空闲 / 正常 / 在线 / 2025-05-02 15:49:56
-- 同一台闸机名下挂三个车位,正好对应三路车位红外模块
# 系统配置 / 配置项管理(实测 8 条,三类)
参数名称 类型 参数项 参数值 备注 更新时间 操作
-- 车位总数 / 1 / cwzs / 20
-- 班级 / bj / 通信2101 / 经管2101 / 计算机2101 / 计算机2102
-- 坐标 / zb / 教学楼 / 119.950236,31.875963 / 共有车位15个
-- 坐标 / zb / 图书馆 / 119.952463,31.874886 / 共有车位20个
-- 坐标 / zb / 后勤服务中心 / 119.952455,31.878504 / 共有车位30个
-- 换校区部署时只需改这三类配置,无需改代码或重新烧录固件
# 停车记录查询(实测字段)
停车卡编号 姓名 学号 班级 入库时间 出库时间 停车时长(分钟) 闸机编号 备注 操作
-- 实测:共 21 条,每页 20 条,共 2 页
-- 在停样本:A95FB105 / 冯军 / 21020829 / 通信2101
-- 2025-05-02 15:38:56 / (空) / (空) / ZDBH01
-- 完成样本:62F18405 / 赖雅涵 / 21660001 / 通信2101
-- 2025-05-02 15:33:18 / 2025-05-02 15:33:18 / 0 / ZDBH01
-- 停车时长由服务端用出入库时间相减得到,不是硬件上报的字段
-- 同一张卡一天内可出现多次记录:系统如实记录每一次刷卡事件
# 实时状态(实测 8 项,2025-05-02 15:50:05)
车位总数 20 空闲车位 19 闸机状态 关闭
车位1 空闲 车位2 空闲 车位3 空闲 禁停区域 正常 设备状态 在线
-- 「20 与 19」不相等,说明当下有一辆车停在别处
-- 这辆车既不在三个受监测车位上、也不在禁停区,说明覆盖面有限
# 百度地图坐标拾取(实测)
定位到「常州工学院」,页面右上角当前坐标:119.849567,31.879009
-- 配置项里的三条坐标即由该工具量出后填入
把实时状态与停车记录放在一起看,系统的数据流就完整了:硬件在车位变化与刷卡时上报,服务端逐条落库并做业务判定,实时页读最新状态,记录页按车牌检索历史。
| 字段分组 | 字段 | 说明 |
|---|---|---|
| 实时状态 | 车位总数 / 空闲车位 / 闸机状态 | 三项随硬件上报实时刷新;闸机状态取「开启」或「关闭」 |
| 实时状态 | 车位1 / 车位2 / 车位3 / 禁停区域 / 设备状态 | 三个车位各占一张卡,取「空闲」或「占用」;禁停区域取「正常」或「告警」;设备状态取「在线」或「离线」 |
| 进出记录 | 停车卡编号 / 姓名 / 学号 / 班级 / 入库时间 / 出库时间 / 停车时长(分钟) / 闸机编号 / 备注 | 按车牌号码检索,可分页;停车时长由出入时间自动算得 |
| 用户管理 | 姓名 / 电话 / RFID / 学号 / 班级 / 更新时间 | 按姓名与电话检索;RFID 一栏即校园卡的 UID,是绑卡与出入库的主键 |
| 车场参数 | 总车位数 / 远程开闸 | 总车位数可在线改写并保存;远程开闸为一次性动作,点一次开一次 |
方案阶段还明确了几条设计意图,它们解释了系统为什么长成现在这个样子:
| 方面 | 设计意图 | 说明 |
|---|---|---|
| 显示方式 | 硬件显示的汉字提前取模固定 | OLED 上的汉字用固化字模,所以只能显示预先取好的内容,学号是其中一项 |
| 红外分工 | 三个红外表示车位、一个表示禁停区域 | 四路红外不是同一用途:三路配合状态显示占用情况,一路专门盯禁停区 |
| 绑定逻辑 | 每次读卡后把卡号传给上位机,由上位机判断是绑卡还是出入库 | 硬件只负责读卡与上报,业务判定全部放在服务端,这是一条明确的分工线 |
| 告警条件 | 未绑定的卡刷卡时蜂鸣器报警、屏幕显示「无效卡,请联系管理员」 | 禁停区域检测到停放后,蜂鸣器告警并由硬件上传告警数据 |
| 屏幕内容 | 显示车位数量与出入时间 | 屏幕不承担录入功能,只做就地状态提示 |
| 权责划分 | 学生注册登录后可查询自己的停车记录,管理员查询所有记录 | 同一套页面按角色区分数据范围 |
其中「显示方式」这一条值得单独说明:OLED 上的汉字提前取模固化。因此屏幕只能显示预先取好的内容,学号是其中一项。这解释了两个现象:一是屏幕上不会出现任意文本;二是硬件与网页端显示的信息并不完全一致 ------ 网页端可以从数据库取任意字段,屏幕只能显示那几组字模。方案里同时写明「屏幕不承担录入功能,只做就地状态提示」,这一点属于有意划定的边界。
六、界面实测
网页端界面按「监控为主、配置为辅」的思路组织,登录后即进入实时状态页。需要说明的是:本项目界面截图是 1920×1040 的桌面网页,在正文栏宽下会缩放到不足一半,界面小字难以辨认,因此每一项字段的具体取值在正文中一并写明,图片主要承担「界面形态」的证据作用。
关于隐私:本项目界面截图中,用户管理页含一个真实手机号,已作模糊遮蔽处理并逐像素自校验;其余内容为演示数据,姓名与学号未作改动。
6.1 系统登录与用户注册
系统以校园共享单车棚的实景照片作为登录页背景,页面上只保留系统名称「校园非机动车管理系统」、登录账号、登录密码与登录按钮四项元素,未登录时不展示任何监控或记录数据,按钮下方另有一行「注册」入口。注册页是独立的一套表单,字段依次为手机号码(同时作为登录账号)、用户姓名、学号、所在班级、登录密码与再次登录密码,提交后由服务端校验账号是否重复,页面底部给出「提交」与「返回」两个按钮。

图 8 登录页与用户注册页
这两页配合,构成了账号从产生到使用的完整入口。需要留意的是,注册填写的学号与班级并不会直接写进硬件 ------ 读卡器读到的只是卡的 UID,学号与班级是服务端在绑卡环节补上的。也正因为如此,网页端的用户管理页才有「RFID」与「学号」两列需要人工对应。
6.2 实时数据展示与车场地图
实时数据页是系统的第一屏:顶端给出更新时间与车场编号下拉框;中间是八项实时数据卡片;下方是车场参数设定区;右侧固定一张百度地图,用于标注各停车点的位置。

图 9 实时数据展示与车场地图
实测截取的一帧为:更新时间 2025-05-02 15:50:05、车位总数 20、空闲车位 19、闸机状态 关闭、车位1 空闲、车位2 空闲、车位3 空闲、禁停区域 正常、设备状态 在线。这帧数据里有两点值得注意:一是「车位总数 20 与空闲车位 19」并不相等,说明当下确有一辆车停在别处,而这辆车既没有落在三个受监测车位上、也没有落在禁停区 ------ 这恰好说明了三路车位检测的覆盖面是有限的;二是「闸机状态 关闭」与「设备状态 在线」同时出现,反映的是截图当下设备已联网、而舵机尚未动作的静止状态。
车场参数设定区提供两个操作:一是把「总车位数」改写后点保存,二是点一次「单次开闸」远程放行。把开闸做成一次性动作而不是一个开关,是为了让每一次点击都对应一条确定的 MQTT 报文 ------ 限定为单次动作就不存在「忘记关回去」的状态。地图上的三个红点分别标注了后勤服务中心、教学楼与图书馆,标签上直接写出各点位的车位数量。
6.3 停车记录查询
停车记录页承担出入库的追溯。页面顶部只提供一个查询条件:车牌号码;查询与重置按钮并排放在输入框右侧;表格下方是分页条,页脚同时给出「当前第几页、每页多少条、共多少条」三项信息。表格字段包含停车卡编号、姓名、学号、班级、入库时间、出库时间、停车时长(分钟)、闸机编号、备注与操作十列。

图 10 停车记录查询页
实测该查询共 21 条记录,每页显示 20 条,共 2 页。抽取其中两条来看:
# 在停样本(车已入棚、尚未出场)
停车卡编号 A95FB105 姓名 冯军 学号 21020829 班级 通信2101
入库时间 2025-05-02 15:38:56
出库时间 (空) 停车时长 (空) 闸机编号 ZDBH01
# 完成样本(进出时间几乎重合的瞬时记录)
停车卡编号 62F18405 姓名 赖雅涵 学号 21660001 班级 通信2101
入库时间 2025-05-02 15:33:18
出库时间 2025-05-02 15:33:18 停车时长 0 分钟 闸机编号 ZDBH01
# 字段来源说明
# 停车卡编号 / 姓名 / 学号 / 班级 —— 由服务端按 RFID 关联用户表得到
# 入库时间 / 出库时间 —— 由服务端在收到上报报文时打时间戳
# 停车时长 —— 服务端用出入库时间相减得到
# => 硬件只上报卡号与车位状态,其余字段全部是服务端派生出来的
演示目录里另有一张以学生身份打开的同名页面,字段完全相同,只是记录条数从 21 条变成 12 条 ------ 同一套页面,学生登录后只会看到自己的记录,管理员看到的是全部记录。
6.4 用户管理与系统配置
用户管理页承担卡片与人的对应关系维护,表格字段包含姓名、电话、RFID、学号、班级、更新时间与操作七列,查询条件为姓名与电话,其中「RFID」一栏即校园卡的 UID,它是绑卡与出入库共用的主键。系统配置页则是另一套入口,把车位总数、班级字典与地图坐标统一收敛成「配置项」,字段为参数名称、类型、参数项、参数值、备注、更新时间与操作。

图 11 用户管理与系统配置页
用户管理页实测注册了 1 条记录:姓名 冯军、RFID A95FB105、学号 21020829、班级 通信2101、更新时间 2025-05-02 12:24,电话一栏在本文中已作模糊处理。系统配置页实测共 8 条参数,可以分成三类:第一类是车位总数(参数项 cwzs,取值 20);第二类是班级字典,把 通信2101、经管2101、计算机2101 与 计算机2102 四个班级编码成下拉选项;第三类是地图坐标,把教学楼、图书馆与后勤服务中心三个点位连同各自的经纬度与车位数量一起写进配置。三类参数放在同一个入口维护,换一个校区部署时不需要改动任何一行代码或重新烧录固件。
6.5 车场坐标拾取与闸机信息
配置页里的经纬度不是凭空写出来的,而是先用百度地图的坐标拾取系统量出来再填进去。拾取系统把地图定位到常州工学院,页面右上角实时显示当前坐标,右侧列出各校区的详细地址与坐标,复制过来即可作为地图点位的初始值。闸机信息管理页则记录每一台闸机的安装位置与它名下三个车位的状态。

图 12 车场坐标拾取与闸机信息页
实测在拾取系统中把地图定位到常州工学院,当前坐标为 119.849567,31.879009。闸机信息管理页实测登记了 1 台闸机:闸机编号 ZDBH01、闸机名称 停车场出入闸A、安装地址 常州工学院图书馆、车位1/车位2/车位3 均为 空闲、禁停区域 正常、online 状态 在线、更新时间 2025-05-02 15:49:56。这里有一条可以交叉验证的线索:闸机的安装地址是图书馆,而配置页里图书馆这一条的车位数量恰好是 20 个,与实时页显示的「车位总数 20」完全一致 ------ 说明这两处的数字来自同一份配置,而不是各自填写的。
七、工程要点
① 判定分两层放。 能在硬件就地完成的(禁停告警、无效卡提示)全部留在主控侧,保证断网时仍然有效;需要数据支撑的(是绑卡还是出入库、停车时长怎么算)统一放在服务端,保证规则调整不必重新烧录固件。
② 两端互不知道对方地址。 设备与网页端都只面对 MQTT 服务器,按主题收发。车场换位置、服务端换部署机器,都不影响对接。
③ 主题末段用设备标识寻址。 同一台服务器可挂载多套车场而互不串扰;排障时只要知道设备标识,就能单独订阅它的两条主题。
④ 四路红外分两种采样方式。 PA0 与 PB0 同属 EXTI0,既然禁停区要独立触发中断,车位1 就只能走定时轮询。把中断资源优先留给「必须立刻响应」的那一路,是嵌入式选脚时常见的取舍。
⑤ 同一块板上两条总线的取向不同。 读卡器的四根线与 SPI1 默认分配整体错位,走的是 GPIO 模拟时序;显示屏的两根线恰好与 I2C1 默认分配吻合,可以直接调用片上外设。选脚时顺手对一下外设默认映射,能省下不少调试时间。
⑥ 供电轨要区分。 四路红外模块与 SG90 舵机取 5 V,MFRC522、OLED12864 与 ESP-01S 取 3.3 V,同一块扩展板并存两条轨,接线时需逐线核对 ------ 舵机堵转瞬间电流较大,与低压器件分开取电可以避免主控复位。
⑦ 配置项是部署成本的关键。 车位总数、班级字典与地图坐标全部做成配置项,换校区时只改数据不改代码。这一点在演示环境里看不出价值,但在真实部署时能省掉一次重新编译与烧录。
⑧ OLED 走固定字模。 屏幕内容提前取模固化,好处是不用带字库、占 Flash 极小,代价是显示内容不可动态扩展。这类取舍在资源紧张的 MCU 上很常见,但要在需求阶段就与「屏幕要显示哪些内容」对齐,否则后期加一项就要重新取模。
八、演示与获取

图 13 演示视频封面
完整的演示视频记录了整机接线与上电、刷卡时舵机的动作与 OLED 内容切换,以及网页端从登录到停车记录查询的全过程,片长约 8 分 42 秒。
如需本项目的完整资料,可在评论区留言或私信,说明需要的项目编号 X504291 及用途(学习 / 二次开发 / 课程设计),以便提供对应的资料组织方式。
| 交付内容 | 形式 |
|---|---|
| 硬件实物 | 已装配并完成联调的整机(扩展板 + 杜邦线) |
| 程序源码 | STM32F103C8T6 固件工程与 Java 服务端 + 网页端工程 |
| 硬件原理图 | 嘉立创 EDA 源文件(json / schdoc)及导出的图像与文档 |
| 演示视频 | 系统完整运行的演示录像(约 8 分 42 秒) |
| 技术支持 | 远程协助环境搭建、程序调试与小规模修改答疑 |
项目编号 X504291。本文所述系统的引脚分配、通信参数、界面字段与实测数值均逐项取自硬件原理图、配网说明与系统运行截图;界面中的卡片编号、学号与车位数据为演示数据,其中手机号已作遮蔽处理;相关技术问题可在评论区交流。