新闻详情

新闻详情

首页 / 资讯中心 / 详情

STM32+ESP8266排队叫号系统设计:主从机架构与Wi-Fi透传实现

发布时间:2026/9/16 1:21:44来源:尧图网络
STM32+ESP8266排队叫号系统设计:主从机架构与Wi-Fi透传实现
简介面向计算机、软件工程、通信工程等专业课程设计与毕业设计场景这份基于STM32与ESP8266的银行排队叫号系统主从机资源包提供了一套完整可参考的嵌入式无线通信项目方案。系统区分主机与从机角色涉及TCP Server/Client、STA/AP组网等典型Wi-Fi通信应用适合具备一定单片机基础、希望快速搭建上下位机联调项目的学生。资源共684个文件压缩包19.39MB除C/H源码外还包含Keil/IAR工程文件、编译生成文件axf/hex、调试配置与批处理脚本以及PDF/Word说明文档便于直接打开工程查看、重新编译或烧录验证。目前已有576人学习使用读者可从中获取系统框架、外设驱动写法、无线收发逻辑及工程管理思路对完成课程报告、答辩演示或毕业设计初稿很有帮助。1. 先把 STM32ESP8266 的排队叫号主从机说清楚在银行网点、政务大厅、医院药房这些场景里排队叫号从来不是单块屏的事。取号机边吐票边刷新等待人数窗口屏要同步喊号等候区大屏还要显示当前叫到几号。如果只用一块 STM32 直接拉所有屏幕布线会绕半个大厅GPIO 数量也撑不住。所以这类项目最常见的落地形态就是主从机一台主机管取号和队列若干台从机管窗口显示和语音播报中间的通信链路交给 ESP8266 的 Wi-Fi 透传解决。这套方案的意义在于把“排队逻辑”和“展示逻辑”拆开主机打一个 TCP Server每台窗口从机按自己的 IP 去连接断开能自动重连哪台窗口屏坏了不影响主队列。它适合正在做 STM32 无线通信练习、毕设或者低成本叫号终端的开发也适合想弄清楚 Wi-Fi 模块如何接入 uart 中断框架的嵌入式爱好者。2. 主从机架构为什么排队逻辑必须放在主机侧设计叫号系统第一步不是画电路而是先把“谁产生号码、谁保存号码、谁展示号码”这三件事切开。2.1 放号与叫号分离排队叫号的核心不是 LED 屏是“队列”。一个正经的队列要管三种状态等待中、已叫号、已过号。如果每台窗口屏都保存一份队列表多台屏同时刷新的时候就会出现同一号码在不同窗口重复叫号的问题。所以队列必须只有一个所有者这就是主机。主机负责三件事。第一生成号码按下取号键后自动从 1 开始递增要支持跨天清零或者断电续号第二维护队列状态比如 VIP 客户插入队首、过号重新排队第三下发叫号指令把当前呼叫的窗口号和号码广播给对应从机同时刷新等待人数。从机则只做两件事接收主机下发的窗口号、号码、动作类型然后驱动数码管、点阵屏或语音模块播报。从机自己不保存队列状态掉电重启后只要重新连上主机就能恢复工作。这种设计的最大好处是“从机无状态”出故障时替换成本极低。2.2 ESP8266 在这套系统里到底是什么角色很多初学者把 ESP8266 当成一个“能联网的单片机”直接把业务逻辑写进 ESP8266 的固件里。但在银行叫号这种主从机项目里更稳妥的做法是让 ESP8266 老老实实做一个串口转 Wi-Fi 的透传桥。换句话说STM32 通过 USART 往 ESP8266 发 AT 指令和数据帧ESP8266 负责建立 TCP 连接把数据从有线侧搬到无线侧。主从机两端看到的都是串口字节流协议解析、队列管理、异常处理全部交给 STM32 的代码控制。这样做有三个直接原因一是 STM32 生态里的状态机、定时器、Flash 存储更好写调试工具也比 ESP8266 的 SDK 顺手二是叫号系统的业务逻辑不复杂没必要引入 NodeMCU 那套 Lua/Arduino 开发三是后续换用别的 Wi-Fi 模块只需要改串口指令层业务层代码几乎不动。也有直接用乐鑫 SDK 在 ESP8266 里跑 Socket 的做法常见于纯物联网产品。但那种方案里 ESP8266 既要管 TCP 又要管业务崩溃一次就得整机重启在“排队到一半突然全部掉线”的场景里用户容忍度很低。2.3 谁做 Server、谁做 Client这里有个容易画反的拓扑主从机通信要基于 TCP 连接先明确 Server 和 Client 的分配。常见做法是主机作为 TCP Server从机作为 TCP Client。为什么不让从机开 Server从机的 IP 是由路由器 DHCP 分配的主机主动去连需要知道每一台从机的地址意味着要维护 IP 表。反过来的话所有从机只需要知道主机的 IP可以通过路由器静态分配或者绑定 MAC 固定 IP主动发起连接失败就重试。从机掉线重连只需要一个连接地址不需要额外广播。需要注意的是ESP8266 在 AT 固件里开启多连接模式ATCIPMUX1之后再开 Server才能同时接受多个 Client。如果只做点对点也可以用 ATCIPMUX0 的透传模式ATCIPMODE1但透传模式一开启主控就没法随时发 AT 指令查状态了。所以我一般建议银行叫号项目用多连接模式每条指令都走 ATCIPSEND 发送别贪图透传模式的简洁。角色硬件网络角色保存队列掉线代价主机取号机STM32 按键 打印机 ESP8266TCP Server是系统整体不可用需要看门狗复位从机窗口屏STM32 显示屏 语音模块 ESP8266TCP Client否仅本窗口无显示主机端标记掉线即可一旦确认了这个拓扑后面的硬件接线和代码结构就都有明确目的了。3. ESP8266 与 STM32 的硬件连接和串口初始化很多人在这个环节翻车问题往往出在供电而不是引脚。先给出一套比较保险的最小连接方案再解释每根线的细节。3.1 引脚分配与供电ESP8266 不能靠 STM32 板载 LDO 带STM32 选 F103C8T6ESP8266 用 ESP-01S 或 ESP-12F。两者的串口电平都是 3.3V TTL理论上可以直接交叉相连不需要电平转换。但要注意 ESP8266 在发射 Wi-Fi 的瞬间电流能冲到 270mA 左右而 STM32 最小系统板上的 AMS1117-3.3 通常只有 800mA 的能力加上板子自身功耗经常会把它拉到电压跌落、ESP8266 反复重启。连接方式如下STM32 的 PA9USART1_TX接 ESP8266 的 RXDSTM32 的 PA10USART1_RX接 ESP8266 的 TXD两个模块的 GND 必须共地否则串口数据全是乱码ESP8266 的 VCC 单独接 3.3V建议从独立的 LDO 或外部稳压输出引不要直接挂 STM32 板载排针CH_PDEN引脚接 10k 电阻上拉到 3.3V否则模块不工作GPIO0 悬空或接 10k 上拉保持运行模式不要进入下载模式电源端我一般会加一个 100uF 电解电容和 0.1uF 陶瓷电容并联放在 ESP8266 供电脚附近。这个细节对“打印小票时 Wi-Fi 断开”这类问题非常关键因为热敏打印机的瞬间电流波动会干扰同一个电源轨。3.2 标准库新建工程时串口怎么初始化这里以 STM32 标准库为例不依赖 HAL方便在 Keil5 里直接建工程时排查问题。初始化 USART1 的代码如下需要注意 F1 的 TX/RX 引脚必须复用推挽输出但不用像 F4 那样使能 AFIO 重映射。void UART1_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; // PA9 TX 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; // PA10 RX 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_Rx | USART_Mode_Tx; USART_Init(USART1, USART_InitStructure); USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); USART_Cmd(USART1, ENABLE); }这段代码的逻辑是把 USART1 配成 115200、8 数据位、1 停止位、无校验同时打开接收中断。ESP8266 官方固件默认波特率就是 115200虽然可以用 ATUART_DEF 改成 9600但我不建议降速因为叫号并发时多个从机同时回报状态波特率低了会出现排队阻塞。接收中断必须在主循环外及时把数据读走否则会触发串口溢出错误。下面给一个常用的接收中断处理只负责把收到的字节放进环形队列。void USART1_IRQHandler(void) { uint8_t data; if (USART_GetITStatus(USART1, USART_IT_RXNE) ! RESET) { data USART_ReceiveData(USART1); RingBuffer_Write(esp8266_rx_buf, data); } }主循环里再从环形队列取数据做 AT 响应解析。之所以不用队列、直接在中断里做字符串匹配是因为 ESP8266 会连续上报主动收到的 TCP 数据除了 IPD 行还有 CONNECT、CLOSED、WIFI DISCONNECT 这些异步状态匹配不完整很容易把半行数据当成命令响应。3.3 ESP8266 上电初始化AT 指令必须逐条确认ESP8266 的 AT 固件上电后不会立刻进入工作状态。STM32 侧要做的第一件事是复位模块然后逐条发送初始化和联网指令每一条都要等待明确的 OK 或错误码不能盲目延时后一口气发完。下面是一组完整的初始化流程常用于 TCP Server 主机侧AT // 测试模块是否响应 ATE0 // 关闭回显 ATCWMODE1 // Station 模式连接路由器使用 ATCWJAPSSID,PASS // 连接无线路由器返回 WIFI CONNECTED OK ATCIPMUX1 // 开启多连接允许最多 4 条 Client 链路 ATCIPSERVER1,8080 // 建立 Server监听 8080 端口固化到代码里的时候一般是把每条命令放进数组发完一条后用一个 2 秒超时等待解析。const char* at_cmds[] { AT\r\n, ATE0\r\n, ATCWMODE1\r\n, ATCWJAP\MyWiFi\,\12345678\\r\n, ATCIPMUX1\r\n, ATCIPSERVER1,8080\r\n }; void ESP8266_Init(void) { for (int i 0; i 6; i) { UART1_SendString((char*)at_cmds[i]); if (Wait_AT_Response(OK, 3000) 0) { // 记录第几条失败用于串口日志排查 } } }需要注意 ATCWJAP 这条命令比较特殊正常连接会先返回WIFI CONNECTED然后才是OK。如果只等待 OK 而忽略前面的状态行程序不会报错但后续可能出现已经连接却没拿到 IP 的假象。这一步必须在调试初期看一眼完整串口日志确认拿到了WIFI GOT IP后再继续。服务器建立成功后ESP8266 会在 STM32 串口上上报link_id编号。比如某个从机连接上来主机串口会收到0,CONNECT。之后从机发来的任何 TCP 数据都会被封装成一行IPD,0,长度:数据上报主机的解析逻辑要处理的正是这行报文。4. 主从机通信帧设计STM32 端叫号命令怎么发硬件跑通了下一步是把“队列状态”变成可在 Wi-Fi 上传输的数据结构。直接发裸字符串当然也能用但叫号系统涉及窗口号、号码、动作类型、CRC 校验我建议定义一套固定长度的二进制帧两端解析起来更干净。4.1 自定义帧结构把窗口号、号码、动作打包设计帧结构时我倾向长度尽量固定这样无需处理粘包和拆包。参考格式如下字段长度取值示例说明帧头2 字节0xAA 0x55用于同步定位帧起点动作1 字节0x01取号、叫号、重呼、过号、心跳窗口号1 字节0x031~16 号窗口排队号码2 字节0x012A最大 9999大端序等待人数2 字节0x0005实时等待人数校验1 字节0xC7CRC8 或累加和帧尾1 字节0xEE固定结束标识动作类型的定义放在枚举里便于扩展typedef enum { ACTION_NOP 0x00, ACTION_TAKE_TICKET 0x01, // 取号 ACTION_CALL 0x02, // 叫号 ACTION_CALL_AGAIN 0x03, // 重呼 ACTION_PASS 0x04, // 过号 ACTION_HEARTBEAT 0x05 // 心跳 } ACTION_TYPE;这个帧总长度 10 字节。相比字符串好处是 STM32 端可以用结构体直接 memcpy 发送从机收到后在中断里按字节匹配帧头即可不用做字符串到整数的转换也不会出现号码前补零的问题。4.2 主机下发叫号指令带超时机制的 TCP 发送主机向指定从机下发叫号帧时需要先建立或复用一条 TCP 连接。如果从机上电时已经连上 ServerESP8266 会分配一个 link_id主机发送时直接使用这个编号。下面给出一个串口发送带确认的发送函数避免死等。uint8_t TCP_SendData(uint8_t link_id, uint8_t* buf, uint8_t len) { char cmd[32]; // 拼 ATCIPSEND 指令指定连接编号和长度 sprintf(cmd, ATCIPSEND%d,%d\r\n, link_id, len); UART1_SendString(cmd); // 等待 ESP8266 返回 提示符 if (Wait_AT_Response(, 500) 0) { return 0; // 超时未收到提示符链路可能断开 } // 发送数据帧内容 UART1_SendChar(0xAA); UART1_SendChar(0x55); UART1_SendByte(buf[0]); UART1_SendByte(buf[1]); // ... 逐字节发送 // 最后发送 0xEE 帧尾 // 等待发送完成回执 return Wait_AT_Response(SEND OK, 500); }这里的等待时间不能太长否则主机会卡在串口上无法响应其他窗口的取号请求。一般 500ms 足够。如果返回失败建议直接调用 ATCIPCLOSElink_id 把连接关掉再通知从机重连。不要尝试在断开的连接上反复 CIPSEND。4.3 从机侧解析 IPD 并驱动显示从机不需要关心数据往哪发它只等着收IPD数据包。ESP8266 在收到 TCP 数据时会输出IPD,0,10:AA 55 02 03 2A 01 05 00 C7 EESTM32 的串口中断会把这一行完整地收进环形队列主循环里做状态机解析。常见做法是只匹配IPD,三个关键字符提取长度字段然后按长度读取后续数据再送入帧解析函数。uint8_t Parse_Frame(uint8_t* buf, CallFrame* frame) { if (buf[0] ! 0xAA || buf[1] ! 0x55) return 0; if (buf[9] ! 0xEE) return 0; if (Frame_CRC8(buf, 8) ! buf[8]) return 0; frame-action buf[2]; frame-window_id buf[3]; frame-ticket_no (buf[4] 8) | buf[5]; frame-wait_count (buf[6] 8) | buf[7]; return 1; }校验通过后从机根据 action 字段决定动作。如果是 0x02 叫号就把 ticket_no 显示到数码管同时给语音模块一个触发脉冲。如果是 0x04 过号闪烁显示并播报“请 XXX 号到 X 号窗口”。4.4 主机循环广播与点对点下发的选择银行叫号系统在叫号那一刻通常只叫一个窗口但等候区大屏需要全量刷新。因此可以约定窗口号字段为 0x00 时表示广播等待人数同时下发到所有屏幕为 0x01~0x10 时表示只发给对应窗口从机用于精确喊号。这样主机只要调用两次发送一次用 link_id 指向目标窗口一次广播。广播的目标 link_id 怎么处理多连接模式下可以给每个从机分配独立 link_id主循环里循环发送。如果路由器开启了组播支持也可以考虑 UDP 组播但前面说过为了可靠性不推荐叫号数据丢了会造成窗口喊号不一致体验非常差。5. 调试技巧断开重连、串口卡死和现场验证方法最后这部分是我最想强调的。叫号系统写完了不一定总在稳定工作状态现场真正崩掉的原因往往不是 STM32 代码而是 ESP8266 的连接异常和电源纹波。5.1 现场最容易遇到的三个现象和对应参数调整现象可能原因修改方案从机开机后一直显示 000主机日志无 CONNECT从机连接了错误的 Server IP在主机路由器里给从机绑定静态 IP确认开机 ATCWJAP 后能拿到网关运行十几分钟窗口屏无反应主机显示 CLOSEDESP8266 空闲被服务端断开默认超时 20 秒设置 ATCIPSTO60同时让双方每 5 秒互发心跳帧按下取号键瞬间屏幕闪烁Wi-Fi 断开重连打印机或蜂鸣器拉低了供电电压单独给 ESP8266 供 3.3V加 470uF 电容储能这里要专门说一个容易忽略的点主机作为 TCP Server 时必须主动给从机发心跳。ESP8266 的 AT 固件在链路空闲时会被底层 TCP 栈断开如果从机不频繁发数就必须靠应用层心跳保活。每 5 秒互发 0xAA55 开头的 ACTION_HEARTBEAT 帧连续三次无回报主动关闭连接重连。5.2 串口卡死和 AT 死等的防御STM32 在调用Wait_AT_Response时如果用 while 循环死等一旦 ESP8266 正好处在推送 IPD 数据和 AT 回执同时发生的时刻接收中断里可能一直读不完外层等不到目标字符串整个系统卡住。正确做法是所有等待都设超时主循环改成非阻塞状态机。uint8_t Wait_AT_Response(const char* target, uint32_t timeout_ms) { uint32_t start HAL_GetTick(); while ((HAL_GetTick() - start) timeout_ms) { if (String_Contains(rx_buffer, target)) { return 1; } } return 0; }同时把串口主循环的执行周期控制在 20ms 以内心跳发送不阻塞在取号按键逻辑里。还有一点STM32 的独立看门狗必须开超时复位后主机自动重新执行 ESP8266_Init即使跑飞了也能自己拉回来。复位后从机会在 3 秒内重新 TCP 连接这段时间现场的窗口屏黑一下没关系但排队队列数据要从内部 Flash 恢复不丢失当前排队号。5.3 低成本端到端验证方法把验证分成两步。第一步主机侧用 PC 串口工具代替从机发一个取号请求帧观察主机返回的叫号广播帧再用现有 ESP8266 模块做 TCP 抓包第二步接上真正的从机屏连按十次取号确认号码递增和过号逻辑实现。具体的验证步骤是先在路由器管理页面确认全部设备在线然后在每台从机上电 10 秒内查看串口日志里的WIFI CONNECTED和CONNECT状态再人为拔掉从机电源等五秒后重新上电观察窗口屏是否在收到心跳的下一跳自动刷出“当前号码 等待人数”。如果从机重连后能恢复到和大屏同步的状态说明状态同步逻辑没有问题。叫号系统真正让人放心的标准是在一边取号一边叫号的并发过程中连续 30 分钟无线设备在线率和号码递增顺序都保持准确这时再去调窗口屏的背光亮度那就是锦上添花了。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

