☰
STM32+Air780E中文短信发送实战:PDU编码与OLED显示
2026/9/29 2:04:28 网站建设 项目流程

把STM32和4G模组Air780E拼在一起,做一个按键发送中文短信、OLED实时显示状态的小装置,听起来难度不大,真正写代码的时候才发现,最磨人的不是STM32本身,而是中文短信那套PDU编码,以及按键、串口、OLED三者之间的时序配合。我最近刚把一个这样的项目完整调通,从硬件接线、PDU编码、代码框架到调试踩坑,记录一篇完整的经验帖,给正在做物联网短信告警、毕业设计,或者只是想玩一下Air780E的开发者做个参考。

这个项目的定位很清楚:STM32做主控,负责按键检测、OLED显示和AT指令调度;Air780E只负责4G入网和短信收发。整套跑通以后,按一下按键,几秒内对方手机就能收到一条中文短信,OLED屏幕上会依次显示待机、发送中、发送成功或者失败原因。对嵌入式入门的同学来说,它几乎覆盖了GPIO中断、定时器消抖、串口通信、I2C驱动、字符编码这几大块基础技能,既有业务闭环,又有典型的技术难点,拿来练手非常合适。

1. 项目拆解与整体方案

1.1 五个硬件角色各干什么

先把标题里的五个关键词拆开看。STM32是整个系统的大脑,所有业务逻辑都跑在它上面:读取按键状态、刷新OLED、生成短信内容、调度串口发送。Air780E是合宙的一款4G Cat.1模组,负责网络接入和短信通道,它本身不参与业务决策,只执行AT指令。按键是输入设备,它触发“发送短信”这个动作。中文短信是这个项目真正有技术含量的部分,英文短信可以直接用7bit编码怼上去,中文必须转成UCS2编码并按PDU格式组包。OLED是反馈设备,让用户看到当前处于什么状态,没有它,按键按下之后你完全不知道系统是在工作还是卡死了。

这五个部分其实对应了嵌入式开发的几个基本功:GPIO输入输出、外部中断、定时器、UART串口通信、I2C驱动、字符编码转换。所以这个项目虽然看起来只是“发条短信”,实际上你能学到的东西相当多。尤其是Air780E这一类4G模组,它的AT指令交互逻辑和老的GSM模块基本一致,以后换成其他模组也能很快上手。

1.2 为什么选AT指令方案而不是LuatOS单芯片

Air780E本身支持两种玩法。一种是刷LuatOS固件,直接用Lua脚本在模组内部把按键、OLED、短信全部写完,这时候STM32基本可以退休,整个项目一颗Air780E就够。另一种是刷AT固件,Air780E老老实实当一个网络外设,所有控制逻辑由外部MCU通过串口发AT指令完成。

这个项目标题既然是“STM32+Air780E”,那天然走的是AT方案,STM32必须存在。从学习角度讲,AT方案更有价值,因为它把“主控MCU”和“通信模组”的边界划得很清楚,你对串口协议、命令超时、状态机这些概念会有非常直观的体会。以后你想把这个4G模块换成NB-IoT模组、WiFi模组,只要AT指令相似,主控代码改动很小。LuatOS方案在量产降成本时确实香,但如果你想练STM32,就别省这一步。

对比项STM32 + Air780E(AT)Air780E + Luatos单芯片
开发语言C / HAL库Lua脚本
成本多一颗MCU,略高单芯片,最低
学习价值GPIO/中断/串口/I2C全覆盖偏向脚本业务逻辑
模组可替换性高,AT指令通用低,绑死LuatOS生态
适合场景学习、毕设、已有STM32平台产品量产、快速原型

如果你选了AT方案,还有一件事要确认:Air780E出厂可能是LuatOS固件也可能已经是AT固件,拿到手先发AT测一下,如果回复OK就是AT固件,不回就先去合宙的文档中心把AT固件刷进去。我用的是官方下载的AT固件版本,后续所有指令都基于这个环境。

1.3 系统数据流与状态划分

