news 2026/9/16 15:26:23

STM32F103驱动SX1278 LoRa物理层通信实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
STM32F103驱动SX1278 LoRa物理层通信实战

简介:本资源是一套基于STM32F103ZET6与LoRa模块(如SX1276/SX1278)的完整无线通信实验工程,面向嵌入式初学者及物联网开发实践者,聚焦LoRa远距离低功耗通信的底层驱动与协议配置。项目覆盖SPI接口初始化、LoRa参数(扩频因子、带宽、编码率)设置、收发函数实现及中断处理等核心环节,适配Keil uVision开发环境,采用HAL库构建,可直接用于课程实验、毕业设计或LoRa节点原型开发。压缩包含99个文件,以48个.h头文件和41个.c源码为主,辅以README说明、JLink调试配置、HEX固件及批处理脚本,结构清晰,模块化程度高,便于理解硬件抽象层与LoRa驱动逻辑。目前已有2978人学习下载,资源体积仅322KB,轻量实用,提供从硬件连接到数据收发的端到端可运行参考,显著降低LoRa在STM32平台上的入门门槛。

1. STM32F103 + LoRa 实现远距离低功耗无线通信,不是堆模块而是调通物理层链路

你手上有块 STM32F103C8T6 最小系统板,买了 SX1278 模块(常见标“LoRa”字样的紫红色 PCB),接上天线、供电、SPI 线,Keil 编译通过却收不到对端发来的数据包——不是代码没烧,而是 SPI 时序没对齐、寄存器配置漏了关键位、LoRa 模式参数不匹配。这不是“STM32 跑个 LoRa demo”的教学幻觉,而是真实产线调试中卡在RegIrqFlags始终为 0、RegOpMode读出来是 0x00 的硬伤现场。本文面向已能点亮 LED、用 HAL_SPI_Transmit 接口发数据、但尚未让 LoRa 收到一帧有效 payload 的工程师:不讲抽象协议栈,只拆解从 STM32F103 标准库(v3.5)驱动 SX1278 的最小可通信闭环——包括如何验证 SPI 连通性、为什么必须手动配置 LORA_SYNC_WORD、怎样用逻辑分析仪抓出RegFifoTxBaseAddr写入失败的时序缺口、以及为何PA11/PA12在 LoRa 应用中要避开 USB 功能冲突。适合正在做智能水表、农业传感器节点、或毕业设计需实测 2km 通信距离的开发者。

2. 用标准库 v3.5 驱动 SX1278:SPI 初始化与寄存器级通信验证

LoRa 模块不是即插即用的 UART 设备,SX1278 本质是一颗射频 SoC,所有功能依赖对 128 个寄存器的精确读写。STM32F103 标准库 v3.5 提供稳定底层支持,但需绕过 HAL 库的抽象层直接操作寄存器,才能控制时序关键点(如 NSS 电平切换时机)。本节给出可复现的初始化路径,重点解决“烧录后RegVersion读不出”、“SPI 通信无响应”两类高频问题。

2.1 硬件连接与 NSS 控制逻辑

SX1278 的 NSS 引脚必须由 MCU 软件精确控制:拉低时启动一次 SPI 事务,拉高则结束。常见错误是将 NSS 接到 STM32 的硬件 NSS(PA4),导致 SPI 外设自动管理电平,与 SX1278 的时序要求冲突。正确接法如下:

SX1278 引脚STM32F103 引脚说明
NSSPA4(软件模拟,非硬件 NSS)必须用 GPIO_WriteBit() 手动控制
SCKPA5SPI1_SCK
MISOPA6SPI1_MISO
MOSIPA7SPI1_MOSI
RESETPB0低电平复位,需上电后延时 10ms 再拉高
DIO0PA0中断引脚,接收完成触发

注意:PA11/PA12 是 USB DP/DN,默认启用时会干扰 SPI1 的 PA6/PA7(因复用功能冲突)。若项目未用 USB,务必在RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_AFIO, ENABLE)后执行GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE)关闭 JTAG 并释放 PA11/PA12,否则 SPI 读写必然失败。

2.2 SPI1 初始化(标准库 v3.5)

以下代码基于stm32f10x_conf.h已包含stm32f10x_spi.hstm32f10x_gpio.h