STM32F107实现Modbus TCP从站:从PHY到LwIP的完整指南 2026/9/16 2:00:47

STM32F107实现Modbus TCP从站:从PHY到LwIP的完整指南

简介:面向 STM32F107 开发者的 Modbus TCP 完整移植参考工程,基于 ARM Cortex-M3 内核,聚焦工业以太网通信场景,解决工业现场设备与上位机之间远程实时数据交换的协议对接问题,适合需掌握 STM32 以太网 MAC、TCP/IP 协…

阅读更多 →
LLM应用开发实战地图:RAG、Agent与框架工程化落地指南 2026/9/16 2:00:47

LLM应用开发实战地图:RAG、Agent与框架工程化落地指南

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

阅读更多 →
微信原生小程序医疗急救工程实践:定位、状态、地图与性能优化 2026/9/16 2:00:47

微信原生小程序医疗急救工程实践:定位、状态、地图与性能优化

简介:本资源是一套面向微信小程序初学者与医疗健康领域开发者的实战型源码案例,聚焦急救场景下的轻应用落地,涵盖AED定位、急救指南展示、一键呼救等核心功能实现。压缩包共39个文件,含11个JS逻辑文件(处理页面交互与网…

阅读更多 →
51单片机直流电机控制:PWM生成、H桥驱动与LCD实时反馈 2026/9/16 2:00:47

51单片机直流电机控制:PWM生成、H桥驱动与LCD实时反馈

简介:本资源是一套面向单片机初学者与课程设计者的完整直流电机控制实践方案,基于经典51单片机实现电机正反转、启停、加减速等核心功能,并通过LCD1602实时显示运行状态,覆盖嵌入式系统开发全流程。资源包共39个文件,涵…

阅读更多 →
车载智能互联盒子怎么选?从CarPlay到安卓智能盒的避坑指南 2026/9/16 2:00:47

车载智能互联盒子怎么选?从CarPlay到安卓智能盒的避坑指南

车载智能互联盒子这种东西,这几年算是被问得最多的汽车数码配件之一。尤其到了2026年,车载智能互联盒子早已不是当年那个“能把手机导航投到中控屏”的简单投屏器,很多带智能系统的盒子已经能独立跑在线影音、语音助手、行车记录联动&#xf…

阅读更多 →
BUUCTF逆向入门实战:从静态分析到脚本还原的完整路径 2026/9/16 1:57:47

BUUCTF逆向入门实战:从静态分析到脚本还原的完整路径

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

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