在之前的教程中,无线通信技术我们学习了蓝牙和 WiFi,今天我们要来学习 4G。
4G 模块在距离上有个突破,它不像蓝牙短距离,也不像 WiFi 只能在局域网,4G 模块可使用户无论在哪,只要有 4G 网络信号覆盖,就可以通讯。
4G 模块是一种用于无线通信的设备,它支持第四代移动通信网络(4G 网络)技术。简单来说,4G模块就像是手机里的一个小芯片,它可以连接到移动通信网络,使设备能够无线传输数据和进行通信。通过 4G 模块,这些设备可以与移动通信网络进行无线连接,并实现高速数据传输、语音通话、视频流媒体、在线游戏等功能。
4G 模块在物联网领域扮演着重要的角色。它们可以嵌入到各种物联网设备中,如智能家居设备、智能健康监测器、智能交通系统等,实现设备之间的互联互通,为物联网应用提供可靠的无线连接。
1. 源码下载及前置阅读
本文首发 良许嵌入式网 :https://www.lxlinux.net/e/ ,欢迎关注!
本文所涉及的源码及安装包如下(由于平台限制,请点击以下链接阅读原文下载):
https://www.lxlinux.net/e/stm32/4g-tutorial.html
如果你是嵌入式开发小白,那么建议你先读读下面几篇文章。
- 从零开始轻松掌握STM32开发的必备指南:零基础快速上手STM32开发(手把手保姆级教程)
- 如果你想搭一个属于自己的工程模板:手把手带你创建HAL版本MDK工程模板
- 计算机概念理清,生动形象,通俗易懂:图解固件、驱动、软件的区别
前期教程,没看过的小伙伴可以先看下。
- 蓝牙模块详解,轻松掌握一种无线通信技术:手把手教你玩转蓝牙模块(原理+驱动)
- 蓝牙模块知识应用:小项目:蓝牙模块点亮RGB三色灯
- ESP8266详解,助你成为物联网应用的专家:手把手教你玩转ESP8266(原理+驱动)
作者简介 |
---|
大家好,我是良许,博客里所有的文章皆为我的原创。 下面是我的一些个人介绍,欢迎交个朋友: · 211工科硕士,国家奖学金获得者; · 深耕嵌入式11年,前世界500强外企高级嵌入式工程师; · 书籍《速学Linux作者》,机械工业出版社专家委员会成员; · 全网60W粉丝,博客分享大量原创成体系文章,全网阅读量累计超4000万; · 靠自媒体连续年入百万,靠自己买房买车。 |
我本科及硕士都是学机械,通过自学成功进入世界500强外企。我已经将自己的学习经验写成了一本电子书,超千人通过此书学习并转行成功。现在将这本电子书免费分享给大家,希望对你们有帮助:
电子书链接:https://www.lxlinux.net/1024.html
2. 4G模块介绍
4G 模块市面上有很多厂家生产的不同型号,一般购买的时候厂家都会给你用户手册,大家可以看着使用。
本次我使用的是亿佰特公司的 E840-TTL(EC03-DNC),如果你是小白,跟着本文学一遍,其他 4G模块也就一通百通了。
官网链接,大家有需要可以去下载用户手册和工具软件:EC03-DNC 4G模块
2.1 EC03-DNC介绍
EC03-DNC 是亿佰特推出的 LTE CAT1 数传模块产品,该产品软件功能完善,覆盖绝大多数常规应用场景。支持移动、联通、电信 4G卡。
EC03-DNC 是为实现串口设备与网络服务器,通过网络相互传输数据而开发的产品,该产品是一款带分集接收功能的 LTE-FDD/LTE-TDD 无线通信数传模块,支持 LTE-FDD、LTE-TDD 网络数据连接,用户只需通过简单的设置,即可实现串口到网络服务器的双向数据透明传输。
EC03-DNC 工作模式分为透传模式和配置模式。
- 透传模式:
上电后模块默认工作在透传模式,并自动开始网络连接,当与服务器建立连接后,串口收到的任意数据将被透传到服务端。同时也可以接收来自服务端的数据,收到服务端数据后模块将直接通过串口输出。
- 配置(AT)模式:
该模式下串口数据均视为 AT 指令。透传模式下串口收到「+++」帧数据后,3秒内 RX 引脚收到任意 AT 指令,则模式切换到 AT 模式。AT 模式下,发送「AT+EXAT<CR><LF>」切换到透传模式。
2.2 功能特点
- 采用最新 4G CAT1 方案;
- 支持数据透明传输;
- 支持 TCP、UDP 网络协议;
- 支持心跳包、注册包功能最大支持64个字节数;
- 支持 MQTT 协议,支持接入 OneNet 平台、百度云平台、阿里云平台的 MQTT 服务;
- 支持2路 Socket 链路同时收发;
- 支持 Modbus RTU 与 Modbus TCP 自动相互转换;
- 支持网络 AT 指令,可以通过网络,远程配置设备;
- 软件看门狗设计,系统稳定;
- 支持 APN/VPN。
2.3 工作参数及引脚介绍
工作参数:
- 工作电压:DC 5V~18V
- 工作温度:-40℃~+85℃
- 默认波特率:115200
- 天线:1代 IPEX 接口
- 耗流(受网络环境影响,仅供参考):驻网(连接基站):150mA@12v;入网静态:60mA@12v;数据传输:110mA@12v
- SIM 卡座:使用MICRO自弹式SIM卡座
引脚介绍:
EC03-DNC | 说明 |
---|---|
RST | 模块复位,拉低有效 |
IO_RT | 低电平持续 3~10S,模块参数将恢复出厂设置,并立即重启 |
LIKA | SocketA 链路连接状态指示引脚, 高:SocketA 与网络服务器连接成功; 低:SocketA 未成功连接到网络服务器; |
LIKB | SocketB 链路连接状态指示引脚, 高:SocketB 与网络服务器连接成功; 低:SocketB 未成功连接到网络服务器; |
DATA | 数据收发指示引脚,当网络接收到数据或者串口接收到数据(50ms 高/10ms低) |
STAT | 设备状态指示引脚, 低:设备上电到正在搜寻 SIM 卡; 1800ms 低,200ms高:设备检查到正确的 SIM 卡,正在附着网络; 高:设备附着网络成功; |
RXD | 数据接收引脚,默认 3.3V,可兼容 5V 通信电平 |
TXD | 数据发送引脚,默认 3.3V,可兼容 5V 通信电平 |
VEF | 驱动电平供电引脚,如需要实现串口通信和 LED 指示为 5V 驱动电平时需要在此引脚输入 5V 电平 |
MOD/SLE/PA11/PA10/EN | NC,暂未开放,默认悬空 |
4V2 | 锂电池电源供电引脚,供电范围:3.8V~4.3V。该引脚禁止反接、禁止与 VCC 一起供电 |
GND | 接地 |
VCC | DC 电源供电引脚,供电范围:5V~18V。该引脚禁止反接、禁止与 4V2 一起供电 |
VD | 外接 SIM 卡电源引脚,若使用板载 SIM 卡座则该引脚 NC 即可 |
RS | 外接 SIM 卡复位引脚,若使用板载 SIM 卡座则该引脚 NC 即可 |
DA | 外接 SIM 卡数据引脚,若使用板载 SIM 卡座则该引脚 NC 即可 |
CL | 外接 SIM 卡时钟引脚,若使用板载 SIM 卡座则该引脚 NC 即可 |
PWR | 电源指示灯 |
天线 | 天线接口 |
WORK | 工作状态指示灯,正常工作时亮起 |
DATA | 数据收发指示灯 ,有数据收发时亮起 |
LINKB | 网络连接指示灯B ,连接时亮起 |
LINKA | 网络连接指示灯A ,连接时亮起 |
3. AT指令
3.1 AT指令集
AT 指令集如下,详细的介绍大家可以看官网的 AT 指令手册。
AT指令 | 说明 |
---|---|
REBT | 重启模块 |
CPIN | 查询版本号 |
EXAT | 退出 AT 指令模式 |
RESTORE | 恢复出厂设置 |
UART | 设置/查询串口参数 |
IMEI | 查询模块 IMEI |
LINKSTA | 查询 SOCK 连接状态 |
LINKSTA1 | 查询 SOCK1 连接状态 |
SOCK | 设置/查询 SOCK 参数 |
SOCK1 | 设置/查询 SOCK1 参数 |
REGMOD | 设置/查询注册包模式 |
REGINFO | 设置/查询自定义注册包信息(ASCII) |
REGINFONEW | 设置/查询自定义注册包信息(16 进制) |
HEARTMOD | 设置/查询心跳包模式 |
HEARTINFO | 设置/查询自定义心跳包信息(ASCII) |
HEARTINFONEW | 设置/查询自定义心跳包信息(16 进制) |
HEARTM | 设置/查询心跳包时间 |
SHORTM | 设置/查询短连接时间 |
CREG | 查询是否注册到网络 |
CSQ | 查询信号强度 |
CPIN | 查询 SIM 卡状态 |
POTOCOL | 查询/设置是否开启协议传输 |
MODBUS | 设置/查询 ModbusTCP/RTU 转换功能 |
MTCPID | 设置/查询 ModbusTCP 事件标识符 |
NETHEAD | 设置/查询网络 AT 指令头 |
MQTTMODE | 设置/查询 MQTT 模式 |
MQTT_ADDRESS | 设置/查询物联网平台地址、端口 |
MQTT_CONNECT | 设置/查询接入物联网平台的参数 |
MQTT_SUBSCRIBE_TOPIC | 设置/查询订阅消息的 topic、消息等级 |
MQTT_PUBLISH_TOPIC | 设置/查询发布消息的 topic、消息等级 |
MQTT_ALIAUTH | 设置/查询阿里云三要素 |
APN | 查询/设置 APN 信息 |
APN_ENABLE | 查询/设置 APN 使能 |
WORK_MODE | 查询/设置工作模式 |
正常发送指令后会收到带有「OK」的返回值,如果你没收到,那就是哪里有错误,可以参照下面这个指令错误码:
错误码 | 说明 |
---|---|
-1 | 无效的命令格式 |
-2 | 无效的命令 |
-3 | 无效的操作符 |
-4 | 无效的参数 |
-5 | 操作不允许 |
3.2 串口调试示例
3.2.1 硬件连接
我们首先插好天线和 SIM 卡,SIM 卡最好带卡套插,不然很容易插不准,而且不易取出。
接线如下:
EC03-DNC | USB转TTL |
---|---|
VCC | 5V |
GND | GND |
RXD | TXD |
TXD | RXD |
连好上电后,等五秒左右初始化,「WORK」指示灯亮,表示正常工作。如果「WORK」不亮或闪烁可以换一张 SIM 卡试试。
3.2.2 串口调试
上电后模块默认工作在透传模式,我们需要在串口发送「+++」(不带回车),3秒内发送任意 AT 指
令,进入 AT 模式。
以下是串口调试示例,我查询了心跳包的一些数据,并将心跳包内容配置成「LX_4G」,配置好后需要发送「AT+REBT」,重启生效。大家做好配置后都需要重启生效。
我们可以发现每次发送 AT 指令,「DATA」灯会闪烁。如果不闪是不正常的哦。
4. 内网穿透
4G 模块需要公网通信,我们需要进行一下内网穿透(内网 IP 穿透),也就是为局域网的设备提供一个外网可访问的地址和端口。
这里我们使用花生壳进行内网穿透,虽然花生壳有些功能收费,但是本教程在免费范围内,放心,不收钱。
如果你家的路由器很牛,自带内外穿透的功能,就不用花生壳了,直接用路由器内网穿透。
电脑下载花生壳,花生壳官网:贝锐花生壳内网穿透
下载好后按照指引在手机上注册登录。
登录成功后如下操作:
点击确定后效果如下:
再开一个网络调试助手,协议类型选择「TCP Client」,远程主机地址填我们花生壳的映射地址。
连接后,发送消息,服务器可以收到。
虽然我们现在是在一台电脑上做测试,但是「TCP Client」访问的是公网 IP 地址。
顺带一提,此时服务器既可以通过公网地址连接通讯,也可以通过局域网地址连接通讯。
5. 编程实战
5.1 通信示意图
实现目标是 4G 模块控制 LED 灯。我们有一个三色 LED 灯,4G 模块连到服务器,服务器下发指令:「green」 则绿灯亮,再次发送「green」则绿灯灭,黄灯和红灯的关键词是「yellow」、「red」 ,效果相同。
5.2 4G模块配置
我们需要通过 AT 指令配置 4G 模块联连接服务器。
接线如下,和刚刚串口调制一样:
EC03-DNC | USB转TTL |
---|---|
VCC | 5V |
GND | GND |
RXD | TXD |
TXD | RXD |
- 将天线、SIM 卡、USB转TTL 等硬件连接好。
- 观察「WORK」灯是否亮起,亮起表示正常工作。
- 打开串口调试助手进入配置(AT)模式。默认波特率115200,发送「+++」(不带回车),3秒内发送任意 AT 指令,进入 AT 模式。
- 可以发送「AT+CPIN」,回复1表示有检测到 SIM 卡;「AT+CSQ」查看信号强度;「AT+ICCID」查询 SIM 卡信息等等检测 SIM 卡是否正常工作。
- 发送「AT+SOCK=TCPC,<IP地址>,<端口> 」连接 socket 服务器。大家看着自己的花生壳发送,我这里发送的是「AT+SOCK=TCPC,8g66h75462.vicp.fun,19142 」,也可以发送「AT+SOCK=TCPC,115.236.153.174,19142 」。
- 发送「AT+LINKSTA 」查看连接状态,串口返回「+OK=Connect」表示连接成功
- 发送「AT+REBT」重启生效,服务器就可以收到我们前面设置的「LX_4G」心跳包。
整体效果如下:
注意:AT 指令要以带回车,全英文符号,别带有多余空格。
5.3 硬件接线
本教程使用的硬件如下:
- 单片机:STM32F103C8T6
- 4G模块:EC03-DNC
- 小灯:三色 LED 灯模块
- 串口:USB 转 TTL
- 烧录器:ST-LINK V2
EC03-DNC | LED | STM32 | USB 转 TTL |
---|---|---|---|
VCC | 3.3 | ||
RXD | A2 | ||
TXD | A3 | ||
GND | G | ||
R | A5 | ||
Y | A6 | ||
G | A7 | ||
GND | G | ||
A10 | TX | ||
A9 | RX | ||
G | GND |
烧录的时候接线如下表,如果不会烧录的话可以看我之前的文章【STM32下载程序的五种方法】。
ST-Link V2 | STM32 |
---|---|
SWCLK | SWCLK |
SWDIO | SWDIO |
GND | GND |
3.3V | 3V3 |
接好如下图:
5.4 LED逻辑代码
LED 灯的代码简简单单,只要进行一下三个灯的初始化就行。
void led_init(void)
{
GPIO_InitTypeDef gpio_init_struct;
LED1_GPIO_CLK_ENABLE(); /* LED1时钟使能 */
LED2_GPIO_CLK_ENABLE(); /* LED2时钟使能 */
LED3_GPIO_CLK_ENABLE(); /* LED3时钟使能 */
gpio_init_struct.Pin = LED1_GPIO_PIN; /* LED1引脚 */
gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; /* 推挽输出 */
gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */
gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */
HAL_GPIO_Init(LED1_GPIO_PORT, &gpio_init_struct); /* 初始化LED1引脚 */
gpio_init_struct.Pin = LED2_GPIO_PIN; /* LED2引脚 */
HAL_GPIO_Init(LED2_GPIO_PORT, &gpio_init_struct); /* 初始化LED2引脚 */
gpio_init_struct.Pin = LED3_GPIO_PIN; /* LED3引脚 */
HAL_GPIO_Init(LED3_GPIO_PORT, &gpio_init_struct); /* 初始化LED3引脚 */
LED1(0); /* 关闭 LED1 */
LED2(0); /* 关闭 LED2 */
LED3(0); /* 关闭 LED3 */
}
LED 的 .h文件:
#ifndef _LED_H
#define _LED_H
#include "sys.h"
/******************************************************************************************/
/* 引脚 定义 */
#define LED1_GPIO_PORT GPIOA
#define LED1_GPIO_PIN GPIO_PIN_7
#define LED1_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0) /* PA口时钟使能 */
#define LED2_GPIO_PORT GPIOA
#define LED2_GPIO_PIN GPIO_PIN_6
#define LED2_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0) /* PA口时钟使能 */
#define LED3_GPIO_PORT GPIOA
#define LED3_GPIO_PIN GPIO_PIN_5
#define LED3_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0) /* PB口时钟使能 */
/******************************************************************************************/
/* LED端口定义 */
#define LED1(x) do{ x ? \
HAL_GPIO_WritePin(LED1_GPIO_PORT, LED1_GPIO_PIN, GPIO_PIN_SET) : \
HAL_GPIO_WritePin(LED1_GPIO_PORT, LED1_GPIO_PIN, GPIO_PIN_RESET); \
}while(0)
#define LED2(x) do{ x ? \
HAL_GPIO_WritePin(LED2_GPIO_PORT, LED2_GPIO_PIN, GPIO_PIN_SET) : \
HAL_GPIO_WritePin(LED2_GPIO_PORT, LED2_GPIO_PIN, GPIO_PIN_RESET); \
}while(0)
#define LED3(x) do{ x ? \
HAL_GPIO_WritePin(LED3_GPIO_PORT, LED3_GPIO_PIN, GPIO_PIN_SET) : \
HAL_GPIO_WritePin(LED3_GPIO_PORT, LED3_GPIO_PIN, GPIO_PIN_RESET); \
}while(0)
/* LED取反定义 */
#define LED1_TOGGLE() do{ HAL_GPIO_TogglePin(LED1_GPIO_PORT, LED1_GPIO_PIN); }while(0) /* 翻转LED1 */
#define LED2_TOGGLE() do{ HAL_GPIO_TogglePin(LED2_GPIO_PORT, LED2_GPIO_PIN); }while(0) /* 翻转LED2 */
#define LED3_TOGGLE() do{ HAL_GPIO_TogglePin(LED3_GPIO_PORT, LED3_GPIO_PIN); }while(0) /* 翻转LED3 */
/******************************************************************************************/
/* 外部接口函数*/
void led_init(void); /* LED初始化 */
#endif
5.5 4G模块初始化
4G 模块初始化代码如下:
UART_HandleTypeDef _4g_uart_handle;
void _4g_init(uint32_t baudrate)
{
_4g_uart_handle.Instance = _4G_INTERFACE; /* 4G */
_4g_uart_handle.Init.BaudRate = baudrate; /* 波特率 */
_4g_uart_handle.Init.WordLength = UART_WORDLENGTH_8B; /* 数据位 */
_4g_uart_handle.Init.StopBits = UART_STOPBITS_1; /* 停止位 */
_4g_uart_handle.Init.Parity = UART_PARITY_NONE; /* 校验位 */
_4g_uart_handle.Init.Mode = UART_MODE_TX_RX; /* 收发模式 */
_4g_uart_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE; /* 无硬件流控 */
_4g_uart_handle.Init.OverSampling = UART_OVERSAMPLING_16; /* 过采样 */
HAL_UART_Init(&_4g_uart_handle); /* 使能4G */
}
5.6 4G收发
4G 模块通过串口与 MCU 进行通讯,所以第一步需要先做好串口的配置。
关于串口的配置,我写过一篇文章手把手教你玩串口,大家可以移步下文查看:
4G 接收具体代码如下:
uint8_t _4g_uart_rx_buf[_4G_RX_BUF_SIZE];
uint8_t _4g_uart_tx_buf[_4G_TX_BUF_SIZE];
uint16_t _4g_uart_rx_len = 0;
void _4g_rx_clear(void)
{
memset(_4g_uart_rx_buf, 0, sizeof(_4g_uart_rx_buf)); //清空接收缓冲区
_4g_uart_rx_len = 0; //接收计数器清零
}
void _4G_IRQHandler(void)
{
uint8_t receive_data = 0;
if(__HAL_UART_GET_FLAG(&_4g_uart_handle, UART_FLAG_RXNE) != RESET){ //获取接收RXNE标志位是否被置位
if(_4g_uart_rx_len >= sizeof(_4g_uart_rx_buf)) //如果接收的字符数大于接收缓冲区大小,
_4g_uart_rx_len = 0; //则将接收计数器清零
HAL_UART_Receive(&_4g_uart_handle, &receive_data, 1, 1000); //接收一个字符
_4g_uart_rx_buf[_4g_uart_rx_len++] = receive_data; //将接收到的字符保存在接收缓冲区
}
if (__HAL_UART_GET_FLAG(&_4g_uart_handle, UART_FLAG_IDLE) != RESET) //获取接收空闲中断标志位是否被置位
{
printf("recv: %s\r\n", _4g_uart_rx_buf); //将接收到的数据打印出来
control_led(); //检测是否有LED关键词
_4g_rx_clear();
__HAL_UART_CLEAR_IDLEFLAG(&_4g_uart_handle); //清除UART总线空闲中断
}
}
通过这几个函数,我们就可以读取 4G 返回的数据,并保存在数组 bt_uart_rx_buf
里。
如果需要通过串口向 4G 模块发送数据,可以使用下面函数:
void _4g_send(char *fmt, ...)
{
va_list ap;
uint16_t len;
va_start(ap, fmt);
vsprintf((char *)_4g_uart_tx_buf, fmt, ap);
va_end(ap);
len = strlen((const char *)_4g_uart_tx_buf);
HAL_UART_Transmit(&_4g_uart_handle, _4g_uart_tx_buf, len, HAL_MAX_DELAY);
}
其实是否向 4G 模块发送数据并不影响我们的实现效果,留着的目的一方面为了让大家复习一下,另一方面可以看出 4G 模块是否在正常工作。
至此,4G 模块的初始化、发送、接收部分就做好了。
5.7 LED控制
检测 4G 模块是否接收到 LED 指令,如果有就反转 LED 灯状态。
void control_led()
{
if(strstr((const char *)_4g_uart_rx_buf, "green") != NULL) //如果接收到关键词"green"
LED1_TOGGLE(); // 翻转LED1
if(strstr((const char *)_4g_uart_rx_buf, "yellow") != NULL) //如果接收到关键词"yellow"
LED2_TOGGLE(); // 翻转LED2
if(strstr((const char *)_4g_uart_rx_buf, "red") != NULL) //如果接收到关键词"red"
LED3_TOGGLE(); // 翻转LED3
}
5.8 主函数
在 main 函数里,我们可以先调用 _4g_init()
函数进行初始化,然后调用 _4g_send()
函数发送数据。
int main(void)
{
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟,72M */
delay_init(72); /* 初始化延时函数 */
usart_init(115200); /* 串口1波特率设为115200 */
_4g_init(115200); /* 串口2波特率设为115200 */
led_init();
printf("4G控制灯……\r\n");
while(1)
{
_4g_send("4G send\r\n");
delay_ms(1000);
}
}
6. 运行过程
将硬件连好,把串口插到电脑 USB 口。
接着我们打开电脑串口软件。设置串口助手波特率 115200(你们不一定要用我这款,随便的串口助手都可以),选择串口号,最后打开串口开始准备接收数据。
这个串口工具接收的是 MCU 串口 1 的数据,也就是 log 。4G 模块接收到数据后,我们使用串口 1 打印到下面的串口助手里。
烧录代码,打开串口调试助手和网络调试助手,上电。
比如我们用服务器(网络调试助手)给 4G 模块发送数据「red」、「yellow」、「green」。
可以看到串口助手成功接收到了「red」 、「yellow」、「green」。
我们的三个小灯也打开了。
再次发送关键词即可关对应的灯。当然,一次发送 「green yellow red」,就可以控制三个小灯一起反转。
细心的同学可能发现了,不需要串口调试助手、USB 转 TTL,也可以实现我们的目标,我的目的是让大家的更清楚 4G 模块的收发过程,大家可以自行删减。
7. 总结
4G 模块在无线通信领域扮演着重要的角色,它为我们提供了便捷、高效的无线网络连接,改变了我们与世界的交流方式,并推动了移动通信和物联网技术的发展,从 3G 到 4G,速度的提升带来了短视频的爆发、全民直播的兴起、手机支付的流行。同时 5G 时代的来临更加让人期待,5G 的上传下载是 4G 的十倍,相信 5G 带来我们的绝不只是速度的提升。
希望本文能帮助您了解和使用 4G 模块。感谢各位看官,peace and love!
另外,想进大厂的同学,一定要好好学算法,这是面试必备的。这里准备了一份 BAT 大佬总结的 LeetCode 刷题宝典,很多人靠它们进了大厂。
刷题 | LeetCode算法刷题神器,看完 BAT 随你挑!
有收获?希望老铁们来个三连击,给更多的人看到这篇文章
推荐阅读:
欢迎关注我的博客:良许嵌入式教程网,满满都是干货!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。