画一条数据流出来理解整个项目。开机后,STM32初始化OLED、串口、GPIO,然后循环读取模组信号强度。用户按下按键,按键引脚产生下降沿,触发外部中断,中断里只做一件事:设置一个KEY_FLAG标志位。主循环检测到标志后,把系统状态切到“发送中”,OLED显示SENDING。接着STM32通过UART2向Air780E发一串AT指令,其中最重要的一条是AT+CMGS=<长度>,模组收到后返回>提示符,STM32立刻把PDU十六进制字符串和结束字节0x1A发过去。模组入网、短信中心处理都需要时间,这个等待过程不能干等,所以要靠串口接收中断和超时机制来判断返回结果。收到+CMGS: <编号>说明成功,收到ERROR说明失败,OLED对应更新SMS OK或者错误码,系统回到待机状态。

这里最忌讳的做法是:在按键中断里直接调用HAL_Delay消抖、然后在中断里把整条短信发完。嵌入式中断里只做“置标志位”这件事,具体逻辑全部放主循环,这是基本素养。短信发送是一个耗时的异步过程,从AT指令到模组返回>,再到网络侧下发,整个过程几百毫秒甚至更久,如果全塞在中断里,系统直接卡死。

2. 硬件准备与连接

2.1 物料清单与核心板选择

我的配置是STM32F103C8T6最小系统板、Air780E核心板、0.96寸SSD1306 OLED(I2C四针)、一个轻触按键、一张能收发短信的4G SIM卡、5V/2A的电源。STM32板子用USB转串口下载程序,Air780E核心板直接用USB线供电,OLED从STM32的3.3V取电,按键占一个PA0引脚,一共没几根线。

这里必须提醒一句:Air780E模组的IO电平是1.8V,跟STM32的3.3V电平不是直接兼容的。如果你是老手,自己画底板、加电平转换芯片没有问题;如果你是新手,强烈建议直接买Air780E核心板,合宙官方核心板已经把USB转串口、SIM卡座、天线座、电平转换全做好,你只需要把核心板的UART引脚引出来给STM32就行。裸模组看着便宜,但焊接SIM卡座、天线、电平转换这一套下来,成本和时间反而更高。

2.2 STM32与Air780E、OLED的接线表

接线遵循“串口交叉”原则,STM32的TX要接模组的RX,STM32的RX接模组的TX。OLED走I2C,SCL和SDA分别接STM32的PB6和PB7,我用的是软件模拟I2C,这样以后换引脚不用改硬件配置。

模块STM32引脚对端引脚说明
Air780E核心板PA2 (USART2_TX)UART_RXDSTM32发送AT指令
Air780E核心板PA3 (USART2_RX)UART_TXDSTM32接收模组应答
SSD1306 OLEDPB6SCL软件I2C时钟
SSD1306 OLEDPB7SDA软件I2C数据
按键PA0按键另一脚接GND内部上拉,按下为低电平
所有模块GNDGND必须共地

OLED模块如果带四针引出,一般是VCC、GND、SCL、SDA四根线,注意别把SCL和SDA接反。SSD1306的I2C地址默认是0x3C,也有少部分是0x3A,如果你的OLED怎么初始化都没反应,先写一个I2C扫描程序确认地址。上拉电阻方面,很多OLED模块板载已经做了,如果你的模块是纯屏没有板载上拉,SCL和SDA各接一个4.7k电阻到3.3V。

2.3 按键电路与Air780E开机时序

按键电路本身很简单,一个轻触按键一端接PA0,一端接GND,STM32内部把PA0配置成上拉输入,平时读到高电平,按下变低电平。内部上拉电阻大约几十k欧姆,在实验室环境够用,如果现场电磁干扰比较厉害,建议外部再加一个4.7k上拉电阻,按下时波形更干净。

Air780E上电流程值得单独说一下。模组不是一上电就能收发AT指令,它有一个开机时序:PWRKEY引脚需要被拉低一段时间,通常几百毫秒到2秒,模组才会开机,开机后串口才会输出就绪信息。我用Air780E核心板的时候直接按板上的PWRKEY按键开机。如果你想实现STM32全自动控制,可以用一个GPIO通过三极管控制PWRKEY拉低。开机后别急着发短信,先发AT等它回OK,再发AT+CPIN?确认SIM卡已经识别,AT+CSQ看信号强度,这才是完整的开机检测流程。

3. 中文短信PDU编码:从手算到代码

3.1 中文短信为什么必须用PDU编码

短信内容的编码方式有好几种,最基础的是GSM 7bit,能表示英文字母和数字,一条短信160个字符。中文不在这个字符集里,所以必须用UCS2编码,也就是UTF-16BE,每个汉字占2个字节,一条短信最多70个汉字。光把内容编码成UCS2还不够,短信协议里需要把目标手机号、编码格式、内容长度这些都打包成一种约定的格式,这个格式就是PDU。

