4G模块详解

在之前的教程中,无线通信技术我们学习了蓝牙和 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 」切换到透传模式。

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,模块参数将恢复出厂设置,并立即重启
LIKASocketA 链路连接状态指示引脚,
高:SocketA 与网络服务器连接成功;
低:SocketA 未成功连接到网络服务器;
LIKBSocketB 链路连接状态指示引脚,
高: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/ENNC,暂未开放,默认悬空
4V2锂电池电源供电引脚,供电范围:3.8V~4.3V。该引脚禁止反接、禁止与 VCC 一起供电
GND接地
VCCDC 电源供电引脚,供电范围: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-DNCUSB转TTL
VCC5V
GNDGND
RXDTXD
TXDRXD

连好上电后,等五秒左右初始化,「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-DNCUSB转TTL
VCC5V
GNDGND
RXDTXD
TXDRXD
  1. 将天线、SIM 卡、USB转TTL 等硬件连接好。
  2. 观察「WORK」灯是否亮起,亮起表示正常工作。
  3. 打开串口调试助手进入配置(AT)模式。默认波特率115200,发送「+++」(不带回车),3秒内发送任意 AT 指令,进入 AT 模式。
  4. 可以发送「AT+CPIN」,回复1表示有检测到 SIM 卡;「AT+CSQ」查看信号强度;「AT+ICCID」查询 SIM 卡信息等等检测 SIM 卡是否正常工作。
  5. 发送「AT+SOCK=TCPC,<IP地址>,<端口> 」连接 socket 服务器。大家看着自己的花生壳发送,我这里发送的是「AT+SOCK=TCPC,8g66h75462.vicp.fun,19142 」,也可以发送「AT+SOCK=TCPC,115.236.153.174,19142 」。

  1. 发送「AT+LINKSTA 」查看连接状态,串口返回「+OK=Connect」表示连接成功
  2. 发送「AT+REBT」重启生效,服务器就可以收到我们前面设置的「LX_4G」心跳包。

整体效果如下:

注意:AT 指令要以带回车,全英文符号,别带有多余空格。

5.3 硬件接线

本教程使用的硬件如下:

  • 单片机:STM32F103C8T6
  • 4G模块:EC03-DNC
  • 小灯:三色 LED 灯模块
  • 串口:USB 转 TTL
  • 烧录器:ST-LINK V2
EC03-DNCLEDSTM32USB 转 TTL
VCC3.3
RXDA2
TXDA3
GNDG
RA5
YA6
GA7
GNDG
A10TX
A9RX
GGND

烧录的时候接线如下表,如果不会烧录的话可以看我之前的文章【STM32下载程序的五种方法】。

ST-Link V2STM32
SWCLKSWCLK
SWDIOSWDIO
GNDGND
3.3V3V3

接好如下图:

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 进行通讯,所以第一步需要先做好串口的配置。

关于串口的配置,我写过一篇文章手把手教你玩串口,大家可以移步下文查看:

【STM32串口接收不定长数据(接收中断+超时判断)】

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();                                                  // 翻转LED1if(strstr((const char *)_4g_uart_rx_buf, "yellow") != NULL)         //如果接收到关键词"yellow"LED2_TOGGLE();                                                  // 翻转LED2if(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://www.mzph.cn/bicheng/64145.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

QT数据库操作详解

在Qt中&#xff0c;操作数据库通常使用Qt SQL模块&#xff0c;该模块提供了一组类来与数据库进行交互。 数据库连接与查询执行 QSqlDatabase::addDatabase(): 添加一个数据库连接。 QSqlDatabase::open(): 打开数据库连接。 QSqlDatabase::close(): 关闭数据库连接。 QSql…

如何实现接口继承与实现继承的区别?如何处理多态性与性能的平衡?

在面向对象编程中&#xff0c;接口继承和实现继承是两个重要的概念&#xff0c;同时多态性也是面向对象编程的一大特性&#xff0c;但在追求多态性的同时&#xff0c;我们也需要考虑性能问题。本文将详细探讨接口继承与实现继承的区别&#xff0c;以及如何处理多态性与性能的平…

Visual Studio 使用 GitHub Copilot 聊天

&#x1f380;&#x1f380;&#x1f380;【AI辅助编程系列】&#x1f380;&#x1f380;&#x1f380; Visual Studio 使用 GitHub Copilot 与 IntelliCode 辅助编码Visual Studio 安装和管理 GitHub CopilotVisual Studio 使用 GitHub Copilot 扩展Visual Studio 使用 GitHu…

TimerPickerDialog组件的用法

文章目录 1 概念介绍2 使用方法3 示例代码我们在上一章回中介绍了Snackbar Widget相关的内容,本章回中将介绍TimePickerDialog Widget.闲话休提,让我们一起Talk Flutter吧。 1 概念介绍 我们在这里说的TimePickerDialog是一种弹出窗口,只不过窗口的内容固定显示为时间,它主…

MySQL运算符知识点

算术运算符 算术运算符主要用于数学运算&#xff0c;其可以连接运算符前后的两个数值或表达式&#xff0c;对数值或表达式进行加(&#xff09;、减&#xff08;-&#xff09;、乘&#xff08;*&#xff09;、除&#xff08;/&#xff09;和取模&#xff08;%&#xff09;运算…

【HTML】HTML动画时钟

