STM32多串口通信与物联网数据终端开发实战

发布时间:2026/7/30 13:41:05
STM32多串口通信与物联网数据终端开发实战 1. 项目概述构建一个智能化的本地数据交互中枢最近在做一个智能家居控制面板的项目核心需求是要在一块屏幕上实时显示传感器数据并且能通过手机远程查看和控制。这个场景在工业监控、环境数据采集等领域也非常常见。我选择了STM32作为主控迪文串口屏做人机界面再搭配一个ESP8266 WIFI模组来实现联网功能。这套组合拳打下来成本可控、开发效率高而且稳定性经过实测非常不错。简单来说这个系统的核心就是让STM32、屏幕和WIFI模组这三者“对话”起来。STM32负责采集和处理数据比如温湿度、设备状态然后通过串口发送给迪文屏幕进行显示同时STM32也通过另一个串口与ESP8266通信将数据上传到云端服务器或者接收来自手机App的指令再转发给屏幕或执行相应的控制动作。整个过程涉及多串口管理、数据协议解析、网络通信等多个环节对嵌入式开发的综合能力是个很好的锻炼。无论你是想做一个物联网数据终端还是为自己的毕业设计增加亮点这套方案都值得深入琢磨。下面我就把自己从硬件选型、软件框架搭建到调试排坑的全过程经验拆解开来希望能帮你少走弯路。2. 核心硬件选型与电路设计思路2.1 主控MCU为什么是STM32在众多单片机中选择STM32尤其是STM32F103C8T6俗称“蓝莓派”或STM32F407这类型号是基于几个非常实际的考量。首先它拥有多个独立的USART通用同步异步收发器这是实现本项目的硬件基础。我们至少需要两个串口一个用于连接迪文屏一个用于连接WIFI模组。STM32F103系列通常有3个USART完全够用甚至还能留出一个给调试打印信息。其次STM32的性能和资源足够丰富。以F103C8T6为例72MHz的主频、20KB RAM、64KB Flash处理多路串口数据解析、简单的业务逻辑以及可能的实时操作系统如FreeRTOS的移植都游刃有余。它的生态极其完善标准库、HAL库、LL库以及STM32CubeMX图形化配置工具能极大提升开发效率降低从零搭建工程的复杂度。最后是成本与采购的便利性。STM32的开发板、核心板在市场上随处可见价格亲民相关的教程、开源项目浩如烟海遇到问题很容易找到解决方案。对于学生和爱好者来说学习成本和试错成本都相对较低。注意在选择具体型号时务必核对数据手册确认你计划使用的串口引脚如USART1的PA9/PA10 USART2的PA2/PA3没有与其他必须功能如调试接口SWD冲突。使用STM32CubeMX进行引脚分配可视化检查是个好习惯。2.2 人机界面迪文串口屏的优势与协议解析迪文串口屏之所以在工控和爱好者项目中流行是因为它极大简化了GUI开发。开发者无需在单片机端编写复杂的图形驱动和界面逻辑只需通过串口发送简单的指令就能控制屏幕显示文字、图片、曲线甚至处理触摸事件。它的核心优势在于“指令集”模式。屏幕内部运行着迪文自己的内核我们通过单片机向屏幕发送符合“DGUS协议”的指令帧就能完成所有操作。例如要在一个ID为0x1000的文本显示控件上显示“25.6℃”只需要通过串口发送一条包含控件地址和数据内容的指令即可。屏幕接收到指令后会自动完成渲染单片机从繁重的图形处理中解放出来。协议本身是二进制的结构紧凑。一个典型的写数据指令帧可能包含帧头如0x5A A5、数据长度、指令码如0x82写变量存储器、变量地址、数据内容、帧尾校验和。理解并封装好这些指令的生成与解析函数是驱动迪文屏的关键。// 示例向迪文屏变量存储器地址0x1000写入一个16位数据0x0A10 void DWIN_Write_VP(uint16_t addr, uint16_t data) { uint8_t cmd_buf[9]; cmd_buf[0] 0x5A; cmd_buf[1] 0xA5; cmd_buf[2] 0x05; // 后续数据长度 cmd_buf[3] 0x82; // 写指令 cmd_buf[4] (uint8_t)(addr 8); // 地址高字节 cmd_buf[5] (uint8_t)(addr); // 地址低字节 cmd_buf[6] (uint8_t)(data 8); // 数据高字节 cmd_buf[7] (uint8_t)(data); // 数据低字节 // 校验和通常为前面所有字节的和的低字节 cmd_buf[8] cmd_buf[2] cmd_buf[3] cmd_buf[4] cmd_buf[5] cmd_buf[6] cmd_buf[7]; // 通过串口1发送 cmd_buf HAL_UART_Transmit(huart1, cmd_buf, 9, 100); }2.3 网络连接ESP8266 WIFI模组的角色与配置ESP8266在这里扮演着“网络翻译官”的角色。STM32本身通常不带网络功能而ESP8266作为一个高度集成的WIFI SoC可以通过AT指令集被STM32控制实现TCP/IP网络栈的功能。我们通常使用ESP8266的“STATCP Client”模式。即让ESP8266连接到家里的无线路由器STA模式然后作为一个客户端Client去连接远端的服务器比如自己搭建的MQTT服务器、或者公有云平台如阿里云、OneNET的接入服务器。STM32只需要通过串口向ESP8266发送AT指令如ATCWJAP连接WIFI、ATCIPSTART建立TCP连接、ATCIPSEND发送数据就能完成网络通信的所有底层操作。选择ESP8266如ESP-01S模块的原因也很直接价格极低十元左右、资料极多、AT指令成熟稳定。虽然它也可以单独编程NodeMCU固件但在本架构中我们将其作为纯透传模组使用让STM32担任绝对的主控有利于整体逻辑的集中管理。电路连接上需要关注电平匹配。ESP8266的工作电压是3.3V与STM32的IO电平一致可以直接连接RX/TX。但要注意ESP8266在启动和发送数据时峰值电流可能较大务必为其提供独立、稳定的3.3V电源电流能力500mA以上为佳避免因供电不足导致反复重启。3. 系统软件架构设计与多任务处理3.1 基于状态机的多串口数据流管理当STM32需要同时与迪文屏和ESP8266通信时串口数据是异步、不定长到达的。最忌讳的做法是在主循环里用HAL_UART_Receive这种阻塞式接收它会严重影响系统对其他事件的响应。标准的做法是使用中断DMA环形缓冲区Ring Buffer的非阻塞架构。以HAL库为例我们可以初始化串口为中断接收模式并开启空闲中断Idle Interrupt。当串口接收到一帧数据并空闲一段时间后会触发空闲中断。在中断服务函数中我们可以将DMA已传输的数据长度计算出来从而知道这一帧数据有多长然后将其从DMA缓冲区拷贝到我们自定义的环形缓冲区中。主循环只需要定期检查环形缓冲区是否有新数据然后进行解析即可。// 示例串口空闲中断回调函数HAL库 void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) { if(huart-Instance USART1) { // 迪文屏串口 // Size参数即为DMA接收到的数据长度 ring_buffer_write(dwin_rx_buf, uart1_dma_buf, Size); // 重新启动DMA接收 HAL_UARTEx_ReceiveToIdle_DMA(huart1, uart1_dma_buf, DWIN_BUF_SIZE); __HAL_DMA_DISABLE_IT(hdma_usart1_rx, DMA_IT_HT); // 可选关闭半传输中断 } else if(huart-Instance USART2) { // ESP8266串口 ring_buffer_write(esp_rx_buf, uart2_dma_buf, Size); HAL_UARTEx_ReceiveToIdle_DMA(huart2, uart2_dma_buf, ESP_BUF_SIZE); __HAL_DMA_DISABLE_IT(hdma_usart2_rx, DMA_IT_HT); } }对于业务逻辑我强烈推荐使用有限状态机FSM来管理。例如与ESP8266的通信可以划分为几个状态ESP_INIT、ESP_CONNECT_WIFI、ESP_WAIT_WIFI_CONN、ESP_CONNECT_SERVER、ESP_TRANSPARENT_TRANS等。主循环中根据当前状态执行相应的动作如发送特定AT指令并根据解析到的ESP8266回复如“OK”、“ERROR”、“WIFI CONNECTED”来跳转到下一个状态。这样写出来的代码结构清晰易于调试和维护。3.2 迪文屏指令封装与页面管理直接裸写指令字节数组既容易出错又不便阅读。我们需要对常用的迪文屏操作进行函数封装。初始化函数屏幕上电后可能需要发送一些初始化指令比如清屏、设置背光亮度、同步RTC时间等。页面切换函数迪文屏工程通常有多个页面.icl文件。切换页面指令是固定的封装成函数DWIN_ChangePage(uint8_t page_id)。数据更新函数这是最常用的。根据你屏幕上控件的类型文本、数值、图标、曲线封装对应的写入函数。例如DWIN_UpdateText(uint16_t addr, char *str)更新文本显示。DWIN_UpdateValue(uint16_t addr, int32_t value)更新数值显示可能需要转换为ASCII或特定格式。DWIN_UpdateIcon(uint16_t addr, uint16_t icon_id)控制图标显示/隐藏。触摸事件处理迪文屏会将触摸控件的地址和数据通过串口返回。我们需要在解析函数中根据返回的地址如按钮地址执行对应的动作比如切换页面、向STM32发送控制命令、触发网络数据上传等。一个良好的页面管理策略是在STM32端用一个全局变量current_page记录当前页面ID。当收到触摸事件或需要跳转时更新这个变量并调用页面切换函数。这样不同页面的业务逻辑如页面1显示温湿度页面2显示历史曲线就可以通过switch(current_page)语句来组织逻辑隔离性好。3.3 ESP8266 AT指令驱动层与网络协议适配驱动ESP8266的核心是构建一个健壮的AT指令发送与响应解析引擎。不能简单地发送指令后死等“OK”。一个完整的AT指令交互过程应包括发送指令、等待响应、超时处理、响应结果判断。typedef enum { ESP_STA_IDLE, ESP_STA_SENT_AT, ESP_STA_WAIT_OK, ESP_STA_SENT_CWMODE, // ... 更多状态 } ESP_State_t; ESP_Status_t ESP_Send_Command_And_Wait(const char *cmd, const char *expect_reply, uint32_t timeout_ms) { HAL_UART_Transmit(huart2, (uint8_t*)cmd, strlen(cmd), 100); clear_esp_rx_buffer(); uint32_t tickstart HAL_GetTick(); while((HAL_GetTick() - tickstart) timeout_ms) { if(ring_buffer_find(esp_rx_buf, expect_reply)) { return ESP_OK; } // 也可以在这里判断是否包含“ERROR”等失败信息 if(ring_buffer_find(esp_rx_buf, ERROR)) { return ESP_FAIL; } } return ESP_TIMEOUT; }在网络协议选择上对于简单的数据上报和指令下发裸TCP/UDP Socket或HTTP/HTTPS POST/GET足以应付。但如果涉及设备间双向通信、一对多发布订阅等复杂场景强烈建议使用MQTT协议。ESP8266的AT固件通常支持MQTT的AT指令。MQTT的“主题”发布/订阅模型非常契合物联网设备与云平台的交互能大大简化你的应用层协议设计。你可以选择连接公共的MQTT Broker如EMQX的公开服务或者在自己的服务器上搭建一个。4. 数据流整合与业务逻辑实现4.1 从传感器到屏幕实时数据流处理假设我们使用一个I2C接口的温湿度传感器如SHT30。STM32需要定时例如每2秒读取传感器数据然后将处理后的结果更新到迪文屏上。这个过程是一个典型的生产者-消费者模型。传感器读取是生产者屏幕更新是消费者。为了避免在屏幕串口通信耗时过长时影响传感器读取的定时准确性我们可以使用一个共享变量如float current_temperature作为数据中介。定时器中断或一个独立的任务负责更新这个共享变量。主循环或另一个低优先级任务负责检查这个变量是否有“新数据”标志如果有则调用DWIN_UpdateValue()函数更新屏幕并清除标志。volatile float sensor_temp 0.0, sensor_humi 0.0; volatile uint8_t sensor_data_ready 0; // 在定时器回调或一个任务中 void Sensor_Read_Task(void) { if(SHT30_Read(temp, humi) HAL_OK) { sensor_temp temp; sensor_humi humi; sensor_data_ready 1; // 设置标志 } } // 在主循环中 void Main_Loop(void) { // ... 其他处理 if(sensor_data_ready) { DWIN_UpdateValue(VAR_ADDR_TEMP, (int)(sensor_temp * 10)); // 放大10倍传输以保留一位小数 DWIN_UpdateValue(VAR_ADDR_HUMI, (int)sensor_humi); sensor_data_ready 0; // 清除标志 } // ... 其他处理 }对于需要平滑显示的数据如波形可以在STM32端做一个简单的滑动平均滤波再将结果发送给屏幕可以避免波形抖动过于剧烈。4.2 从屏幕到云端控制指令与数据上报流数据流向另一个方向从触摸屏或云端到设备控制。本地控制流用户在迪文屏上点击了一个“打开继电器”的按钮。屏幕会通过串口向STM32发送一条指令比如“AA BB 03 01 CC DD EE FF”假设的协议。STM32在解析迪文屏返回数据的函数中识别到按钮地址和按下动作然后执行HAL_GPIO_WritePin(RELAY_GPIO_Port, RELAY_Pin, GPIO_PIN_SET)。同时可以更新屏幕上一个指示灯的图标给予用户反馈。云端上报流STM32可以定时如每30秒或在数据变化时将当前传感器数据通过ESP8266上报到云端。这里就涉及到数据封装。一个简单的方法是封装成JSON格式通过HTTP POST发送或者通过MQTT发布到一个主题如device/123456/sensor_data。// 构造一个简单的JSON字符串 char mqtt_payload[128]; snprintf(mqtt_payload, sizeof(mqtt_payload), {\dev_id\:\%s\,\temp\:%.1f,\humi\:%.0f,\relay\:%d}, DEVICE_ID, sensor_temp, sensor_humi, relay_status); // 然后通过AT指令发送MQTT发布命令 ESP_MQTT_Publish(device/data, mqtt_payload);云端控制流手机App通过云端下发指令比如关闭继电器。云端服务器通过MQTT或HTTP将指令下发给ESP8266。ESP8266通过串口将指令原文如{“cmd”:”relay_off”}传给STM32。STM32解析JSON可以使用轻量级库如cJSON执行对应操作关闭继电器GPIO并更新迪文屏状态最后可能还要发送一个确认报文回云端。这样就完成了一个完整的云端-设备-屏幕的闭环控制。4.3 心跳、重连与异常处理机制一个健壮的物联网设备必须能应对网络异常。心跳机制是保持长连接和检测连接状态的有效手段。你可以让STM32定时如每60秒通过ESP8266向服务器发送一个心跳包比如一个特定的MQTT消息或一个简短的HTTP请求。如果连续几次发送失败或收不到服务器回应则认为网络连接已断开此时状态机应回退到ESP_CONNECT_WIFI或ESP_CONNECT_SERVER状态发起重连。对于ESP8266本身也要有超时重启的备选方案。如果长时间比如5分钟无法与服务器建立有效通信且重试多次失败可以考虑通过STM32的GPIO控制一个连接到ESP8266复位脚的MOSFET对其进行硬件复位。这是一种最终手段但能有效解决模组“死机”的问题。所有涉及网络和外部设备屏幕、传感器的操作都必须有超时处理。在发送指令后启动一个软件定时器超时后无论是否收到响应都要离开等待状态进行错误计数或执行补救措施防止整个系统因某个环节卡死而停滞。5. 开发环境搭建与关键调试技巧5.1 利用STM32CubeMX快速初始化工程STM32CubeMX是ST官方推出的图形化配置工具能极大加速项目初期搭建。使用步骤如下选择芯片型号在“Pinout Configuration”界面选择你使用的具体STM32型号。配置时钟树根据外部晶振频率配置系统主频到最高如STM32F103C8T6配置为72MHz。CubeMX会自动计算并设置好各分频系数确保时钟配置正确。配置外设USART1连接迪文屏模式选择“Asynchronous”波特率设置为迪文屏支持的速率通常是115200或9600。记得开启全局中断。USART2连接ESP8266同样配置为异步模式波特率通常为115200。开启全局中断。I2C1连接传感器配置为I2C模式选择合适的时钟速度如100kHz。GPIO配置控制继电器的GPIO为输出模式并设置初始电平。定时器配置一个基本定时器如TIM6用于产生系统时基或传感器读取定时。配置DMA可选但推荐在USART1和USART2的DMA Settings标签页为RX方向添加DMA请求。模式选择“Circular”循环模式这样配合空闲中断可以实现自动的不定长数据接收。生成代码在“Project Manager”中设置好IDEKeil MDK或STM32CubeIDE、工程路径和名称选择“HAL库”然后生成代码。这样一个包含所有外设初始化的基础工程就生成了你只需要在生成的main.c、stm32f1xx_it.c等文件中添加自己的业务逻辑即可。5.2 串口调试的“三板斧”调试多串口系统清晰的调试信息至关重要。启用调试串口除了连接迪文屏和ESP8266的串口强烈建议再启用一个串口如USART3连接到电脑的USB转串口工具专门用于打印调试日志。使用printf重定向到该串口可以方便地打印变量值、状态信息、错误提示。// 在usart.c中重写fputc函数 int fputc(int ch, FILE *f) { HAL_UART_Transmit(huart3, (uint8_t *)ch, 1, 0xFFFF); return ch; } // 然后就可以在主函数中使用printf了 printf([System] Boot OK. Current Page: %d\r\n, current_page);逻辑分析仪或示波器当通信异常时仅靠打印信息可能不够。用逻辑分析仪抓取STM32与迪文屏或ESP8266之间的TX、RX引脚波形可以直观地看到发送的每一个字节、时序、波特率是否正确。这是排查硬件连接问题和底层驱动问题的终极武器。分段验证法不要试图一次性让整个系统跑通。应该分模块调试第一步先让调试串口printf工作。第二步单独调试迪文屏。写一个最简单的程序只循环发送一条清屏指令看屏幕是否有反应。第三步单独调试ESP8266。使用调试串口手动发送AT指令可以通过STM32转发验证WIFI连接和TCP连接是否正常。第四步单独调试传感器读取数据并通过调试串口打印。最后再将所有模块整合起来。5.3 迪文屏与WIFI模组的独立测试在接入STM32之前最好先用USB转TTL工具分别测试迪文屏和ESP8266确保它们本身是好的并且你理解了其通信协议。迪文屏测试将屏幕的RX/TX/GND连接到USB转TTL工具打开串口助手如XCOM、SSCOM。设置好波特率以十六进制格式发送一条简单的指令比如页面切换指令5A A5 07 82 00 84 5A 01 00 01切换到页面1。如果屏幕有反应页面切换说明屏幕和指令理解正确。迪文官方提供的“DGUS Tool”软件也可以用来在线调试屏幕非常方便。ESP8266测试同样连接好USB转TTL注意电压必须是3.3V。上电后在串口助手发送AT\r\n应该能收到OK的回复。然后依次测试ATCWMODE1设置STA模式、ATCWJAP你的WiFi名,密码、ATCIPSTARTTCP,服务器IP,端口等指令。这个过程能让你熟悉AT指令的交互流程和常见回复为编写驱动代码打下坚实基础。6. 常见问题排查与稳定性优化实录6.1 通信失败问题集中排查在实际焊接和调试中通信问题是最常遇到的。下面是一个排查清单问题现象可能原因排查步骤与解决方案迪文屏无任何显示1. 电源问题电压不足或电流不够2. 波特率不匹配3. TX/RX接反4. 屏幕内核文件未正确下载1. 用万用表测量屏幕供电电压是否为5V或3.3V视型号而定确保电源能提供足够电流通常需500mA以上。2. 核对代码中串口初始化波特率与屏幕设置波特率是否一致常用115200。3. 交换STM32与屏幕的TX和RX线。4. 使用SD卡将正确的 .icl, .cfg, .fon等文件下载到屏幕Flash中。迪文屏花屏或局部显示异常1. 电源纹波过大2. 干扰严重3. 显示变量地址或数据格式错误1. 在屏幕电源引脚就近并联一个100uF的电解电容和一个0.1uF的瓷片电容滤波。2. 检查通信线是否过长尝试使用屏蔽线或双绞线并远离电机等干扰源。3. 使用迪文屏的“变量跟踪”功能检查STM32发送的数据是否与屏幕工程中定义的变量类型、地址匹配。ESP8266无法连接WiFi1. AT指令格式错误2. WiFi密码错误或信号弱3. 模块供电不足4. 模块固件不支持某些指令1. 确保AT指令以\r\n结尾。通过调试串口打印出发送的原始指令进行核对。2. 用手机确认WiFi信号强度并检查密码中的特殊字符。3. 测量ESP8266 VCC引脚电压在模块发射数据时电压不应跌落太多3.0V。使用独立LDO供电。4. 尝试使用ATGMR查看固件版本必要时使用Flash下载工具刷新最新AT固件。ESP8266连接服务器失败1. 网络不可达服务器IP/端口错2. 路由器防火墙或服务器防火墙限制3. TCP连接数已满1. 用电脑上的网络调试助手在服务器端创建TCP Server先用ESP8266连接电脑测试。2. 检查服务器安全组规则和防火墙开放对应端口。3. 确保服务器端程序能处理多连接或及时释放已断开连接。数据上传偶尔丢失1. 未处理网络发送拥堵2. 未等待上次发送完成就发起新发送3. 服务器处理超时1. 在发送ATCIPSEND指令前先检查模块是否返回“”提示符。2. 实现一个“发送完成”确认机制例如等待收到“SEND OK”后再进行下一次发送。3. 优化服务器端代码设置合理的Socket超时时间和缓冲区。6.2 系统稳定性与抗干扰设计心得电源是重中之重单片机系统大部分诡异的问题都源于电源。务必为STM32、迪文屏、ESP8266提供独立、干净、充足的电源。模拟部分如传感器与数字部分MCU、屏幕的电源最好用磁珠或0欧电阻隔离。在每个芯片的电源引脚附近都必须放置一个0.1uF的退耦电容并且尽量靠近引脚。地线设计确保整个系统有一个完整、低阻抗的“地平面”。单点接地是理想情况在复杂系统中难以实现但至少要保证地线回路尽量短粗避免形成环路天线引入干扰。信号完整性串口通信线如果超过20厘米就要考虑信号质量。使用双绞线并在STM32的输出端串联一个33欧姆左右的电阻可以抑制过冲和振铃提高通信可靠性。对于ESP8266这类射频模块其天线周围要严格按照数据手册要求进行布局净空处理避免金属遮挡。软件看门狗一定要开启STM32的独立看门狗IWDG或窗口看门狗WWDG。在主线任务和关键子任务中定期“喂狗”。这样即使程序因为未知原因跑飞也能自动复位避免设备“假死”。对于ESP8266也可以在软件上实现“守护线程”定期发送AT指令检查其是否存活无响应则触发硬件复位。数据校验与重发无论是与屏幕还是与云端的通信应用层协议最好加上校验如CRC16。对于重要的控制指令或数据上报可以实现简单的应答重发机制。发送方等待接收方的确认帧超时未收到则重发重发次数超过阈值则记录错误。这能有效应对偶发的数据包丢失。6.3 内存管理与性能优化要点在资源有限的STM32上内存使用需精打细算。避免动态内存分配在嵌入式实时系统中使用malloc/free容易产生内存碎片导致不可预知的问题。所有缓冲区如串口接收缓冲、JSON构造缓冲都使用静态数组在编译时分配。合理设置缓冲区大小迪文屏指令帧较短但ESP8266的AT指令响应可能很长尤其是收到服务器数据时。给ESP8266的接收环形缓冲区要足够大建议512字节以上。同时发送缓冲区也要匹配MQTT报文或HTTP请求的最大可能长度。优化串口中断服务函数中断函数里只做最必要的事情——拷贝数据到环形缓冲区、清除标志、重启DMA。所有耗时的解析、处理逻辑都放到主循环或任务中。绝对避免在中断里调用HAL_Delay或进行复杂的字符串处理。使用查表法替代复杂运算例如将传感器ADC原始值转换为实际物理量时如果计算涉及浮点运算且频繁执行可以考虑预先计算一个查找表用查表加插值的方法来替代实时计算能节省大量CPU时间。STM32F1系列没有硬件FPU浮点运算尤其耗时。经过以上从硬件到软件、从原理到实操的详细拆解相信你已经对如何构建STM32迪文屏WIFI模组的数据交互系统有了全面的认识。这套架构的灵活性很高你可以替换其中的任意部分比如把ESP8266换成4G Cat.1模组实现更广域的连接或者把迪文屏换成更廉价的TFT屏配合LVGL库来自主开发UI。核心思想是不变的明确各模块的边界与接口用状态机管理复杂流程重视调试和稳定性设计。在实际动手时耐心按照分模块调试的方法进行遇到问题多利用调试工具观察波形和数据大部分难题都能迎刃而解。