很多新手第一次见PDU串会觉得很玄乎,它其实就是一串十六进制字节,有一堆字段:SMSC短信中心、TP-MTI消息类型、目标号码、PID协议标识、DCS编码方案、UDL用户数据长度、UD内容。你可以把它理解成寄快递时的快递单:收件人地址、包裹类型、重量、内容物全部写在一个面单上。短信中心拿到这个面单,才知道把包裹送到哪、怎么解析里面的内容。PDU编码是整个项目最容易出错的地方,但动手算一遍之后就彻底通了。

3.2 手机号转换:加86、两两反转、补F

PDU里的电话号码不是按普通文本存的,它是BCD编码,也就是每个字节存两位数字,而且两位数字的顺序要反转。目标手机号13512345678要转成国际格式,先在前面加86变成8613512345678,然后从开头两个一组分组:86 | 13 | 51 | 23 | 45 | 67 | 8。分组后每组内部两个数字互换位置:86转成68,13转成31,51转成15,23转成32,45转成54,67转成76。最后剩下一个单独的8,要在后面补一个F凑成两位,变成8F。

所以13512345678经过转换后是:68 31 15 32 54 76 8F。这里有几个高频错误点,我在调试时全踩过。第一个是忘了加86,号码长度不对,短信中心解析不了。第二个是反转方向搞反,转成了86 13 51 23 45 67 8F这种原样输出。第三个是补F的位置,有的新手把F补在最前面或者中间,最后一位必须是补F。只要号码转换错了,发送结果大概率是ERROR或者对方收到乱码。

再看另一个例子加固一下记忆。13901234567,加86变成8613901234567,分组86 | 13 | 90 | 12 | 34 | 56 | 7,反转后是68 31 09 21 43 65 7F。注意90反转后是09,不要丢掉前面的0,PDU串里这个位置的0必须保留。

3.3 汉字转UCS2编码

接下来把短信内容“测试”转成UCS2。在PC上打开Python,执行一行命令就出结果:

"测试".encode("utf-16-be").hex()

输出是6d4b8bd5,所以“测”对应6D 4B,“试”对应8B D5。如果你不想开Python,网上也有很多Unicode查码工具,输入汉字直接给十六进制。对于固定短信内容,我建议直接在PC上把所有要发的短信用这种方式预编码好,在STM32端用const数组存着,这样MCU完全不用做编码运算,代码简单、运行也快。

如果短信内容要动态变化,比如后面想加上温湿度值,就需要在单片机上做一个UTF-16BE编码函数。你可以先把数字转成ASCII码,再把每个ASCII字符的高字节填0,拼进内容里。UCS2编码下,ASCII字符也是2字节,比如字母A就是0x00 0x41。也就是说发一条“温度25.5度”这类短息,内容里中文字符和数字字符都要统一按UCS2处理,只编码中文不编码数字,最后一样是乱码。

3.4 构建完整PDU串并算对长度

现在我们给“发送短信到13512345678,内容是测试”构建完整PDU。按字段顺序排下来:

序号字节含义
000SMSC长度字段为0,表示使用网络默认短信中心
101TP-MTI,SMS-SUBMIT提交类型
200MR消息参考号
30D目标号码的BCD长度,13位
491号码类型,国际格式
5-1168 31 15 32 54 76 8F转换后的目标号码
1200PID协议标识,普通短信
1308DCS编码方案,UCS2
1404UDL用户数据长度,4字节
15-186D 4B 8B D5“测试”的UCS2编码

把这些字节拼成一个十六进制字符串就是:

0001000D916831153254768F0008046D4B8BD5

这一串是38个字符,也就是19个字节。AT指令里要填长度,AT+CMGS=19,这个长度是字节数,不是字符数。很多人在这里翻车,明明发送的字符串是38个字符,结果在AT+CMGS里填了38,模组直接回ERROR。如果你的PDU内容变了,就用strlen(hex字符串) / 2算一下字节数。有一点需要注意,不同AT固件对长度是否包含最前面的SMSC长度字段定义略有差异,实测Air780E按整个字符串一半填没问题,如果模组报错,把长度减1再试一次通常就能通过。

