【STM32】单片机ADC原理详解及应用编程
本篇文章主要详细讲述单片机的ADC原理和编程应用,希望我的分享对你有所帮助!
目录
一、STM32ADC概述
1、ADC(Analog-to-Digital Converter,模数转换器)
2、STM32工作原理
二、STM32ADC编程实战
(一)、ADC开发的寄存器库函数
(二)、ADC开发的HAL库
(三)、实战工程
1、ADC单通道采集
2、ADC多通道采集
三、结语
一、STM32ADC概述
1、ADC(Analog-to-Digital Converter,模数转换器)
STM32的ADC(Analog-to-Digital Converter,模拟数字转换器)是STM32微控制器系列中集成的一种功能强大的模块,用于将模拟信号转换为数字信号。STM32微控制器广泛应用于嵌入式系统,ADC模块在许多应用场景中都至关重要,例如传感器读取、信号处理和控制系统。
模拟量(Analog Quantity)是指在一个连续范围内可以取任意值的物理量。这种物理量的值可以是任意的实数,通常用来表示那些变化是渐进的、连续的特征,而不是离散的。
- 模拟量:可以在一个连续的范围内变化,例如温度可以是25.1°C、25.2°C等,具有无限个可能值。
- 数字量:只能取有限的离散值,例如开关的开(1)和关(0)状态,或者数字传感器读取的值。
在许多应用中,模拟量需要转换为数字量以便进行处理,这通常通过模数转换器(ADC)实现。转换后,计算机或微控制器能够以数字形式读取和处理这些信号。
ADC转换模式:
单次转换模式(Single Conversion Mode):ADC在每次触发时只进行一次转换。适用于低速、低功耗的应用。
连续转换模式(Continuous Conversion Mode):ADC持续进行转换,适用于需要实时监测的应用,如信号处理和实时数据采集。
扫描模式(Scan Mode):ADC可以在多个通道间进行扫描,每个通道依次进行转换,适合多通道数据采集。
触发模式(Triggered Mode):转换过程由外部信号触发,可以是定时器、GPIO引脚等,适合需要同步数据采集的场景。
差分模式(Differential Mode):ADC测量两个输入信号的差值,提供更高的噪声抗性,适用于高精度测量。
伪差分模式(Pseudo-Differential Mode):其中一个输入端连接到地,另一端测量信号,适合简单的差分测量。
在ADC(模数转换器)的应用中,通道组可以分为规则通道组(Regular Channel Group)和注入通道组(Injected Channel Group)。这两种通道组的主要区别在于它们的工作方式、优先级以及使用场景。
规则通道组(Regular Channel Group)
定义:规则通道组是ADC的主要通道组,用于常规的信号采集。它通常用于周期性采集的传感器信号。
特点:
- 持续转换:在连续转换模式下,规则通道组可以在多个通道间进行循环采样。
- 优先级低:相较于注入通道组,规则通道组的优先级较低,通常用于常规数据的采集。
- 数据存储:转换结果通常存储在一个数据寄存器中,等待主程序读取。
- 触发方式:可以通过定时器、外部事件等方式触发采样。
适用场景:适用于需要实时采集且对响应时间要求不高的应用,如环境监测、温度传感器等。
注入通道组(Injected Channel Group)
定义:注入通道组用于优先级更高的信号采集,通常用于突发事件或特定条件下的快速采样。
特点:
- 高优先级:注入通道组具有较高的优先级,能够在任何时候中断规则通道组的采样进行数据采集。
- 快速响应:适合快速响应的应用,如检测瞬时信号变化、故障检测等。
- 独立触发:可以独立于规则通道组进行触发,支持多种触发源(如外部引脚、内部事件等)。
- 多个通道:通常可以配置多个注入通道,进行快速的信号采样。
适用场景:适用于需要在特定条件下迅速采集信号的应用,如运动控制、脉冲信号采集等。
2、STM32工作原理
STM32包含1~3个12位逐次逼近型的模拟数字转换器。每个ADC最多有18个通道,可测量16个外部信号源和2个内部信号源。各通道的A/D转换可以单次、连续、扫描或间断模式执行,有规则通道组和注入通道组,每次转换结束可产生中断。转换的结果可以左对齐或右对齐方式存储在16位数据寄存器中。
1)STM32F103C8T6有2个ADC,ADC1和ADC2。记为ADCx。
2)每个ADC有18个通道。16个外部信号源测量通道ADCx_IN0~ADCx_IN15,2个内部信号源测量通道。信号源引脚对应如下:
ADC的工作过程一般包括以下几个步骤:
- 采样:在某个时间点上对模拟信号进行测量,获取其电压值。
- 量化:将模拟信号的电压值与ADC的参考电压进行比较,将其转换为相应的数字值。
- 编码:将量化后的结果编码为二进制形式,输出给后续的数字电路或处理器。
ADC工作原理思维导图概况如下:
STM32F103ADC时钟和采样时间
1、时钟源
- STM32F103 的 ADC 通常由 APB2 总线时钟提供时钟。ADC 的最大工作频率为 14 MHz。
- 你需要配置 APB2 时钟(通常通过时钟配置寄存器进行配置)以确保 ADC 的工作频率在合适范围内。
2、ADC 时钟设置
- ADC 时钟的配置可以通过配置系统时钟(HSE、HSI 或 PLL)来实现。通常在系统初始化时设置。
- 在 ADC 模块中,可以通过寄存器设置 ADC 的预分频系数,以确保 ADC 时钟不超过最大工作频率。
3、采样时间配置
STM32F103 的 ADC 允许用户根据输入信号的特性选择不同的采样时间。可选的采样时间设置包括:
- 1.5 个 ADC 时钟周期
- 7.5 个 ADC 时钟周期
- 13.5 个 ADC 时钟周期
- 28.5 个 ADC 时钟周期
- 41.5 个 ADC 时钟周期
- 55.5 个 ADC 时钟周期
- 71.5 个 ADC 时钟周期
- 239.5 个 ADC 时钟周期
通过设置 ADC 寄存器中的采样时间字段,可以选择合适的采样时间。例如,对于快速变化的信号,可能选择较短的采样时间;而对于慢变化的信号,较长的采样时间可以提高测量的准确性。
4、采样时间与转换时间的关系
采样时间加上转换时间组成了每次 ADC 转换的总时间。转换时间对于 STM32F103 的 ADC 是固定的,大约为 1.5 个 ADC 时钟周期。
因此,总的转换时间公式可以表示为:
总时间=采样时间+1.5xADC时钟周期
二、STM32ADC编程实战
在编程实战之前,让我们先来了解一下ADC开发相关的库函数。
(一)、ADC开发的寄存器库函数
1. ADC初始化函数
void ADC_Init(ADC_TypeDef *ADCx, ADC_InitTypeDef *ADC_InitStruct)
功能:初始化指定的ADC外设。
参数:
ADC_TypeDef *ADCx
:指向ADC外设的指针(如ADC1
、ADC2
)。
ADC_InitTypeDef *ADC_InitStruct
:指向ADC初始化结构的指针,包含ADC配置参数。用途:设置ADC的基本参数,如分辨率、对齐方式、时钟分频等。
2. 配置ADC通道
void ADC_RegularChannelConfig(ADC_TypeDef *ADCx, uint32_t Channel, uint32_t Rank, uint32_t SamplingTime)
功能:配置ADC的常规通道。
参数:
ADC_TypeDef *ADCx
:指向ADC外设的指针。
uint32_t Channel
:选择要配置的ADC通道。
uint32_t Rank
:在转换序列中的排名。
uint32_t SamplingTime
:采样时间配置。用途:配置ADC通道以供后续的采样和转换。
3. 启动和停止ADC转换
void ADC_Cmd(ADC_TypeDef *ADCx, FunctionalState NewState)
功能:启用或禁用指定的ADC外设。
参数:
ADC_TypeDef *ADCx
:指向ADC外设的指针。
FunctionalState NewState
:功能状态,选择ENABLE
或DISABLE
。用途:控制ADC的开启和关闭。
void ADC_StartConversion(ADC_TypeDef *ADCx)
功能:开始ADC的转换。
参数:
ADC_TypeDef *ADCx
:指向ADC外设的指针。用途:启动ADC转换过程。
4. 读取ADC转换结果
uint16_t ADC_GetConversionValue(ADC_TypeDef *ADCx)
功能:获取ADC的转换结果。
参数:
ADC_TypeDef *ADCx
:指向ADC外设的指针。返回值:返回ADC转换后的数值。
用途:读取转换完成后的结果。
5. 配置DMA支持
void ADC_DMACmd(ADC_TypeDef *ADCx, FunctionalState NewState)
功能:启用或禁用ADC的DMA功能。
参数:
ADC_TypeDef *ADCx
:指向ADC外设的指针。
FunctionalState NewState
:功能状态,选择ENABLE
或DISABLE
。用途:在使用DMA传输ADC数据时配置DMA。
6. 中断支持
void ADC_ITConfig(ADC_TypeDef *ADCx, uint32_t ADC_IT, FunctionalState NewState)
功能:启用或禁用ADC中断。
参数:
ADC_TypeDef *ADCx
:指向ADC外设的指针。
uint32_t ADC_IT
:选择中断源。
FunctionalState NewState
:功能状态,选择ENABLE
或DISABLE
。用途:控制ADC的中断行为。
7. 中断回调函数
在使用中断时,需要定义回调函数以处理ADC转换完成的事件。
void ADC1_2_IRQHandler(void) {if (ADC_GetITStatus(ADC1, ADC_IT_EOC) != RESET) {// 处理ADC转换完成uint16_t adcValue = ADC_GetConversionValue(ADC1);// 清除中断标志ADC_ClearITPendingBit(ADC1, ADC_IT_EOC);} }
(二)、ADC开发的HAL库
1. ADC初始化函数
HAL_ADC_Init()
功能:初始化ADC外设。
参数:
ADC_HandleTypeDef *hadc
:指向ADC句柄的指针,结构体中包含ADC的配置参数。返回值:HAL库返回状态,通常为
HAL_OK
(成功)或错误代码。用途:设置ADC的基本参数,如分辨率、对齐方式、扫描模式等。
2. ADC通道配置函数
HAL_ADC_ConfigChannel()
功能:配置指定的ADC通道。
参数:
ADC_HandleTypeDef *hadc
:指向ADC句柄的指针。
ADC_ChannelConfTypeDef *sConfig
:指向通道配置结构的指针,包含通道选择、采样时间等。返回值:HAL库返回状态,通常为
HAL_OK
(成功)或错误代码。用途:设置通道的采样时间和输入模式等参数。
3. 启动和停止ADC转换
HAL_ADC_Start()
功能:启动ADC转换。
参数:
ADC_HandleTypeDef *hadc
:指向ADC句柄的指针。返回值:HAL库返回状态。
用途:使ADC开始进行转换。
HAL_ADC_Stop()
功能:停止ADC转换。
参数:
ADC_HandleTypeDef *hadc
:指向ADC句柄的指针。返回值:HAL库返回状态。
用途:结束ADC转换过程,释放资源。
4. 读取ADC转换结果
HAL_ADC_PollForConversion()
功能:等待ADC转换完成(轮询方式)。
参数:
ADC_HandleTypeDef *hadc
:指向ADC句柄的指针。
uint32_t Timeout
:等待超时的时间(单位:毫秒)。返回值:HAL库返回状态,通常为
HAL_OK
(成功)或超时错误代码。用途:在转换过程中进行轮询,直到转换完成。
HAL_ADC_GetValue()
功能:获取ADC转换结果。
参数:
ADC_HandleTypeDef *hadc
:指向ADC句柄的指针。返回值:ADC的转换结果。
用途:在转换完成后读取结果值。
5. DMA支持
HAL_ADC_Start_DMA()
功能:启动ADC转换并通过DMA传输数据。
参数:
ADC_HandleTypeDef *hadc
:指向ADC句柄的指针。
uint32_t *pData
:指向存储结果的缓冲区指针。
uint32_t Length
:缓冲区的长度。返回值:HAL库返回状态。
用途:使用DMA提高数据传输效率。
6. 中断支持
HAL_ADC_Start_IT()
功能:启动ADC转换并使能中断。
参数:
ADC_HandleTypeDef *hadc
:指向ADC句柄的指针。返回值:HAL库返回状态。
用途:在需要中断处理的应用中使用。
7. 中断回调函数
HAL_ADC_ConvCpltCallback()
功能:ADC转换完成时的回调函数。
参数:
ADC_HandleTypeDef *hadc
:指向ADC句柄的指针。用途:在此函数中处理转换结果。
(三)、实战工程
1、ADC单通道采集
#include "stm32f10x.h" // 引入 STM32F10x 设备头文件,包含特定于设备的定义和功能// 初始化 ADC (模数转换器)
void AD_Init(void)
{// 使能 ADC1 的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);// 使能 GPIOA 的时钟,以便配置 GPIO 引脚RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);// 配置 ADC 时钟为 PCLK2 的 1/6RCC_ADCCLKConfig(RCC_PCLK2_Div6);// 定义一个 GPIO 初始化结构体GPIO_InitTypeDef GPIO_InitStructure;// 设置引脚模式为模拟输入GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;// 设置要配置的引脚为 PA0GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;// 设置 GPIO 引脚的速度为 50MHzGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;// 初始化 GPIOAGPIO_Init(GPIOA, &GPIO_InitStructure);// 配置 ADC 的常规通道,设置通道为 ADC_Channel_0,序列为 1,采样时间为 55.5 个周期ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);// 定义一个 ADC 初始化结构体ADC_InitTypeDef ADC_InitStructure;// 设置 ADC 工作模式为独立模式ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;// 设置数据对齐方式为右对齐ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;// 设置外部触发转换为无ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;// 设置连续转换模式为禁用ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;// 设置扫描模式为禁用ADC_InitStructure.ADC_ScanConvMode = DISABLE;// 设置转换通道数量为 1ADC_InitStructure.ADC_NbrOfChannel = 1;// 初始化 ADC1ADC_Init(ADC1, &ADC_InitStructure);// 使能 ADC1ADC_Cmd(ADC1, ENABLE);// 复位 ADC 校准寄存器ADC_ResetCalibration(ADC1);// 等待复位完成while (ADC_GetResetCalibrationStatus(ADC1) == SET);// 开始 ADC 校准ADC_StartCalibration(ADC1);// 等待校准完成while (ADC_GetCalibrationStatus(ADC1) == SET);
}// 获取 ADC 转换值的函数
uint16_t AD_GetValue(void)
{// 启动软件触发的 ADC 转换ADC_SoftwareStartConvCmd(ADC1, ENABLE);// 等待转换完成标志位设置while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);// 返回 ADC 转换结果return ADC_GetConversionValue(ADC1);
}
2、ADC多通道采集
#include "stm32f10x.h" // 引入 STM32F10x 设备头文件,包含特定于设备的定义和功能// 初始化 ADC (模数转换器)
void AD_Init(void)
{// 使能 ADC1 的时钟,确保 ADC1 可以正常工作RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);// 使能 GPIOA 的时钟,以便配置 GPIO 引脚用于 ADCRCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);// 配置 ADC 时钟为 PCLK2 的 1/6RCC_ADCCLKConfig(RCC_PCLK2_Div6);// 定义一个 GPIO 初始化结构体,用于设置 GPIO 的模式和速度GPIO_InitTypeDef GPIO_InitStructure;// 设置 GPIO 模式为模拟输入 (AIN)GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;// 设置要配置的引脚为 PA0, PA1, PA2 和 PA3GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;// 设置 GPIO 引脚的速度为 50MHzGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;// 初始化 GPIOA,应用上面的配置GPIO_Init(GPIOA, &GPIO_InitStructure);// 定义一个 ADC 初始化结构体,用于配置 ADC 参数ADC_InitTypeDef ADC_InitStructure;// 设置 ADC 工作模式为独立模式ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;// 设置数据对齐方式为右对齐ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;// 设置外部触发转换为无(软件触发)ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;// 设置连续转换模式为禁用ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;// 设置扫描模式为禁用ADC_InitStructure.ADC_ScanConvMode = DISABLE;// 设置转换通道数量为 1ADC_InitStructure.ADC_NbrOfChannel = 1;// 初始化 ADC1,应用上面的配置ADC_Init(ADC1, &ADC_InitStructure);// 使能 ADC1ADC_Cmd(ADC1, ENABLE);// 复位 ADC 校准寄存器ADC_ResetCalibration(ADC1);// 等待复位完成while (ADC_GetResetCalibrationStatus(ADC1) == SET);// 开始 ADC 校准ADC_StartCalibration(ADC1);// 等待校准完成while (ADC_GetCalibrationStatus(ADC1) == SET);
}// 获取指定 ADC 通道的转换值
uint16_t AD_GetValue(uint8_t ADC_Channel)
{// 配置 ADC 通道,设置通道、序列和采样时间ADC_RegularChannelConfig(ADC1, ADC_Channel, 1, ADC_SampleTime_55Cycles5);// 启动软件触发的 ADC 转换ADC_SoftwareStartConvCmd(ADC1, ENABLE);// 等待转换完成标志位设置while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);// 返回 ADC 转换结果return ADC_GetConversionValue(ADC1);
}
三、结语
关于STM32单片机的ADC原理及编程实现就分享到此了,希望我的分享对你有所帮助!
关于以上工程的源代码,大家可以私信我,收到后我会第一时间回复!也可以回复“STM32ADC”
相关文章:

【STM32】单片机ADC原理详解及应用编程
本篇文章主要详细讲述单片机的ADC原理和编程应用,希望我的分享对你有所帮助! 目录 一、STM32ADC概述 1、ADC(Analog-to-Digital Converter,模数转换器) 2、STM32工作原理 二、STM32ADC编程实战 (一&am…...

C# 委托简述
1.委托 1.1什么是委托 委托委托 官网解释: 委托是安全封装方法的类型,类似于 C 和 C 中的函数指针。 与 C 函数指针不同的是,委托是面向对象的、类型安全的和可靠的。 委托的类型由委托的名称确定。 个人理解:委托就是一个方法的模板。它可以接收…...

瑞吉外卖项目
目录 Day01业务开发 一、项目总体介绍与展示 二、软件开发整体介绍 (一)软件开发流程 三、瑞吉外卖项目介绍 (一)项目介绍 (二)技术选型功能架构 1.技术选型—— 编辑2.功能架构—— 编辑 &a…...

Docker:4、龙晰(Anolis OS 8.8)宝塔面板安装
接上文Docker:1、基于龙晰 (Anolis OS 8.8 )的基础镜像制作,本节我们介绍:基于Docker的龙晰(Anolis OS 8.8 )宝塔安装。 在第一节中由于我们对 Docker 容器进行了SSH设置,这为我们这…...

多端项目开发全流程详解 - 从需求分析到多端部署
引言 在当今互联网时代,一个完整的产品常常需要覆盖多个终端,包括小程序、Web端(后台管理系统)、App端等。本文将详细介绍一个采用前后端分离架构的多端项目开发流程,重点分析各个终端的特点、功能定位及其开发要点。…...

4.5KB原生html+js+css实现图片打印位置的坐标和尺寸获取
一般用于图片打印文字或图片的坐标获取,代码来自AI有改动。 功能:本地图选择后不上传直接可比划线条作为对角线得到矩形,动态显示坐标 按下鼠标开始松开鼠标结束。有细微BUG但不影响坐标获取。 <!DOCTYPE html> <html lang"en">…...

智诊小助手-记录模式选择
记录模式总共有连续记录、硬件触发、软件触发、错误触发四种模式选择,并且在选择完记录模式后还可以设置保留触发点前报文条数、存储时间、录制通道、保存类型 配置过程如下: 点击下面右图中模式选择即可进入到左图中的参数配置界面 如上图选择的配置…...

JDBC: Java数据库连接的桥梁
什么是JDBC? Java数据库连接(Java Database Connectivity,简称JDBC)是Java提供的一种API,允许Java应用程序与各种数据库进行交互。JDBC提供了一组标准的接口,开发者可以利用这些接口执行SQL语句、处理结果集…...

英伟达GPU算力【自用】
GPU(图形处理单元)算力的提升是驱动当代科技革命的核心力量之一,尤其在人工智能、深度学习、科学计算和超级计算机领域展现出了前所未有的影响力。2024年的GPU技术发展,不仅体现在游戏和图形处理的传统优势上,更在跨行…...

「C/C++」C++11 之 智能指针
✨博客主页何曾参静谧的博客📌文章专栏「C/C」C/C程序设计📚全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasoli…...

算法面试小抄
第一章:算法与数据结构要点速学 1.时间复杂度 (大 O) 首先,我们来谈谈常用操作的时间复杂度,按数据结构/算法划分。然后,我们将讨论给定输入大小的合理复杂性。 数组(动态数组/列表) 规定 n arr.length, 注意: &am…...

当有违法数据时,浏览器不解析,返回了undefined,导致数据不解析
现象:页面上没有看到数据 排查:断点到线上的源码里:1、协议回调确实没有拿到数据是个undefined 2、network里看服务确实响应了数据 3、控制台没有任何报错。 心情:莫名其妙的现象 我本地有json格式化工具,copy进去后&…...

在MySQL中ORDER BY使用的那种排序算法
在 MySQL 中,ORDER BY 子句的排序算法通常根据场景、数据量和表的索引情况而有所不同。MySQL 常用的排序算法包括: 文件排序(File Sort):MySQL 没有使用索引排序的情况下,会进行文件排序,这可以…...

学习threejs,使用粒子实现雨滴特效
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言1.1 ☘️THREE.Points简介1.11 ☘️…...

分布式-单元化架构1
一 两地三中心 1.1 两地三中心* 两地指的是两个城市:同城,异地。三中心指的是三个数据中心:生产中心、同城容灾中心、异地容灾中心。 在同一个城市或者临近的城市建设两个相同的系统,双中心具备相当的业务处理能力,…...

C++模板、STL
目录 一、模板 1、函数模板 (1)、基本语法和使用 (2)、函数模板注意事项 (3)、普通函数与函数模板的区别 (4)、普通函数与函数模板的调用规则 (5)、模板的局限性 2、类模板 (1)、基本语法 (2)、类模板与函数模板区别 (3)、类模板中成员函数创建时机 (4)、类模板对象…...

计算机视觉中的点算子:从零开始构建
Hey小伙伴们!今天我们要聊的是一个非常基础但极其重要的计算机视觉技术——点算子(Point Operators)。点算子主要用于对图像的每个像素进行独立的处理,比如亮度调整、对比度增强、灰度化等。通过这些简单的操作,我们可…...

国际中文教育知识图谱问答
你还在为毕业设计头疼么?想快速搭建一个智能化系统,展示数据又能精准回答问题?那你绝对不能错过这个超实用的 知识图谱问答系统,特别适用于需要整合复杂数据关系、交互性强的项目! 这个系统基于 Neo4j图数据库 开发&a…...

酒店大板轻触开关与传统的开关有什么区别
酒店大板轻触开关与传统的开关在功能、设计、使用方式以及安装维护等多个方面都存在显著的差异。以下是对这些差异的详细分析: 功能差异 酒店大板轻触开关: 多功能性:酒店大板轻触开关通常集成了多种功能,如控制照明、窗帘、夜灯、…...

【蓝桥杯选拔赛真题78】python电话号码 第十五届青少年组蓝桥杯python选拔赛真题 算法思维真题解析
目录 python电话号码 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python电话号码 第十五届蓝桥杯青少年组python比赛选拔赛真题 一、题目要…...

对比两个json串的diff,支持map的深度递归
背景 项目重构,对老接口进行技术改造。动代码后,难免会有些bug,我们需要对比改造前后接口的返回,来判断逻辑是否有问题,这就涉及两个json的对比。 常规的diff文本工具是按行对比,无法处理复杂的map。本文通…...

【我的创作纪念日1024】
我的创作纪念日1024 机缘成就明年的规划 机缘 过去的1024个日子里,我在专业发展、职场和发展、科技创新创业、软件开发、人工智能、虚拟现实、区块链等栏目分享了一些工作和学习的建议和体会。尤其是在2022年,我连续发布100篇的博文,不仅仅是…...

萤石设备视频接入平台EasyCVR私有化视频平台变电站如何实现远程集中监控?
一、方案背景 随着城市经济的发展和电力系统的改造,变电站的数量和规模逐渐增加,对变电站的安全管理和监控需求也越来越高。视频监控系统作为重要的安全管理手段,在变电站中起到了关键的作用。 目前青犀视频研发的萤石设备视频接入平台EasyC…...

什么是多线程?请描述 Java 中实现多线程的基本方式?
今天和大家探讨一下 Java 中的多线程,包括它的基本概念、实现方式以及一些实际开发中的注意事项。 什么是多线程? 多线程是指在一个程序中存在多个执行流,每个执行流都可以独立于其他执行流执行。 在 Java 中,多线程允许开发者…...

Dynamic Sparse No Training: Training-Free Fine-tuning for Sparse LLMs
大语言模型(LLM)在设备上部署道路上落下了一个令人生畏的障碍。本文关注于大语言模型的剪枝算法。 动态稀疏训练(Dynamic Sparse Training,DST)是一种近期收到广泛关注的剪枝算法。与之前大部分剪枝方法需要训练整个网…...

解决n+1查询数据库问题
文章目录 1. 问题描述2. 解决方法3. 总结 1. 问题描述 在写项目中,可能会碰到一个问题:通过查询表A得到一个list结果,再对list中的n个元素各查询一次关联的表B。形成对数据库执行n1次查询。这种代码会无形增加数据库的处理负担,影…...

DICOM 基础知识:深入理解DICOM数据结构与标签说明
目录 DICOM 图像概念 DICOM 图像关键特性: DICOM 文件结构 常见数据元素: 数据元素示例详解 DICOM-VR 数据类型说明 DICOM 标准支持的数据集 结语 DICOM 图像概念 DICOM(Digital Imaging and Communications in Medicine&…...

Git - 如何删除 push 过一次的文件链路追踪?
(以 target 文件夹为例)如果你已经在 .gitignore 中添加了 target/ 目录,但 target 文件夹仍然出现在 Git 的变更列表中,可能是因为它之前已经被添加到 Git 仓库中。即使你更新了 .gitignore,Git 仍然会跟踪这些文件。…...

软件测试学习总结
一.软件测试概念和目的 软件测试的概念: 测试模型(V模型) 软件测试就是在软件投入运行前,对软件需求分析、设计规格说明和编码实现的最终审查,它是软件质量保证的关键步骤。 通常对软件测试的定义有两种描述: 定义1:软件测试是为了发现错误而执行程序的过程 定义2:…...

c语言错题——#define对应的查找替换
文章目录 一、题目 提示:以下是本篇文章正文内容,下面案例可供参考 一、题目 分析 结构体向最长的char对齐,前两个位段元素一共42位,不足8位,合起来占1字节,最后一个单独1字节,一共3字节。另外…...