尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
基于GSM短信模块与单片机的远程开锁系统设计解析
简介基于单片机GSM/GPRS远程控制与短信开锁设计资料面向电子类学生、单片机开发爱好者及需要快速搭建远程控制方案的工程师。整合五套完整设计覆盖51单片机与MSP430平台涵盖远程拨号开锁、短信控制家电插座、智能快递箱、蓝牙GSM防盗系统以及SIM800C模块应用等典型场景。包内共264个文件压缩包约92MB以jpg实物图、pdf论文与说明、c/h源程序、schdoc/pcbdoc原理图及PCB、Proteus仿真dsn等为主目录按五套方案分类查找方便可对照原理图与源程序理解设计思路。已有608人学习下载适合用于课程设计、毕业设计或产品预研。资料包含完整原理图、可编译源程序、仿真文件、论文报告及实物图每套均能独立支撑从硬件设计到代码调试的完整流程尤其适合想快速理解GSM模块选型、AT指令控制与远程通信机制的读者。1. 从一把锁说起单片机、GSM/GPRS 与远程开锁的完整链路你人不在现场却要开一把锁。工地配电箱、无人值守机柜、短租房门、快递柜的维护格口——这类场景的共同点是没有 WiFi、没有 4G 专网但手机信号一定覆盖。靠 GSM 短信远程控制去开锁是这类需求里最粗粝也最皮实的方案一条短信从基站进到 SIM800C模块把它吐给单片机单片机比对号码和口令后驱动继电器电磁锁得电弹开。整个过程没有任何云端参与意味着不存在云服务挂了就开不了门的单点故障。但这套系统的难度并不在开锁本身而在电源设计和短信链路。GSM 模块发射瞬间峰值电流超过 2A电源压降会导致模块重启中文 PDU 编码算错一个字节收到的就是乱码——这些坑只会在你真正把原理图、仿真和实物连起来调试时浮出水面。这篇文章按硬件架构、AT 指令链路、单片机程序骨架、五套资料的复习路径、现场调试技巧五层展开把整条链路完整过一遍。2. 短信链路最底层AT 指令、PDU 与 TEXT 模式GSM/GPRS 模块的英文名是 GSM/GPRS Module它本质上是一台被剥掉屏幕和键盘的手机——你通过串口向它发 AT 指令它替你完成搜网、收发短信、拨号上网这些射频动作。远程开锁只依赖短信收发GPRS 在这里的作用更多是提供 TCP/UDP 数据通道供你以后扩展状态上报或远程配置。但无论走哪条路你对模块的全部控制都落在 AT 指令上这是绕不开的第一层地基。2.1 选型先定硬件接口TTL、串口与供电主流的 GSM 模块SIM800C、SIM900A、SIM7000C 等以及它们的国产替代型号几乎都是 UART TTL 电平接口和 STC51、STM32 可以直接相连。这里有一个高频翻车点部分模块底板自带了 MAX232 电平转换芯片输出的是 RS232 电平接单片机时必须绕过底板转换电路直接从模块的 TTL 引脚取信号。选择模块时先确认底板是否透明——如果串口经过 MAX232 后再输出单片机一侧就需要额外的 TTL 转接绕这一圈除了增加故障点没有任何收益。供电方面模块的工作电压通常是 3.4V 到 4.4V推荐直接用 4V 左右的稳压源而不是接 5V 再指望模块内部的 LDO因为发射瞬态电流能到 2ALDO 的压差会直接把电压拖垮。常见的做法是用 LM2596 或 MP1584 降压模块将 12V 电源降到 4V并在模块电源引脚附近并联一个 470uF 以上的电解电容和一个 100nF 瓷片电容——前者扛瞬态后者滤高频噪声。数据手册上的峰值电流 2A不是夸张是电源设计的绝对下限。2.2 最小验证用 AT 指令把短信发出去模块上电后先用串口助手或 screen 打开模块的串口默认波特率通常为 115200。第一次交互只做一件事确认串口链路畅通。# 打开/dev/ttyUSB0波特率1152008N1 screen /dev/ttyUSB0 115200 # 进入终端后逐条发送注意每条指令末尾要带回车 AT # 模块应回复: OK ATCSQ # 模块应回复: CSQ: 18,0 信号强度第一个数字越大越好范围0-31 ATCREG? # 模块应回复: CREG: 0,1 第二个参数为1或5表示已注册上网络逻辑说明AT相当于握手信号确认串口参数正确且模块已启动ATCSQ查询信号质量返回值18,0中的 18 对应的实际信号强度大约在 -80dBm 左右小于 10 就说明天线位置有问题ATCREG?查询网络注册状态返回值0,1中第一个 0 表示禁用主动上报第二个 1 表示已注册到家庭网络如果是 2 表示正在搜索网络3 表示注册被拒绝4 表示未知状态。确认网络注册后就可以发短信了。TEXT 模式下指令直观但只能发 ASCII 字符中文短信必须切换成 PDUProtocol Description Unit模式。这是整个短信链路最重要的分界线。# 切换到TEXT模式 ATCMGF1 # 模块应回复: OK # 发送短信8613800138000是接收方号码中国移动短信中心号码请用自己的SIM卡查询 ATCMGS8613800138000 # 模块回复: 表示进入短信内容输入状态 # 在后输入英文helloworld然后按CtrlZ十六进制0x1A发送 helloworld # 模块回复: CMGS: 42, OK 表示发送成功42是模块内部的消息编号参数说明ATCMGF的两个取值是 0PDU和 1TEXT大部分运营商都支持 TEXT 发英文短信中文会乱码或直接失败ATCMGS发送指令TEXT 模式下直接跟号码PDU 模式下跟一个十六进制字符串。最后一步用 CtrlZ 发送而不是回车回车在短信内容中会被识别为换行。2.3 PDU 编码中文短信的必经之路PDU 模式的本质是把短信内容和号码按特定规则压缩编码。号码部分很简单去前缀、每两位反转内容部分对中文而言每个汉字取 Unicode 码位然后按高位在前、低位在后的顺序写到字节流中。以开锁两个字为例# pdu_encode.py - 中文短信PDU编码 phone 13800138000 # 接收方手机号 message 开锁 # 短信内容 smsc 8613800013800 # 短信中心号码注意要含国际前缀86 # 1. 短信中心号码处理长度 反转 if smsc.startswith(): smsc smsc[1:] smsc smsc.replace(F, ) if False else smsc # 奇数长度补F if len(smsc) % 2: smsc F smsc_pdu smsc F # 短信中心号码末尾统一补F smsc_pdu .join([smsc_pdu[i1] smsc_pdu[i] for i in range(0, len(smsc_pdu) - 1, 2)]) smsc_len len(smsc_pdu) // 2 # 2. 目标号码处理同样反转相邻两位 phone_pdu phone (F if len(phone) % 2 else ) phone_pdu .join([phone_pdu[i1] phone_pdu[i] for i in range(0, len(phone_pdu) - 1, 2)]) # 3. 短信内容每个汉字转Unicode码位占2字节 content_hex message.encode(utf-16-be).hex().upper() # 4. 组装PDU短信中心 协议控制字段 号码格式 号码 协议标识 编码方式 有效期 内容长度 内容 pdu (smsc_len.to_bytes(1, big).hex().upper() smsc_pdu 11 # 第一个字节: 发起短信 0D # 号码长度: 13位 91 # 号码格式: 国际格式 phone_pdu 00 # 协议标识: 普通短信 08 # 编码方式: UCS2 AA # 有效期: 4天 format(len(content_hex) // 2, 02X) content_hex) # 5. 完整AT指令注意指令中的PDU不包含短信中心长度字节 at_cmd ATCMGS str((len(pdu) - 2) // 2) \r full at_cmd pdu \x1a print(pdu) print(full)逻辑说明utf-16-be是 UCS2 编码的最大字节序版本每个汉字固定占 2 字节短信内容的长度字段单位是字节数而不是字符数所以要把十六进制字符串长度除以 2 再换算成十六进制最后的 AT 指令长度ATCMGSlen中的 len 是指 PDU 除去短信中心长度字段之后的有效字节数这个单位容易算错少一个字节模块就会一直停在提示符不发送。上述代码直接贴在 Python 3 环境中即可运行输出的full变量可以直接通过串口发送。TEXT 与 PDU 的分工原则纯英文字符串用 TEXT 模式代码可读性好、调试方便任何包含中文、特殊符号、或需要嵌入时间戳的消息一律用 PDU。这里没有第三条路。3. 单片机侧程序骨架短信解析、开锁执行与回执AT 指令链路打通后真正决定这套系统稳定性的是单片机的程序架构。远程开锁的代码核心不是怎么发短信而是怎么从一串串口数据里把有用的一帧完整地抠出来——GSM 模块的串口会持续吐出网络状态、短信提示、AT 回显等无关数据如果不在这一层做干净的数据帧切割任何上层逻辑都会被脏数据干扰。3.1 上电初始化先等模块醒来GSM 模块的启动时间通常需要 3 到 10 秒取决于 SIM 卡和网络环境。单片机复位后立即向模块发送AT指令几乎必然收到空响应或乱码正确的做法是给模块一个固定的上电延时。// gsm_init.c - GSM模块初始化 void gsm_init(void) { char buf[64]; // 模块上电后延时10秒等待网络注册 delay_ms(10000); // 清除串口缓冲区中残留数据 while (uart_available()) uart_read(); // 发送握手指令重试3次 for (char retry 0; retry 3; retry) { uart_send_str(AT\r\n); delay_ms(500); if (strstr(rx_buffer, OK) ! NULL) break; } // 切换到PDU模式中文短信必需 uart_send_str(ATCMGF0\r\n); delay_ms(200); // 关闭短信内容转发新短信不主动推主动查询 uart_send_str(ATCNMI0,0,0,0,0\r\n); delay_ms(200); }逻辑说明ATCNMI0,0,0,0,0的作用是禁止模块在收到新短信时主动往串口推送内容。此时模块收到短信会只更新一条CMTI: SM,23类的提示第 23 是存放在 SIM 卡中的消息序号。你可以在主循环中主动查询ATCMGLALL来拉取全部短信也可以在收到 CMTI 提示后按序号读取ATCMGR23。对于远程开锁这种低频控制场景主动查询比中断推送更容易控制逻辑复杂度——中断推送意味着你必须在任意时刻都可能被打断这在裸机开发中会让状态机复杂化。3.2 核心从串口流中切割出一条完整短信GSM 模块返回的数据以\r\n为行分隔符但一行数据可能分多次到达串口所以必须在中断处理函数中按字节拼装而不是按行读取。下面是一个典型的裸机实现// sms_parser.c - 串口接收与短信解析 #define UART_BUF_SIZE 256 volatile char rx_buf[UART_BUF_SIZE]; volatile uint8_t rx_head 0; volatile uint8_t rx_tail 0; // 串口中断服务函数每个字节到达时触发 void uart_isr(void) __interrupt(4) { char c SBUF; // 读走硬件缓冲区 rx_buf[rx_head] c; // 写入环形缓冲区 rx_head (rx_head 1) % UART_BUF_SIZE; } // 从环形缓冲区中取出一行以\r\n结尾超时返回NULL char* get_complete_line(uint16_t timeout_ms) { static char line[128]; uint16_t line_len 0; uint32_t start millis(); while (millis() - start timeout_ms) { while (rx_head ! rx_tail) // 环形缓冲区有数据 { char c rx_buf[rx_tail]; rx_tail (rx_tail 1) % UART_BUF_SIZE; if (c \n) { line[line_len] \0; return line; } if (line_len sizeof(line) - 1) line[line_len] c; } } return NULL; }逻辑说明rx_buf是环形缓冲区中断只负责往 buffer 里写主循环负责读这样不会丢字节。get_complete_line以\n作为一行结束的标志剔除了\r。这个函数给后续的指令解析提供了干净的一行输入。注意环形缓冲区的边界条件写指针rx_head和读指针rx_tail相等时表示缓冲区为空所以缓冲区实际可用空间是UART_BUF_SIZE - 1代码中line[line_len] \0之前有长度检查防止溢出。3.3 短信解析与开锁执行拿到完整的一行后解析逻辑分两步先判断这一行是否为CMTI提示即收到了新短信再从 SIM 卡中读出短信内容并查找开锁口令。口令建议采用固定格式比如#8023——#是起始符8023是口令。// main_loop.c - 主循环中的短信处理与开锁执行 void process_line(char* line) { // 1. 判断是否新短信提示: CMTI: SM,3 if (strncmp(line, CMTI, 5) 0) { // 提取短信序号 char* idx strrchr(line, ,); if (idx) { int sms_index atoi(idx 1); // 2. 用ATCMGR读取短信内容 sprintf(cmd, ATCMGR%d\r\n, sms_index); uart_send_str(cmd); delay_ms(300); // 3. 在执行区中查找口令 if (strstr(rx_buf, #8023) ! NULL) { relay_on(); // 继电器吸合 delay_ms(3000); // 开门保持3秒 relay_off(); // 继电器断开 // 4. 发送中文回执短信PDU编码略参见2.3节 send_sms_pdu(13800138000, 门已打开); // 5. 删除已处理的短信防止重复触发 sprintf(cmd, ATCMGD%d\r\n, sms_index); uart_send_str(cmd); } } } }参数说明relay_on和relay_off是继电器控制函数开锁动作的 GPIO 逻辑取决于继电器模块是低电平触发还是高电平触发。多数市售继电器模块使用光耦隔离输入通常IN接低电平时继电器吸合——如果你的板子相反只需在relay_on中把引脚拉反即可。两个细节值得强调第一开门保持时间3000ms需要根据电磁锁的电压和灵敏度调整锁具的弹簧耐力是关键约束标准的电插锁 3 秒足够磁力锁则需要维持到关门信号到来第二短信删除动作ATCMGD必须做否则同样的短信会在 SIM 卡中反复出现每次ATCMGR都会触发开锁相当于别人复制同一条短信就能无限开门。3.4 安全性边界白名单与口令模式短信远程开锁天生有安全弱点——SIM 卡可以被复制短信内容可以被对端服务器截获。对这个弱点我一般会做两层补偿第一层是白名单在程序初始化时写死一串允许开锁的手机号ATCMGR读出的号码不在白名单内就直接丢弃不回执不开锁第二层是口令动态化开锁短信不再是固定口号而是#8023配合时间戳的低位数字每小时变化比如 16 点 30 分时口令为#80231630如果你不想在代码里维护时间同步至少做到口令与门锁编号的绑定。等于说开锁权限由号码 口令双因子约束而不是只认口令。这会让程序多出几十行解析代码却能让复制 SIM 卡的攻击者失效——攻击者拿到的号码不变但口令已经变了旧口令记录对新时间窗口完全无效。4. 五套资料的落地路径原理图、仿真、论文与实物图怎么配合用标题里提到的五套资料——原理图、源程序、仿真、论文、实物图——是这类课题最常见的内容组织方式也是工程学习的优质素材。但很多人拿到资料后的第一个错误就是打开源程序从头读到尾。资料包的阅读顺序应当和项目实施顺序相反先看论文建立系统认知再读原理图理解硬件接着跑仿真验证逻辑之后才轮到代码最后拿实物图对照验收。4.1 原理图只看三块电路原理图里通常有显示、键盘、存储、电源等若干模块远程开锁课题的核心电路只有三块读图时优先盯住它们电路模块关键元器件为什么重要电源部分LM2596/MP1584、电解电容GSM 发射瞬间 2A 电流电源纹波大则模块重启串口电平匹配分压电阻/RX-TX 直连模块与单片机 TTL 电平必须一致5V 单片机会烧模块继电器驱动ULN2003、三极管 续流二极管继电器线圈是感性负载没有续流二极管会击穿驱动管读原理图时用笔跟踪三路信号电源从输入端流经哪个稳压芯片到达单片机与 GSM 模块串口 TX/RX 从单片机引脚引出后有没有电平转换环节继电器的线圈引脚上是否并联了反向二极管通常是 1N4007 或 SS14。这三块都没有问题其余电路可以暂时不看。4.2 Proteus 仿真边界比效果更重要Proteus 是 51、STM32 仿真的主流工具GSM 模块在 Proteus 中的仿真通常通过虚拟终端或串行接口模拟实现。仿真能验证的核心逻辑是单片机收到虚拟串口数据后能否正确解析并触发开锁动作。至于射频信号、SIM 卡、AT 指令交互仿真做不到——AT 指令在仿真中只是普通字符串。因此仿真时的一个务实做法是在虚拟终端中直接输入ATCMGR1\r\nCMTI: SM,1\r\n之类的字符串观察单片机的解析函数是否走到了继电器控制分支。这一步可以提前暴露字符串切割的 bug比如行尾处理不当、索引偏移、strstr 查找边界错误这些 bug 在实际硬件上排错的成本远高于仿真。4.3 代码与原理图对不上的四个典型问题五套资料来自同一项目但版本不一致几乎是常态。代码和原理图结合检查时我一般查四个点引脚映射是否一致——源程序中sbit relay P1^0;而原理图里继电器接在 P2.7这就是硬性冲突。晶振频率是否一致——delay(3000);的物理时长和晶振频率强相关原理图 12MHz、代码注释却写 11.0592MHz串口波特率必然偏差。继电器触发极性——原理图标注高电平吸合代码初始化端口输出的却是低电平逻辑反了。模块型号代差——资料里的 GSM 模块是 SIM300而现在你手里是 SIM800C引脚兼容但 AT 指令集有细微差异比如 SIM800C 不支持ATCPMS的某些参数组合。这些问题的排查思路都非常机械把原理图、代码注释、实物照片三方对齐任何不一致的地方都按实物照片 原理图 代码注释的优先级去修因为最原始的制作过程通常是改板不改进、改代码不改文档。4.4 五套资料的复习顺序资料包的高效打开路径推荐是论文 → 原理图 → 仿真 → 源程序 → 实物图。论文负责给你一个别人是怎么设计的全局视角原理图把论文中的方案变成具体元件仿真验证控制逻辑是否成立源程序提供最细粒度的实现细节实物图是最终的验收标准。如果你是在做毕业设计这个顺序同样适用于你自己的文档编写——先写出系统框图再画电路然后写代码最后拍实物。有一类高频切入点值得关注源程序中的注释往往比代码本身更有价值。比如注释// 此处延时不可减少防止GSM模块未初始化就发AT指令这类注释透出的是作者踩过的电源和管理时序的坑。遇到这种注释拿笔在纸上记下来并标记为排错照应的知识点。5. 现场排错三件事PDU 乱码、信号强度与电源共地问题5.1 学会用数字说话ATCSQ的阈值判断模块说它收到短信了但内容乱码模块说它发送成功了但对方收到的全是豆腐块——这类 PDU 乱码问题在远程开锁中排前三位。乱码的根因通常是以下三种中的一种。# pdu_debug.py - 检查PDU编码是否正确 pdu 0891683108200105F011000D91683120003800F80008319011631E93 4 # 上面的PDU是开锁二字的十六进制: 5F00 9501 content_start pdu.rfind(08) 4 # 找编码方式后面的内容 content_hex pdu[content_start:].replace( , ) # 期望输出: 5F00 9501 print(content_hex[:8]) # 手工验证: 5F00是“开”的UCS2码9501是“锁”的UCS2码 # 如果输出内容不是目标文字的Unicode码位说明编码或解析环节有误排查乱码时按编码格式 → 长度字段 → 发送工具三步走。先确认你按 UCS2 编码而不是 GB2312 或 UTF-8因为 PDU 严格指定 UCS2再确认ATCMGS后面的长度字段是否比真实长度少算或多算——长度单位是字节数开锁两个汉字的 UCS2 编码长度是 4写成 2 就会截断内容最后用十六进制串口工具直接发一次 PDU 来排除单片机代码的干扰如果能收到正确短信说明问题在单片机侧否则就是模块或 SIM 卡的问题。5.2 信号强度的硬性指标ATCSQ的十档标准ATCSQ返回的数值从 0 到 31常见的判断标准是31 表示信号极佳26~30 为优秀20~25 良好15~19 一般10~14 较差的边缘状态可能出现短信收发延迟或失败10 以下基本不可用。远程开锁场景对信号的要求是 ≥15因为开锁短信是时间敏感的——用户在门外等待开门一条短信延迟 30 秒体验已经完全不可接受。如果信号强度不足优先处理天线位置而不是换 SIM 卡。GSM 模块自带的天线接口是 IPEX 或 SMA天线应尽量垂直放置并远离金属外壳铁质配电箱内部是典型的信号屏蔽环境天线引到箱体外部通常能带来 5 到 10 的提升。还有一个容易忽略的因素2G 网络正逐步退网新买的 SIM 卡可能默认注册到 4G/5G 网络而模块不支持 VoLTE 短信必须联系运营商开通 2G 业务或者改用 NB-IoT/4G 模块。5.3 共地问题模块和单片机之间最后一道坎共地即把两个模块的地引脚接到同一电位上是串口通信最基本的约束也是远程开锁实物调试中最容易被忽略的一环。常见的故障现象是单片机发的指令模块收不到或模块返回的数据单片机读出来全是 0xFF其中一个原因就是地没接牢。TTL 串口是电平信号5V 单片机的 RX 引脚需要收到模块的 3.3V 高电平如果两个设备不共地模块的输出电平在单片机看来可能是 1.2V 或 3.8V——远超出 TTL 高电平的阈值范围。解决方式是把模块的输出端TX_RX分别经过 1kΩ电阻接到单片机再把模块的 GND 直接接到单片机 GND这是一个非常廉价的电平适配方案也能兼顾大多数 5V/3.3V 混接场景。如果只是共地之后仍然偶发乱码检查波特率误差51 单片机用 11.0592MHz 晶振才能在波特率 9600 下保持误差在 0.0% 附近12MHz 晶振下 9600 波特率存在约 2% 的误差长时间传输就会积累成乱码——这在原理图阶段就该检查清楚。共地 波特率 接线长度这三个因素全部到位短信远程开锁的硬件链路才算真正稳定。本文还有配套的精品资源点击获取
RELATED