3.5 完整AT指令序列和时间顺序

短信发送的AT指令顺序是固定的,不可能一条指令发完,必须一步一步来,每一条都要等模组返回OK再发下一条。完整的交互过程如下:

发:AT 收:OK 发:ATE0 收:OK 发:AT+CMGF=0 收:OK 发:AT+CSQ 收:+CSQ: 18,0 发:AT+CGREG? 收:+CGREG: 0,1 发:AT+CMGS=19 收:> 发:0001000D916831153254768F0008046D4B8BD5 然后立刻发0x1A(十六进制字符,不是字符串"1A") 收:+CMGS: 42

看到>提示符之后,要尽快把PDU内容发出去,但也不能一股脑把下一轮AT指令一起塞进去。0x1A是Ctrl+Z,表示PDU数据结束,这个字节必须用十六进制发送,如果你在串口助手里手动测试,就勾选HEX发送,输入1A再发送。收到+CMGS: 42说明短信中心已经接收,42是短信中心分配给这条短信的编号。如果收到ERROR,就要看具体错误码排查PDU格式、信号、SIM卡状态。

命令之间为什么必须等返回?因为模组和短信中心是异步交互的,你在它处理上一条命令时发下一条,它可能直接丢弃或者返回乱码。这一点在PC上用串口助手手动验证时体会最深,手速一快就出错。

4. STM32代码实现与驱动逻辑

4.1 OLED初始化、取模与汉字显示

OLED我用的是SSD1306控制器,0.96寸128x64,I2C接口。初始化时要发一串配置命令,设置显示开关、电荷泵、对比度、内存地址模式这些参数。网上随便搜都能找到标准的初始化序列,我用的关键命令如下:

// SSD1306 初始化命令子集 0xAE, // 关闭显示 0x20, 0x00, // 水平地址模式 0xC8, // COM扫描方向 0x40, // 显示起始行 0x81, 0xCF, // 设置对比度 0xA1, // 段重映射 0xA6, // 正常显示 0xA8, 0x3F, // 多路复用比 1/64 0xD3, 0x00, // 显示偏移 0xD5, 0x80, // 时钟分频 0xDA, 0x12, // COM引脚配置 0x8D, 0x14, // 开启电荷泵 0xAF, // 开启显示

这些命令不用死记,照抄就能用。真正容易踩坑的是汉字显示。SSD1306本身没有字库,所有字符都是以点阵形式写进去的。英文和数字可以用8x16的ASCII点阵,汉字至少16x16点阵,一屏128x64最多显示4行汉字。我用的是PCtoLCD2002工具,取模方式选择“阴码、逐列式、逆向、高位在前”,生成16x16点阵数组,然后在代码里按页写入OLED显存。

如果你发现OLED显示中文出现雪花一样的乱码,90%是取模参数的“逐列式/逐行式”和你写入函数不匹配。比如取的是逐列式,写入函数却按逐行式填充,字符看起来就是破碎的。我自己遇到过好几次,解决办法就是固定一组取模参数后,代码只按那一种参数写,不要混用网上抄来的零散函数。刚开始调试建议先用英文“SEND OK”这类简单的显示,跑通后再上中文字库,减少变量。

4.2 按键消抖与事件触发

按键接在PA0上,配置成外部中断下降沿触发。但机械按键按下时,触点会有几毫秒到几十毫秒的抖动,表现为引脚电平在0和1之间快速跳变,如果不在中断里做处理,一次按下可能被识别成多次触发,短信就会重复发送。

我的做法是“中断置标志 + 定时器消抖”。外部中断触发后,不立即认为是有效按键,而是启动一个20ms定时器,定时时间到后再读一次PA0电平,如果仍然是低电平,才确认真按键。这样比在中断里用HAL_Delay硬等要文明得多,因为Delay会阻塞整个系统,OLED刷新和串口接收全部停下。

// 定时器每10ms进一次中断 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { static uint8_t cnt = 0; if (key_pressed) { cnt++; if (cnt >= 2) // 20ms电平稳定 { if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET) { key_flag = 1; // 置位发送标志 } key_pressed = 0; cnt = 0; } } }

外部中断里只把key_pressed置位,具体电平判断放到定时器里,定时器里确认后再把key_flag置位,主循环检测到key_flag才进入短信发送流程。这套消抖逻辑看起来绕了一点,但好处是任何环节都不阻塞,系统的实时性有保障。如果不用中断,纯靠主循环轮询加20ms软件延时,大多数场合也能用,只是不够优雅。