今天分享一个比较有趣的HTML动画时钟&#xff0c;感兴趣的小伙伴可以自行上手体验一番&#xff0c;操作也非常简单&#xff0c;如下&#xff1a; 1. 实操 实践操作步骤&#xff1a; 创建一个文本文件 clock.txt将上述代码粘贴到 clock.txt 中。修改文件后缀&#xff0c;将文…

Linux高并发服务器开发 第四天(wc/whoami命令 权限修改chmod 添加/删除用户(组) 切换用户 修改文件所有者/所属组 查找/过滤)

目录 1.wc和whoami命令 1.1wc命令 1.2whoami命令 2.用户权限/用户/用户组 2.1修改文件权限chmod 2.1.1文字设定法 2.1.2数字设定法 2.2添加删除新用户和新用户组 2.3切换用户 2.4修改文件所有者和所属组 2.4.1修改所有者 2.4.2修改所属组 3.查找和过滤 3.1find—…

微服务架构导学

一. 什么是微服务 微服务是一个软件架构风格&#xff0c;将一个大型的项目拆分成多个小项目&#xff0c;每个项目都被称为一个微服务&#xff0c;通过多个微服务共同组成一个大的项目。 二. 单体架构和微服务架构 单体架构 将整个项目的功能、模块全部堆积在一个项目中 优点&am…

【kubernetes】kubectl get nodes报NotReady

目录 1. 说明2. 问题描述3. kube-flannel.yml 1. 说明 1.这里k8s的版本是v1.17.4。2.若kube-flannel.yml中的镜像拉取不下来&#xff0c;可以下载本文章的文件资源&#xff0c;手动docker load -i ***.tar的方式。3.v1.17.4的kube-flannel.yml参考下面代码。4.通过kubectl get…

web实操7——ServletContext

概念 和服务器通信 功能 解释说明&#xff1a; mime&#xff1a;互联网中一种文件的类型&#xff0c;可以用servletContext对象来获取。 域对象&#xff1a;用来共享数据&#xff0c;里面有一些get,set,removeAttribute,只要搞清楚ServletContext对象的域的范围是什么 如何…

C语言之输入输出

标准库 IO 输入输出功能并非C语言的组成部分&#xff0c;ANSI标准定义了相关的库函数 输入输出 <stdio.h> 流stream是与设备关联的数据的源或者目的地。 文本流&#xff1a;由文本行组成的序列 不同系统的特性可能不一样&#xff0c;比如行最大长度和行结束符 二进制流…

LLMC:大语言模型压缩工具的开发实践

关注&#xff1a;青稞AI&#xff0c;学习最新AI技术 青稞Talk主页&#xff1a;qingkelab.github.io/talks 大模型的进步&#xff0c;正推动我们向通用人工智能迈进&#xff0c;然而庞大的计算和显存需求限制了其广泛应用。模型量化作为一种压缩技术&#xff0c;虽然可以用来加速…

微信小程序的文件结构

微信小程序的文件结构非常直观且高效&#xff0c;主要由几个关键文件夹和文件组成。以下是对微信小程序文件结构的详细解析&#xff1a; 一、关键文件夹 Pages文件夹&#xff1a; 这是小程序的“心脏”&#xff0c;包含了每个页面的文件。每个页面通常由四个文件定义&#xff…

数据安全法-政务数据安全与开放

第五章 政务数据安全与开放 第三十七条 国家大力推进电子政务建设&#xff0c;提高政务数据的科学性、准确性、时效性&#xff0c;提升运用数据服务经济社会发展的能力。 第三十八条 国家机关为履行法定职责的需要收集、使用数据&#xff0c;应当在其履行法定职责的范围内依…

总结与提升

今天学习了ai&#xff0c;对今天学习的内容进行总结。 本文参考chat gpt-4的训练文献。 模型架构基础 Transformer 架构&#xff1a;ChatGPT 采用了 Transformer 架构&#xff0c;这是一种基于自注意力机制的深度学习模型架构。它能够并行计算文本中的长期依赖关系&#xff…

舌头分割数据集labelme格式2557张1类别

数据集格式&#xff1a;labelme格式(不包含mask文件&#xff0c;仅仅包含jpg图片和对应的json文件) 图片数量(jpg文件个数)&#xff1a;2557 标注数量(json文件个数)&#xff1a;2557 标注类别数&#xff1a;1 标注类别名称:["tongue"] 每个类别标注的框数&#xff1…

Jenkins 启动 程序 退出后 被杀死问题

参考 Spawning Processes From Build (jenkins.io) 解决jenkins脚本启动项目后进程被杀死_jenkins杀进程-CSDN博客

使用 Maven 来构建 Scala

以下是使用Maven构建Scala项目的基本步骤&#xff1a; 1. 创建Maven项目 - 可以使用Maven的原型&#xff08;archetype&#xff09;来创建项目。在命令行中运行 mvn archetype:generate -DgroupIdcom.example -DartifactIdmy -scala - project -DarchetypeArtifactIdmaven - ar…

测试工程师八股文03|Python编程题

一、题目 1、合并两个数组 class Solution:def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:nums1[m:] nums2nums1.sort()2、判断链表中是否有环 class Solution:def hasCycle(self, head: ListNode) -> bool:seen set()while head:if…

[Unity] AppLovin Max接入Native 广告 Android篇

把下载下来的maxnativelibrary-release-文件放在Plugins/Android下 将这一行加入到mainTemplate.gradle文件中 implementation androidx.constraintlayout:constraintlayout:2.1.4添加下面的两个脚本 using System; using System.Collections; using System.Collections.Gener…