void SPI1_Init(void) { SPI_InitTypeDef SPI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOA | RCC_APB2PERIPH_GPIOB | RCC_APB2PERIPH_SPI1, ENABLE); // PA4 (NSS), PA5 (SCK), PA6 (MISO), PA7 (MOSI) 配置为复用推挽 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // PB0 (RESET) 配置为推挽输出 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOB, &GPIO_InitStructure); // SPI1 初始化:主模式,CPOL=0 CPHA=0,波特率预分频=4(72MHz/4=18MHz,SX1278 最高支持 10MHz,安全) SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; SPI_InitStructure.SPI_Mode = SPI_Mode_Master; SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; // 空闲时钟低电平 SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; // 第一跳变沿采样 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; // 软件控制 NSS SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_Init(SPI1, &SPI_InitStructure); SPI_Cmd(SPI1, ENABLE); }
参数说明:
  • SPI_BaudRatePrescaler_4:Fpclk2=72MHz → SCK=18MHz,SX1278 允许最高 10MHz,此处留余量;若通信不稳定,可降为_8(9MHz)。
  • SPI_CPOL_Low&SPI_CPHA_1Edge:SX1278 数据手册明确要求 CPOL=0, CPHA=0(即空闲低电平,上升沿采样),与多数 LoRa 模块标注的 “SPI Mode 0” 一致。
  • SPI_NSS_Soft:强制软件控制 NSS,避免硬件 NSS 导致的时序错位。

2.3 寄存器读写函数与RegVersion验证

SX1278 的寄存器地址为 8 位(0x00–0x4F),读写需遵循特定格式:写操作发送0x80 | addr,读操作发送addr。以下函数实现单字节读写,并加入超时机制防止死循环:

uint8_t SX1278_ReadRegister(uint8_t addr) { uint8_t data; GPIO_ResetBits(GPIOA, GPIO_Pin_4); // NSS = 0 SPI_I2S_SendData(SPI1, addr); // 发送地址(读模式) while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); SPI_I2S_ReceiveData(SPI1); // 清空 RX FIFO SPI_I2S_SendData(SPI1, 0x00); // 发送 dummy byte 触发读 uint32_t timeout = 10000; while ((SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET) && --timeout); if (timeout == 0) return 0xFF; data = SPI_I2S_ReceiveData(SPI1); GPIO_SetBits(GPIOA, GPIO_Pin_4); // NSS = 1 return data; } void SX1278_WriteRegister(uint8_t addr, uint8_t value) { GPIO_ResetBits(GPIOA, GPIO_Pin_4); // NSS = 0 SPI_I2S_SendData(SPI1, 0x80 | addr); // 写地址(高位 1) while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); SPI_I2S_ReceiveData(SPI1); // 清空 RX FIFO SPI_I2S_SendData(SPI1, value); // 发送数据 while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); GPIO_SetBits(GPIOA, GPIO_Pin_4); // NSS = 1 }
验证步骤:
  1. 上电后执行GPIO_ResetBits(GPIOB, GPIO_Pin_0); Delay_ms(10); GPIO_SetBits(GPIOB, GPIO_Pin_0);复位 SX1278;
  2. 调用SX1278_ReadRegister(0x42)读取RegVersion,正常值应为0x12(SX1278)或0x22(SX1276);
  3. 若返回0xFF,检查:NSS 是否真拉低、SPI 时钟是否使能、PA4 是否被其他外设占用、逻辑分析仪抓SCK/MOSI/MISO是否有波形。

提示:用 Saleae Logic 抓 SPI 波形时,重点观察NSS下降沿后SCK是否立即启动,且MOSI发送的地址字节是否为0x42(读)或0xC0(写 0x40 地址)。若MOSI全为 0x00,说明SPI_I2S_SendData()未生效,需检查SPI_Cmd(SPI1, ENABLE)是否遗漏。

3. LoRa 模式配置与最小收发闭环:从空闲到收到第一帧数据

RegVersion验证通过后,不能直接发包——SX1278 默认处于 FSK 模式,必须显式切换至 LoRa 模式并配置关键参数。本节给出可直接运行的初始化序列,覆盖RegOpModeRegModemConfig1/2RegPaConfig等 12 个核心寄存器,并解释每个值的物理意义。

3.1 LoRa 模式使能与基础参数设定

以下函数将 SX1278 置于 LoRa 接收模式(RX),中心频率 433MHz,扩频因子 SF7,带宽 BW125kHz,编码率 CR4/5:

void SX1278_LoRaInit(void) { // 步骤1:进入 Sleep 模式(0x00) SX1278_WriteRegister(0x01, 0x00); Delay_ms(10); // 步骤2:设置 LoRa 模式(RegOpMode = 0x80) SX1278_WriteRegister(0x01, 0x80); // LoRa mode, sleep // 步骤3:配置 LoRa 参数(关键!) SX1278_WriteRegister(0x1D, 0x72); // RegModemConfig1: BW125kHz, CR4/5, ImplicitHeader=0 SX1278_WriteRegister(0x1E, 0xC5); // RegModemConfig2: SF7, TxContOn=0, RxPayloadCrcOn=0, SymbTimeout=0x05 SX1278_WriteRegister(0x26, 0x04); // RegModemConfig3: LowDataRateOptimize=0, AgcAutoOn=1 // 步骤4:设置频率(433MHz → 0x6C 0x80 0x00) SX1278_WriteRegister(0x06, 0x6C); // RegFrfsMsb SX1278_WriteRegister(0x07, 0x80); // RegFrfsMid SX1278_WriteRegister(0x08, 0x00); // RegFrfsLsb // 步骤5:设置输出功率(+17dBm,PA_BOOST 使能) SX1278_WriteRegister(0x09, 0xFF); // RegPaConfig: PaSelect=1, MaxPower=0x0F, OutputPower=0x0F → +17dBm SX1278_WriteRegister(0x0A, 0x09); // RegPaRamp: ramp time = 3.4ms // 步骤6:设置 LORA_SYNC_WORD(默认 0x12,但需显式写入) SX1278_WriteRegister(0x39, 0x12); // RegSyncWord // 步骤7:配置 FIFO(TX/RX 基地址均为 0x00) SX1278_WriteRegister(0x0E, 0x00); // RegFifoTxBaseAddr SX1278_WriteRegister(0x0F, 0x00); // RegFifoRxBaseAddr // 步骤8:进入 RX 连续模式 SX1278_WriteRegister(0x01, 0x85); // RegOpMode = 0x85 → LoRa, RXCONTINUOUS }
关键寄存器解析:
寄存器地址名称物理含义
0x01RegOpMode0x800x850x80: LoRa+Sleep;0x85: LoRa+RXCONTINUOUS(持续监听)
0x1DRegModemConfig10x72Bit7-6: BW=125kHz;Bit5-3: CR=4/5;Bit2-0: HeaderMode=Explicit(显式头)
0x1ERegModemConfig20xC5Bit7-4: SF=7;Bit2: CRC关闭(调试阶段建议关);Bit1-0: SymbTimeout=5(符号超时)
0x39RegSyncWord0x12同步字,收发双方必须一致,否则无法解调。常被忽略导致“收不到包”

3.2 发送一帧数据并验证 DIO0 中断

发送流程:写 FIFO → 设置 IRQ 映射 → 切换至 TX 模式 → 等待 DIO0 上升沿(TX Done):

void SX1278_SendPacket(uint8_t *data, uint8_t len) { uint8_t i; // 1. 写入 FIFO for (i = 0; i < len; i++) { SX1278_WriteRegister(0x00, data[i]); // RegFifo,自动递增地址 } // 2. 设置 IRQ 映射:DIO0 = TxDone SX1278_WriteRegister(0x40, 0x40); // RegDioMapping1: DIO0=01 (TxDone) // 3. 切换至 TX 模式 SX1278_WriteRegister(0x01, 0x83); // RegOpMode = 0x83 → LoRa, TX // 4. 等待 DIO0 上升沿(需外部中断或轮询) while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == RESET); // PA0 = DIO0 }
接收流程(轮询方式,避坑版):
uint8_t SX1278_ReceivePacket(uint8_t *buffer, uint8_t *len) { uint8_t irqFlags, rxNbBytes; // 读取 IRQ 标志 irqFlags = SX1278_ReadRegister(0x12); // RegIrqFlags if ((irqFlags & 0x40) == 0) return 0; // RxDone 未置位 // 读取接收长度 rxNbBytes = SX1278_ReadRegister(0x13); // RegRxNbBytes if (rxNbBytes == 0 || rxNbBytes > 64) return 0; // 读取 FIFO 数据 SX1278_WriteRegister(0x0D, 0x00); // RegFifoAddrPtr = 0x00(指向 RX 起始) for (uint8_t i = 0; i < rxNbBytes; i++) { buffer[i] = SX1278_ReadRegister(0x00); // RegFifo } *len = rxNbBytes; // 清除 IRQ 标志 SX1278_WriteRegister(0x12, 0xFF); // RegIrqFlags 写 1 清零 return 1; // 成功接收 }
验证方法:
  • 发送端调用SX1278_SendPacket("HELLO", 5)
  • 接收端在while(1)中轮询SX1278_ReceivePacket(),成功后用串口打印buffer
  • 若始终不进if ((irqFlags & 0x40) == 0),检查:RegIrqFlagsMask是否被误写、DIO0 是否接错引脚、RegFifoRxBaseAddr是否为 0x00(否则读 FIFO 地址偏移)。

4. STM32F103 与 LoRa 的协同优化:降低功耗、提升抗干扰与调试技巧

当基础收发跑通后,实际部署会遇到新问题:电池供电节点续航不足、工业现场存在同频干扰、长距离通信丢包率高。本节不讲理论,只给 STM32F103 可落地的优化手段,全部基于标准库 v3.5 和 SX1278 寄存器操作。

4.1 低功耗设计:从 23mA 待机降到 1.8μA

SX1278 的 Sleep 模式电流约 1.8μA,但 STM32F103 若未关闭外设时钟,整体功耗仍达 23mA。关键步骤:

  1. 关闭未用外设时钟

    RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_ADC1 | RCC_APB2PERIPH_TIM1 | RCC_APB2PERIPH_SPI2 | RCC_APB2PERIPH_USART1, DISABLE);
  2. 配置 PWR 低功耗模式

    PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI); // STOP 模式,电流 ~20μA // 唤醒源:EXTI_Line0(DIO0 中断)或 RTC Alarm
  3. SX1278 进入 Sleep 的寄存器操作

    SX1278_WriteRegister(0x01, 0x00); // RegOpMode = 0x00 → Sleep // 注意:Sleep 前需确保 FIFO 清空,否则唤醒后状态异常

提示:使用PWR_EnterSTOPMode()时,若用 DIO0 唤醒,需提前配置 EXTI_Line0 触发下降沿(RX Done 为上升沿,故需反相或改用 DIO1),否则无法退出 STOP。

4.2 抗干扰实战:动态扩频因子与信道检测

在 433MHz ISM 频段,WiFi/蓝牙/微波炉均可能造成突发干扰。SX1278 支持信道活动检测(CAD),可在发送前判断信道是否空闲:

uint8_t SX1278_ChannelActivityDetection(void) { SX1278_WriteRegister(0x01, 0x80); // Sleep SX1278_WriteRegister(0x01, 0x82); // CAD 模式(LoRa + CAD) Delay_ms(1); // 等待 CAD 完成(典型 1.5ms) if (SX1278_ReadRegister(0x12) & 0x04) { // RegIrqFlags: CadDetected return 1; // 信道忙 } return 0; // 信道空闲 }

若检测到忙,则动态提升扩频因子(SF8→SF9)以增强抗噪能力:

// SF8 → SF9 修改 RegModemConfig2(0x1E) SX1278_WriteRegister(0x1E, 0xD5); // Bit7-4 = 1001 → SF9

4.3 调试技巧:用串口重定向printf查看寄存器状态

在 Keil 中启用microLIB后,重定义fputcprintf输出到 USART1:

#include "stm32f10x_usart.h" int fputc(int ch, FILE *f) { USART_SendData(USART1, (uint8_t) ch); while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); return ch; } // 初始化 USART1(PA9/PA10) void USART1_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOA | RCC_APB2PERIPH_USART1, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Tx; USART_Init(USART1, &USART_InitStructure); USART_Cmd(USART1, ENABLE); }

然后在关键节点插入:

printf("RegOpMode=0x%02X, RegIrqFlags=0x%02X\r\n", SX1278_ReadRegister(0x01), SX1278_ReadRegister(0x12));

实时查看寄存器值,比逻辑分析仪更快定位RegIrqFlags不更新的问题。

5. 实战排错:解决error: no STM32 target found!与 LoRa 通信失败的 5 类根因

当 Keil 提示error: no STM32 target found!或 LoRa 模块始终无响应时,90% 的问题不在代码逻辑,而在开发环境与硬件链路。本节按发生概率排序,给出可立即验证的排查动作,每项均对应具体命令或寄存器读值。

5.1 ST-Link 连接失效的 3 种物理层检查

no STM32 target found是烧录失败的第一信号,必须逐项排除:

检查项操作预期结果失败表现
SWD 接线用万用表测 SWDIO(PA13)、SWCLK(PA14)对地电阻均为 10kΩ~100kΩ(上拉电阻)电阻为 0Ω → 短路;无穷大 → 断线
BOOT0/BOOT1测 BOOT0 引脚电压0V(GND)→ Flash 模式;3.3V → 系统存储器模式BOOT0=3.3V 会导致 ST-Link 无法访问 Flash
NRST 引脚用示波器看 NRST 波形上电后有 100ms 低电平复位脉冲无脉冲 → 复位电路故障,MCU 不启动

注意:若使用 ST-Link V2,固件版本低于 V2.J27.S4 时无法识别 STM32F103C8T6(因芯片 ID 识别缺陷)。升级方法:打开 ST-Link Utility → Help → Firmware update。

5.2 LoRa 通信失败的寄存器级根因表

SX1278_ReadRegister(0x42)返回0x000xFF,或RegIrqFlags始终为 0,按此表顺序验证:

根因类别关键寄存器正常值验证命令修复动作
SPI 时序错误RegOpMode(0x01)0x00(Sleep)或0x80(LoRa Sleep)printf("0x01=0x%02X\r\n", SX1278_ReadRegister(0x01));SPI_BaudRatePrescaler_8,确认CPOL/CPHA为 0/0
电源不足RegPaConfig(0x09)0xFF(PA_BOOST 使能)SX1278_ReadRegister(0x09)返回0x00检查 VDD_PA 是否接 3.3V(SX1278 PA 引脚需独立供电)
频率偏移RegFrfsMsb/Mid/Lsb(0x06-0x08)0x6C,0x80,0x00(433MHz)读三字节拼成 24bit 值,转十进制计算公式:Freq = (RegFrfs * 32M) / 2^19,433MHz 对应0x6C8000
同步字不匹配RegSyncWord(0x39)0x12(默认)SX1278_ReadRegister(0x39)收发两端必须完全一致,不可省略写入
FIFO 地址错位RegFifoTxBaseAddr(0x0E) &RegFifoRxBaseAddr(0x0F)均为0x000x0E0x0F若为0xFF,说明之前写寄存器失败,需重刷初始化序列

5.3 使用st-flash命令行工具绕过 Keil 烧录

当 Keil 因驱动问题无法识别目标时,用开源st-flash直接烧录.bin文件:

# 安装 stlink(Ubuntu) sudo apt install stlink-tools # 烧录 firmware.bin 到 0x08000000 st-flash write firmware.bin 0x08000000 # 读取 Flash 验证 st-flash read flash.bin 0x08000000 0x20000

st-flash提示Failed to connect to target,执行:

st-util --probe # 列出所有 ST-Link 设备 st-flash --debug write firmware.bin 0x08000000 # 开启 debug 日志

日志中出现Target voltage: 3.28V表示供电正常;若为0.00V,则 SWD 线缆或目标板供电故障。

最后,验证 LoRa 通信是否真正建立:用两块板分别运行发送/接收代码,用手机录音 app 录下空中信号(LoRa 信号在 433MHz 呈连续嘶嘶声),听到稳定白噪声即表示射频链路已激活——这是比任何寄存器读值更底层的物理层确认。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/16 15:25:38

多环境API管理规范:环境隔离配置与密钥安全实践

你有没有遇到过这种情况&#xff1a;本地联调一切正常&#xff0c;一到 test 环境就开始刷 401&#xff0c;日志面板全是 authentication fails, your api key&#xff1b;好不容易把 test 弄好了&#xff0c;上线前又发现生产环境的回调地址压根没配&#xff0c;甚至测试数据混…

作者头像 李华
网站建设 2026/9/16 15:23:39

MATLAB图像配准实战:SURF特征提取与RANSAC仿射变换估计

简介&#xff1a;基于RANSAC与Affine变换的图像配准MATLAB仿真资源&#xff0c;面向图像处理、计算机视觉方向的初学者与研究人员&#xff0c;帮助理解特征点匹配、随机采样一致性剔除误匹配以及仿射变换模型估计的完整流程。资源共6个文件&#xff0c;以MATLAB脚本、JPG测试图…

作者头像 李华
网站建设 2026/9/16 15:22:15

SSM学生宿舍管理系统毕设实战:从环境搭建到数据一致性保障

简介&#xff1a;这是一套面向计算机专业本科生毕业设计与Java初学者实战训练的SSM框架宿舍管理项目&#xff0c;聚焦校园公寓数字化管理场景&#xff0c;覆盖学生报修、签到、奖惩、访客登记及宿舍评分等核心业务流程。资源包共3个文件&#xff08;1个SQL数据库脚本用于初始化…

作者头像 李华
网站建设 2026/9/16 15:19:20

SpringBoot校园快递系统:Redis+MQTT实现高并发取件与远程打印

简介&#xff1a;本资源是一套完整的本科毕业设计项目源码&#xff0c;基于SpringBoot开发的校园快递驿站管理系统&#xff0c;面向计算机专业本科生、Java初学者及Web全栈学习者&#xff0c;解决高校快递代收代发场景下的信息化管理需求。系统采用前后端分离架构&#xff0c;后…

作者头像 李华
网站建设 2026/9/16 15:16:16

Cursor 连上 TaoToken 后,靠 Memory Bank 把包月请求省下来

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华