相关推荐

PM Skills Marketplace 贡献指南:从 frontmatter 规范到自动化校验的插件开发实战

PM Skills Marketplace 贡献指南:从 frontmatter 规范到自动化校验的插件开发实战

PM Skills Marketplace 贡献指南:从 frontmatter 规范到自动化校验的插件开发实战 【免费下载链接】pm-skills PM Skills Marketplace: 100 agentic skills, commands, and plugins — from discovery to strategy, execution, launch, and growth. 项目地址: htt…

📅 2026/9/11 7:17:56
风电电力系统低碳调度模型与Matlab实现

风电电力系统低碳调度模型与Matlab实现

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

📅 2026/9/11 7:12:56
scrcpy 教程:一条命令把手机投屏到电脑

scrcpy 教程:一条命令把手机投屏到电脑

scrcpy 教程:一条命令把手机投屏到电脑 【免费下载链接】scrcpy Display and control your Android device 项目地址: https://gitcode.com/GitHub_Trending/sc/scrcpy 给别人演示刚做的 App,对方围着你 6 寸的小屏幕挤成一团,字小看不…

📅 2026/9/11 7:12:56
MORE NEWS

更多资讯

📰

Refine v5 useLogList Hook 实战指南:审计日志列表查询、底层原理与边界情况

Refine v5 useLogList Hook 实战指南:审计日志列表查询、底层原理与边界情况 【免费下载链接】refine A React Framework for building internal tools, admin panels, dashboards & B2B apps with unmatched flexibility. 项目地址: https://gitcode.com/Git…

📰

从“各扫各的”到一套方案:SonarQube统一前后端代码质量管理

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

📰

axum 路由详解:Router::route 的静态路径、捕获段与通配符匹配规则

axum 路由详解:Router::route 的静态路径、捕获段与通配符匹配规则 【免费下载链接】axum HTTP routing and request-handling library for Rust that focuses on ergonomics and modularity 项目地址: https://gitcode.com/GitHub_Trending/ax/axum Router:…

📰

Spring Boot数据库配置实战与优化指南

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

📰

卡方检验怎么选?SAS分类变量比较全攻略:从四格表到CMH分层分析

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

📰

Duix.Avatar本地部署教程:3步完成离线数字人克隆,生成第一条口播视频

Duix.Avatar本地部署教程:3步完成离线数字人克隆,生成第一条口播视频 【免费下载链接】Duix-Avatar 🚀 Truly open-source AI avatar(digital human) toolkit for offline video generation and digital human cloning. 项目地址: https://…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