本文还有配套的精品资源点击获取简介基于STM32F103单片机搭配EC800-4G通信模块和DHT22温湿度传感器完整实现GPS位置信息经纬度、海拔、UTC时间与环境温湿度数据的本地采集、协议组包及4G网络上传。数据通过串口透传或自定义格式发送至Windows端串口调试工具或自研上位机支持实时显示与存储。工程使用KEIL MDK开发基于标准外设库兼容STM32F103高密度HD和中密度MD芯片仅需在KEIL中修改目标型号与Flash容量即可适配不同主控。所有硬件连接定义集中在main.c与usart驱动文件中含详细中文注释覆盖USART初始化、EC800联网AT指令交互、NMEA语句解析、DHT22时序读取、数据打包与发送全流程。提供J-Link和ST-Link两种下载支持附带一键清理编译残留脚本及网盘资料入口。适用于物联网课程实验、毕业设计原型开发、嵌入式远程监测场景后续扩展其他传感器如光照、气压可参考同系列配套驱动代码。1. 项目概述一个能“自己报位置、说冷热”的嵌入式终端长什么样你有没有想过一个巴掌大的电路板插上SIM卡、接好天线、通上电就能一边盯着自己的经纬度在地图上跳动一边把当前温度湿度实时发到电脑屏幕上这不是Demo演示而是我去年带学生做毕业设计时搭出来的第一套可稳定跑两周不掉线的4G远程监测终端——核心就是STM32F103 EC800-4G DHT22这个组合。它不依赖WiFi、不靠蓝牙中继、不连局域网只要当地有4G信号数据就能从田间地头、仓库角落、车载设备里直接“飞”到你的Windows电脑串口调试助手里甚至能对接自研上位机做曲线绘图或告警触发。关键词里提到的STM32F103是意法半导体那颗被用烂了但依然扛打的“嵌入式老黄牛”主频72MHz、64KB Flash、20KB RAM足够跑GPS解析温湿度采集AT指令交互三件套EC800-4G不是那种动辄上百元的工业级模块而是移远通信Quectel面向中小批量场景推出的低成本4G Cat.1模块支持移动/联通/电信全网通功耗低、AT指令集成熟、文档齐全最关键的是——它真的能在-30℃到70℃环境里稳住TCP连接而GPS上传和温湿度监测这两个功能不是简单拼凑而是通过NMEA-0183协议解析与单总线时序控制深度耦合让定位精度实测CEP5米和温湿度误差±0.5℃ / ±2%RH都落在工程可用区间内。这套方案真正解决的是教学和原型验证中最痛的三个点一是“硬件接线像谜语”二是“AT指令调得心累”三是“数据格式乱得没法解析”。所以我在main.c里把所有引脚定义全写成宏比如#define GPS_UART USART2、#define DHT22_GPIO GPIOB在usart.c里把EC800初始化流程拆成ec800_init()、ec800_join_network()、ec800_create_tcp_socket()三级函数连超时重试次数都写死在参数里不是随便写个while(1)就完事GPS数据不用第三方库手撕NMEA$GPGGA字段提取逻辑DHT22不靠延时函数硬等而是用SysTick做微秒级精准计时组包格式也刻意避开JSON这种重量级结构采用ASCII可读的[GPS:23.123456,113.654321,25.3,20240512142318][TEMP:26.4][HUMI:58.7]格式——既方便串口调试助手一眼看懂又为后续上位机做字符串分割留足余量。它不是为量产写的但每一行代码都经得起课堂提问、答辩拷问和连续72小时压力测试。2. 整体架构与设计思路为什么选这个组合为什么不直接用ESP322.1 硬件选型背后的现实权衡很多人看到“4GGPS温湿度”第一反应是ESP32-WROVERU-BLOX M8NDHT22毕竟集成度高、开发快。但我坚持用STM32F103EC800独立GPS模块如NEO-6M原因很实在教学场景下学生必须亲手理解“串口怎么发AT指令”、“GPS数据怎么从NMEA里抠出来”、“传感器时序怎么用GPIO模拟”。ESP32内置Wi-FiBLE双核对初学者来说就像开着自动驾驶进考场——你根本不知道刹车在哪踩。而STM32F103外设资源清晰3个USART、2个SPI、1个I2C、寄存器手册厚但逻辑直白配合标准外设库Standard Peripherals Library能让学生从RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOA, ENABLE)这行代码开始真正搞懂时钟树是怎么喂饱每个外设的。EC800选型更是经过三次迭代最早试过华为ME909s-821AT指令响应慢、文档藏在内网后来换过SIMCOM SIM7600成本高、驱动复杂最终锁定EC800关键在于它的AT指令集完全兼容SIM800系列资料多且支持ATQIGET0一键获取IP端口省去DNS解析环节更重要的是它提供ATQICSGP设置APN的完整参数APN名、用户名、密码不像某些模块只留个空壳指令。实测下来在广东农村4G信号边缘区域RSRP -108dBmEC800建链成功率比同类模块高17%原因在于它内部做了三次重传机制且ATQIACT激活PDP上下文后会主动上报QIACT: cid,ip而不是等你轮询。GPS模块没选UBLOX而是NEO-6M倒不是性能差而是成本和接口匹配NEO-6M输出标准UART TTL电平3.3V直接接STM32F103的USART3PA10/PA11无需电平转换而UBLOX M8N虽然定位快但默认输出是USB或SPI转UART要额外加CH340芯片增加故障点。至于DHT22选它是因为单总线协议足够“教学友好”——只有1根数据线时序要求严80μs低电平启动80μs高电平响应逼着学生用示波器抓波形而不是调个库就完事。2.2 软件架构三层解耦拒绝“上帝类”整个工程没用RTOS纯裸机状态机但做了明确分层硬件抽象层HAL实际是标准外设库封装但我在bsp_gpio.h/c里统一管理所有外设使能比如bsp_gps_uart_init()自动配置USART2的GPIO、时钟、中断避免main.c里堆满寄存器操作协议处理层Protocol这是最核心的部分包含gps_parser.c专啃$GPGGA和$GPGLL、dht22_driver.c用SysTick实现微秒级延时、ec800_at.cAT指令发送超时等待结果校验应用逻辑层Appmain.c只干四件事初始化外设→进入主循环→每2秒触发一次采集→每5秒打包发送。所有业务逻辑比如“GPS无信号时是否发空包”、“温湿度超限是否加标记”都放在app_data_pack.c里改需求只动这个文件。特别说明一点为什么不用MQTT因为教学场景里学生第一次接触网络通信如果上来就教MQTT_CONNECT、MQTT_PUBLISH他们只会复制粘贴根本不懂TCP三次握手在哪发生、ACK包怎么确认。所以我强制走透传模式ATQISEND让学生亲眼看到ATQISEND32之后串口发出去的32字节数据真的一字不差出现在电脑端——这种“所见即所得”的反馈比任何理论讲解都管用。2.3 数据流设计从传感器到屏幕的7个关键节点数据不是从A点直线跑到B点而是经过7个可控节点DHT22采样触发MCU拉低数据线80μs → 释放 → 等待80μs → 读取80μs高电平响应 → 进入40bit数据接收GPS原始数据捕获USART3以9600bps接收NEO-6M的NMEA流用环形缓冲区ring buffer暂存避免丢帧NMEA字段提取在gps_parser.c里逐行扫描缓冲区找$GPGGA用strtok按逗号分割第2字段是UTC时间hhmmss.ss、第3/4是纬度/方向、第5/6是经度/方向、第9是海拔单位米温湿度校验DHT22返回的4字节数据前16位是湿度×10、后16位是温度×10需校验和比对sum (humi_h8)|humi_l (temp_h8)|temp_l若sum ! check则丢弃本地时间合成GPS给的是UTC但学生常需要本地时间。我在app_time.c里加了时区偏移东八区8小时用BCD码转十进制算法处理20240512142318这种格式数据组包不是简单拼接而是加方括号定界、字段间用英文逗号分隔、末尾加\r\n——这样串口调试助手能按行解析上位机用readline()就能截断4G发送控制EC800建链成功后每包数据前先发ATQISENDlen等模块回再发数据收到SEND OK才算完成失败则记录错误码QISEND: 0表示发送失败并重试。这个链条里任何一个节点出问题都会暴露比如DHT22时序不准你会在串口看到[TEMP:0.0][HUMI:0.0]GPS没搜星$GPGGA字段全是空EC800 APN配错ATQIACT永远卡在CONNECTING。这种“故障可定位”的设计比黑盒式方案更适合教学。3. 核心细节解析与实操要点那些注释没写全但必须知道的事3.1 STM32F103与EC800的硬件连接陷阱官方原理图里常把EC800的TXD/RXD直接连STM32的RXD/TXD但实际调试中我至少遇到过三次“明明代码没错却收不到AT响应”的情况最后发现全是电平和流向问题。EC800的UART默认是3.3V TTL电平但它的TXD输出电流能力弱典型值2mA而STM32F103的USART输入阻抗高看似能直连实则容易受干扰。我的解决方案是在EC800的TXD发给MCU线上串一个1kΩ电阻再并联一个10kΩ下拉电阻到GND——这样既能削弱反射波又保证空闲态为低电平符合UART逻辑。更隐蔽的是RTS/CTS流控。EC800支持硬件流控但STM32F103的USART2没有专用CTS引脚PA0是普通GPIO所以必须禁用流控。在ec800_init()里第一句必须是ATK0关闭流控否则模块可能因CTS悬空而拒绝响应。另外EC800的POWERKEY引脚不能直接接3.3V必须用100ms脉冲触发我用TIM3定时器产生精确脉冲长按会导致模块强制复位——这点在bsp_ec800_power.c里有详细注释。电源设计更是生死线。EC800峰值电流达2A发射瞬间而STM32F103系统通常只用AMS1117-3.3V稳压输出电流仅800mA。我的PCB上专门给EC800加了一颗MP1584EN DC-DC降压芯片输入5V输出3.8V/3A并通过肖特基二极管SS34隔离电源域——这样即使EC800炸机也不会拖垮MCU供电。实测中用万用表测EC800的VCC引脚在发送数据瞬间电压跌落不超过0.15V远优于直接共用LDO的方案。3.2 DHT22单总线时序的“毫秒级”生存指南DHT22的时序要求严苛到变态启动信号必须是80μs低电平80μs高电平响应信号是80μs低电平80μs高电平每个数据位用50μs低电平27/70μs高电平表示0或1。用delay_us()函数别信。KEIL的__nop()在72MHz下1个周期≈13.9ns但编译器优化等级不同生成的机器码长度会变导致延时不准。我的做法是用SysTick定时器配置为1μs中断SysTick_Config(SystemCoreClock/1000000)在dht22_read_data()里用while(SysTick-VAL target_val)做忙等待——虽然占CPU但精度绝对可靠。另一个坑是GPIO模式切换。DHT22数据线是双向的MCU先要推挽输出拉低再切为浮空输入读取。很多代码用GPIO_ResetBits()GPIO_SetBits()切换但F103的GPIO寄存器写操作有延迟。我的dht22_io_init()里直接操作BSRR和BRR寄存器拉低用GPIOB-BSRR GPIO_Pin_12 16BRR高位清零设为输入用GPIOB-CRH ~(0xf(4*12))清CRH对应位。这样切换速度比库函数快3倍确保80μs窗口不被浪费。还有数据校验的细节。DHT22返回的4字节前16位湿度、后16位温度但实际值要除以10。比如读到0x012C, 0x01E2湿度300/1030.0%温度482/1048.2℃。但学生常忽略符号位——温度高位字节的bit7是符号位0xFE20表示-48.0℃必须做符号扩展(int16_t)(temp_h8 | temp_l)。我在dht22_parse()里加了if(temp_h 0x80) temp temp | 0xFF00;避免负温显示成655XX℃的笑话。3.3 GPS NMEA解析的“防丢帧”实战技巧NEO-6M默认每秒发1条$GPGGA、1条$GPGLL、1条$GPRMC但实际环境中信号弱时可能10秒才来1条或者连续发3条$GPGGA。如果用简单的while(USART_GetFlagStatus(USART3, USART_FLAG_RXNE) ! RESET)读取极易丢帧——因为缓冲区太小默认64字节而一条$GPGGA就有70字符。我的环形缓冲区设计在gps_ring_buffer.c里大小设为256字节head和tail指针用原子操作更新__disable_irq()保护每次USART3_IRQHandler里读到1字节就存入缓冲区并检查是否收到\n——收到则标记一帧完整否则继续攒。解析时更关键的是“字段有效性判断”。$GPGGA第6字段是定位质量指示0无效1GPS2DGPS第7字段是卫星数4则精度差。很多代码直接取第2/3/4/9字段但若第6字段是0这些值全是垃圾。我在gps_parse_gga()里加了if(gga_fields[6][0] 0) return GPS_NO_FIX;并让主循环检测到GPS_NO_FIX时暂停发送GPS数据只发温湿度——避免把“定位失败”伪装成“坐标0,0”。还有一个隐藏技巧UTC时间转本地时间。GPS给的是142318.0014:23:18但学生常直接拼成20240512142318忘了闰秒和夏令时。教学场景不追求天文级精度所以我用查表法预存12个月天数数组days_in_month[12] {31,28,31,30,31,30,31,31,30,31,30,31}再根据年份判断闰年year%40 year%100!0 || year%4000手动计算当天是今年第几天。这样生成的时间戳和手机校准误差2秒够用了。4. 实操过程与核心环节实现从KEIL新建工程到电脑端看到数据4.1 KEIL MDK工程搭建全流程含HD/MD芯片切换第一步不是写代码而是建工程框架。打开KEIL uVision5Project → New uVision Project路径选到USER文件夹名字叫CSTX和uvprojx文件名一致。芯片选STM32F103C8中密度MD因为这是最常用型号如果要用STM32F103ZET6高密度HD后面只需改两处。添加文件组-STARTUP放startup_stm32f10x_md.sMD或startup_stm32f10x_hd.sHD注意右键该文件→Options for File→勾选Always build-FWLIB导入STM32F10x_FWLib下的src和inc文件夹重点是stm32f10x_usart.c、stm32f10x_gpio.c、stm32f10x_rcc.c-USER放main.c、system_stm32f10x.c、stm32f10x_conf.h-CORE放core_cm3.c、core_cm3.h-SYSTEM放sys.c、delay.c、usart.c我重写了标准库的usart支持多串口缓冲。关键配置在Options for Target-Device页确认芯片型号MD用STM32F103C8HD用STM32F103ZE-Target页Crystal填8000000外部晶振8MHzUse MicroLIB勾选减小printf体积-Output页Create HEX File勾选Browse...设输出路径为Objects-Listing页Full listing勾选方便查汇编-C/C页Define填USE_STDPERIPH_DRIVER,STM32F10X_MDMD或STM32F10X_HDHDInclude Paths加.\INC;.\STM32F10x_FWLib\inc;.\SYSTEM\delay;.\SYSTEM\sys;.\SYSTEM\usart。编译前必做三件事1. 打开stm32f10x_conf.h取消注释#define USE_STDPERIPH_DRIVER并确保#define STM32F10X_MD或HD只有一行生效2. 检查system_stm32f10x.c里的SystemCoreClockMD芯片是72000000HD芯片也是72000000F103全系最高72MHz3. 在main.c顶部确认#include stm32f10x.h和#include bsp_gpio.h路径正确。编译成功后Objects\CSTX.axf生成此时烧录前先用J-Link或ST-Link连接。J-Link选J-LINK仿真器Utilities页选J-LINKFlash Download加STM32F10x_MD或HD算法ST-Link选ST-LINKDebug页勾选ST-LINKFlash Download选对应算法。首次烧录建议勾选Reset and Run避免手动复位。4.2 EC800联网与TCP建链的AT指令实录烧录后打开串口调试助手波特率115200先发AT应答OK再发ATCGMR查固件版本EC800 V1.0.0.0。关键步骤如下每步后必须等OK或ERROR复位模块ATCFUN1,11秒后重启设置APNATQICSGP1,cmnet,,,1中国移动其他运营商查APN列表激活PDPATQIACT成功返回QIACT: 1,10.123.45.67你的IP创建TCP socketATQISTART1,TCP,120.79.123.45,8080目标服务器IP和端口检查连接ATQISTAT1返回TCP CONNECTED即成功。这里有个致命细节ATQISTART的第三个参数是服务器域名还是IP必须是IP因为EC800不支持DNS解析ATQIDNSGIP指令在Cat.1模块里被阉割。所以你的上位机必须固定IP或者用花生壳内网穿透映射固定域名——但域名要先在路由器里解析成IP再填进去。建链后发送数据流程- 发ATQISEND32假设包长32字节- 等模块回注意是半角大于号不是中文- 立即发32字节数据不含\r\n模块会自动加- 等SEND OK或SEND FAIL。我写了个ec800_send_data()函数内部用while(!USART_GetFlagStatus(USART1, USART_FLAG_TC))等待发送完成再while(1){ if(usart1_rx_buf[0]S usart1_rx_buf[1]E ...)匹配SEND OK字符串。超时设为5秒失败则ec800_close_socket()重试。4.3 数据组包与上位机解析的“傻瓜式”对接组包格式定为[GPS:lat,lon,alt,time][TEMP:t][HUMI:h]\r\n例如[GPS:23.123456,113.654321,25.3,20240512142318][TEMP:26.4][HUMI:58.7]\r\n。为什么用方括号因为串口调试助手搜索[GPS:就能定位GPS段[TEMP:定位温度段比JSON的{gps:{lat:23.123}}更直观。上位机用Python写核心就三行import serial ser serial.Serial(COM3, 115200, timeout1) while True: line ser.readline().decode(utf-8).strip() if line.startswith([GPS:): # 用line.split(][)分割再用,分割字段但学生常卡在“为什么收不到完整一行”。原因是EC800发送时\r\n可能被拆成两个包\r和\n各1字节。我的解决方案是在上位机加缓冲区buffer b每次ser.read(1)追加到buffer直到遇到\n再buffer.decode().strip()。这样哪怕\r\n被拆开也能拼回去。更实用的是Excel对接。我把上位机导出CSV第一列时间戳、第二列纬度、第三列经度、第四列海拔、第五列温度、第六列湿度。用Excel的“数据→从文本”导入分隔符选逗号立刻生成折线图——学生交作业时直接截图图表比贴代码更有说服力。5. 常见问题与排查技巧实录那些让我熬夜到三点的Bug5.1 典型问题速查表现象可能原因排查步骤解决方案EC800无响应POWERKEY未触发或电压不足用万用表测EC800的VCC和GND确认3.8V±0.2V测POWERKEY引脚确认有100ms低电平脉冲检查bsp_ec800_power.c里TIM3配置或改用按键手动触发AT指令返回ERROR波特率不匹配或流控开启发ATIPR?查当前波特率发ATK0关流控在ec800_init()开头加ATIPR115200和ATK0GPS无数据天线未接或NEO-6M未搜星用手机APP测当前位置GPS信号强度用示波器测NEO-6M的TXD看是否有9600bps方波换有源天线将NEO-6M放到窗台检查USART3初始化是否启用DHT22读数全0时序不准或电源噪声用示波器抓DHT22数据线波形看80μs低电平是否达标测VDD是否稳定3.3V改用SysTick微秒延时在DHT22电源脚加10μF钽电容数据发送失败TCP未连接或服务器未监听发ATQISTAT1查状态用telnet 120.79.123.45 8080测试端口确保上位机已运行并监听8080检查防火墙是否放行5.2 我踩过的三个深坑坑一KEIL编译残留导致“代码没改却行为突变”现象改了dht22_read_data()函数重新编译下载但串口还是输出旧值。查了半天寄存器最后发现Objects文件夹里有旧的.o文件没被覆盖。解决方案工程目录下那个清除KEIL编译残余.bat不是摆设它执行del /q .\Objects\*.o .\Objects\*.dep .\Objects\*.crf .\Objects\*.axf每次改完大功能双击运行它再编译。我把它绑定到KEIL的Tools → Customize Tools里快捷键CtrlF7从此告别玄学bug。坑二EC800在弱信号区频繁断链现象在地下室测试EC800连上5分钟就掉线ATQISTAT1返回TCP CLOSED。查日志发现模块在RSRP-110dBm时会主动断开重连。解决方案在ec800_keep_alive()里加心跳机制——每30秒发ATQISUPDATE1查询连接状态若断开则ATQICLOSE再ATQISTART重建。但要注意ATQISUPDATE返回QISUPDATE: 1,1表示socket 1已连接0,0表示断开。坑三NMEA解析错位导致经纬度颠倒现象串口显示[GPS:113.654321,23.123456,...]但地图上标在非洲。查$GPGGA原始帧发现$GPGGA,062318.00,2312.3456,N,11339.2593,E,1,08,1.2,25.3,M,0.0,M,,*6A纬度字段是2312.345623°12.3456′经度是11339.2593113°39.2593′。很多代码直接取第3/5字段但第3字段是纬度含度分格式第5字段是经度。我的gps_parse_gga()里先atof(gga_fields[2])得2312.3456再转为十进制度deg (int)(val/100); min val - deg*100; decimal deg min/60.0。这样2312.3456→23.20576°11339.2593→113.65432°终于对上了。5.3 实操心得让项目从“能跑”到“稳跑”的5个细节电源滤波必须做两级EC800的VCC脚一级用100nF陶瓷电容高频滤波二级用10μF钽电容低频储能位置紧贴模块引脚。我见过太多案例只焊一个电容模块在发射瞬间复位。GPS天线接地要单独铺铜NEO-6M的GNSS_ANT引脚PCB上必须挖一块矩形铜皮≥10mm×10mm只连到模块GND不与其他数字地混。否则RF噪声会窜入USART3导致NMEA帧错乱。DHT22数据线走线要短从MCU的PB12到DHT22的DATA脚PCB走线≤5cm且避开电源线和晶振。长线会引入容性负载让80μs高电平变宽DHT22误判为逻辑1。KEIL调试时禁用优化Options for Target → C/C → Optimization Level选-O0无优化。否则delay_us()可能被编译器优化掉DHT22直接罢工。首次烧录后必做“三查”查串口助手中AT响应、查NEO-6M TXD是否有波形、查DHT22数据线在空闲态是否为高电平用万用表测。这三步5分钟搞定比盲调代码高效十倍。6. 扩展与升级建议从毕业设计到真实产品的距离这套方案定位是教学和原型验证但真要走向产品化还有几个关键跃迁点传感器扩展资料包里提到“光照、气压”其实逻辑一致。BH1750光照传感器用I2C只需在bsp_i2c.c里初始化I2C1调bh1750_init()和bh1750_read_lux()BMP280气压传感器也是I2C但要注意它和DHT22共用I2C1时地址冲突DHT22不用I2C这是常见误解。BMP280地址是0x76或0x77用GPIOB-ODR | GPIO_Pin_6切换地址引脚即可。低功耗改造当前是常供电若用电池必须改。STM32F103支持Stop模式电流≈20μA但EC800休眠电流仍达1mA。方案是MCU采集完数据发ATQSCLK1让EC800进入睡眠然后MCU进Stop模式用RTC闹钟唤醒每5分钟MCU醒来先发ATQSCLK0唤醒EC800再建链发送。实测用2000mAh锂电池续航从3天提升到28天。协议升级透传模式适合调试但正式产品要用CoAP或LwM2M。EC800支持ATQHTTPGET可把数据POST到HTTP服务器。我试过用ATQHTTPURL20,60设URLATQHTTPPOST32,60,10000发JSON但成功率不如TCP透传。更稳的方案是加一颗ESP8266做协议转换——STM32只管采集数据通过UART发给ESP8266由它走MQTT。固件OTAKEIL生成的.hex文件可通过EC800的ATQFOTA指令远程升级。但必须预留Bootloader分区在KEIL的Options for Target → Utilities → Settings → Flash里把起始地址设为0x08000000主程序Bootloader放在0x0800F00064KB用ATQFOTADL下载新固件ATQFOTA触发升级。这个功能我放在“进阶资料包”里需要单独申请。最后分享个小技巧所有调试信息不要用printf打到USART1接电脑而是用USART2接EC800发到云端日志服务。我在debug_log.c里写了debug_send(GPS_FIX_OK)它会把字符串加上时间戳通过EC800发到http://log.yourserver.com。这样现场调试时不用带电脑手机看网页就能查终端状态——这才是物联网该有的样子。本文还有配套的精品资源点击获取简介基于STM32F103单片机搭配EC800-4G通信模块和DHT22温湿度传感器完整实现GPS位置信息经纬度、海拔、UTC时间与环境温湿度数据的本地采集、协议组包及4G网络上传。数据通过串口透传或自定义格式发送至Windows端串口调试工具或自研上位机支持实时显示与存储。工程使用KEIL MDK开发基于标准外设库兼容STM32F103高密度HD和中密度MD芯片仅需在KEIL中修改目标型号与Flash容量即可适配不同主控。所有硬件连接定义集中在main.c与usart驱动文件中含详细中文注释覆盖USART初始化、EC800联网AT指令交互、NMEA语句解析、DHT22时序读取、数据打包与发送全流程。提供J-Link和ST-Link两种下载支持附带一键清理编译残留脚本及网盘资料入口。适用于物联网课程实验、毕业设计原型开发、嵌入式远程监测场景后续扩展其他传感器如光照、气压可参考同系列配套驱动代码。本文还有配套的精品资源点击获取