4.3 串口接收与AT应答解析

STM32通过USART2和Air780E通信,波特率115200,8N1。发送AT指令直接用HAL_UART_Transmit阻塞发送没问题,因为指令本身很短。难点在于接收模组的异步返回,这必须用中断接收加环形缓冲区的思路。

我建了一个环形缓冲区接收模组的串口数据,在接收中断里把每个字节填进缓冲区,主循环里再去匹配关键字。这样无论模组是返回OK、>还是+CMGS: 42,数据都不会丢。

uint8_t rx_buf[256]; volatile uint16_t rx_cnt = 0; void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance == USART2) { rx_buf[rx_cnt++] = rx_data; if (rx_cnt >= sizeof(rx_buf)) rx_cnt = 0; HAL_UART_Receive_IT(&huart2, &rx_data, 1); } }

判断AT命令是否成功,我写了一个简单的等待函数,在超时时间内不断查找环形缓冲区中是否出现目标字符串:

uint8_t at_wait(const char *expect, uint32_t timeout_ms) { uint32_t start = HAL_GetTick(); while (HAL_GetTick() - start < timeout_ms) { // 在rx_buf中查找expect if (strstr((char*)rx_buf, expect) != NULL) { return 1; } } return 0; // 超时 }

这里有个容易忽略的点:Air780E开机后可能主动上报一些URC消息,比如网络注册状态+CFUN: 1、+CGEV等,这些字符会混在缓冲区里。所以解析AT结果时不要简单地判断“缓冲区收到了东西”,而是要明确匹配OK、>、+CMGS、ERROR这几个关键字。我一开始就是没注意URC,主循环看到缓冲区有数据就以为成功了,结果OLED显示SMS OK,其实对方根本没收到短信。

4.4 短信发送主流程代码

核心发送函数逻辑很直白:先按PDU串的长度发AT+CMGS=<len>,等待模组回>,再发送PDU十六进制字符串,紧接着发0x1A,最后等+CMGS或ERROR。这里我把PDU串直接用const数组定义,因为内容是固定的,不占用RAM。

const char pdu_hex[] = "0001000D916831153254768F0008046D4B8BD5"; const uint16_t pdu_len = sizeof(pdu_hex) / 2 - 1; // 减掉结尾的\0 void send_sms(void) { char cmd[32]; uint8_t ctrl_z = 0x1A; OLED_ShowString(0, 0, "SENDING..."); sprintf(cmd, "AT+CMGF=0\r\n"); uart_send(cmd); at_wait("OK", 2000); sprintf(cmd, "AT+CMGS=%d\r\n", pdu_len); uart_send(cmd); if (!at_wait(">", 3000)) { OLED_ShowString(0, 0, "NO RESP"); return; } uart_send((char*)pdu_hex); // 发送PDU十六进制字符串 uart_send_byte(ctrl_z); // 发送结束字节 if (at_wait("+CMGS", 10000)) { OLED_ShowString(0, 0, "SMS OK"); } else { OLED_ShowString(0, 0, "FAIL"); } }

注意pdu_len的计算。pdu_hex字符串长度是38个字符,加结尾的\0一共39字节,sizeof返回39,除以2取整再减1,得到19,这个正好是PDU字节数。细节明明很简单,实际写代码时非常容易算错,我建议你写完以后加一句printf或者用调试器看一眼这个变量的值,确认是19再往下跑。

5. 调试实录与常见问题排查

5.1 OLED不亮、花屏的排查思路

OLED不亮先量电压,VCC是不是3.3V,GND有没有接好。电压正常就确认I2C地址,写一个扫描程序把0x3C和0x3A都试一遍。初始化之后发一条全屏填充命令,如果全屏能亮,说明驱动基本没大问题。如果全屏亮但显示字符是花的,重点查取模参数,PCtoLCD2002里阴码/阳码、逐列式/逐行式、高位在前/低位在前这三组参数必须和写入函数保持一致。还有一个容易被忽略的点:OLED电源不要和Air780E的VBAT混在一起,Air780E瞬时电流很大,会把OLED供电拉低,花屏和闪烁往往就是这么来的。

5.2 短信发不出去:从信号到PDU逐项排查

短信发不出去,先查环境条件。用AT+CPIN?查SIM卡识别状态,返回READY才说明卡被识别,如果返回ERROR,大概率是SIM卡没放好或者卡槽接触不良。查AT+CSQ看信号强度,返回值范围0到31,第一项越小信号越差,低于10基本很难发出去。查AT+CGREG?,第二个数字为1或5才表示已注册上4G网络。网络条件都正常,才轮到PDU格式问题。+CME ERROR: 500这类错误通常跟PDU参数有关,优先检查AT+CMGS的长度、号码反转、DCS是不是08。

如果PDU格式完全正确但依然失败,还要看短信中心。发AT+CSCA?查询当前短信中心号码,空的话就手动设置一个归属地的短信中心号码。Air780E默认走网络侧短信中心,大多数时候不配也能发,但极端情况下会卡在这一步。

5.3 对方收到乱码的原因

短信能收到但显示乱码,基本可以断定问题出在编码。最典型的原因是DCS没有设置成08。DCS=08告诉短信中心,用户数据按UCS2解析,如果你用了08以外的值,系统可能按7bit或者8bit去解析2字节一组的汉字,结果自然全乱。第二个原因是PDU内容里的汉字本身转码转错了,把“测试”转成了别的值。第三个原因是短信内容里混入了没有转成UCS2的数字或字母,比如内容部分是中文UCS2,部分数字又直接用了ASCII,编码不统一,手机解析出来就乱。建议先用手机给这个号码发一条普通短信,排除接收端手机自身的问题。

5.4 按键误触和重复发送

按键按下一次,短信发了三条,这种情况我在学生项目里见过太多次。用示波器抓PA0引脚,按下瞬间能看到一串毛刺脉冲,这就是抖动。外部中断对每个下降沿都会响应,一次按键可以触发好几次中断。解决办法就是软件消抖加“释放检测”。我看到你按下,等20ms再确认一次电平,确认后只置一次标志位,然后要检测到按键释放、引脚回到高电平,才允许下一次触发。这样即使一直按住按键,也不会重复发送,最多发一条。

现象可能原因解决办法
OLED不亮I2C地址不对、没上拉、电源不足扫描地址,确认上拉,独立供电
OLED花屏取模参数与写入函数不匹配统一阴码/逐列式/逆向/高位在前
短信全部失败SIM卡没识别、信号差、PDU长度错查CPIN/CSQ,核对CMGS长度
短信收到乱码DCS不是08、编码混用、UTF16转错统一UCS2,检查PDU内容字段
按一次发多条按键抖动、无释放检测20ms消抖,等释放再允许下次触发
模组串口无响应波特率不对、没开机、TX/RX接反发AT验证,检查PWRKEY时序

5.5 模组上电不开机或者串口无响应

最后说一个特别容易被新手忽略的问题:Air780E串口没输出,先别怀疑模块坏了,先检查你到底有没有让它开机。Air780E不是一上电就工作的,PWRKEY必须有一段拉低动作。你可以用官方USB串口工具连接核心板,上电后按一下板上的PWRKEY按键,然后马上在串口助手里发AT,看有没有返回OK。如果电脑串口助手正常,换成STM32就没反应,优先检查STM32和Air780E之间存在共地问题,TX和RX是不是交叉接了。

另外,Air780E开机之后不要立刻发AT+CMGS,最好等2秒左右,让它先完成网络附着。快速连续初始化会让模组抛出一堆URC消息,你解析AT结果时会被这些无关字符串干扰,逻辑判断很容易错乱。我在代码里开机后固定延时3秒再走业务流程,实测稳定性有明显提升。

最后分享两个我自己调这个项目时觉得最值钱的经验。第一,强烈建议先把Air780E用USB转串口接到电脑,用串口助手把AT、CMGF、CMGS整条链路在PC上手动跑通,确认PDU串没问题,再写STM32代码。不要一上来就STM32和模组联调,出问题的时候你根本分不清是硬件接线问题、PDU编码问题还是代码逻辑问题。第二,PDU组包这一步不要手拼,写一个小工具函数,输入手机号和短信内容,直接输出十六进制字符串和长度。我后来把生成PDU的Python脚本留在项目目录里,改短信内容时跑一下脚本,复制结果进const数组就行,几分钟完事。剩下的就靠你实际动手去踩坑了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询