当前位置: 首页 > article >正文

STM32单片机入门学习——第22节: [7-2] AD单通道AD多通道

写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难,但我还是想去做!

本文写于:2025.04.07

STM32开发板学习——第22节: [7-2] AD单通道&AD多通道

  • 前言
  • 开发板说明
  • 引用
  • 解答和科普
  • 一、AD单通道
  • 二、AD多通道
  • 问题
  • 总结

前言

   本次笔记是用来记录我的学习过程,同时把我需要的困难和思考记下来,有助于我的学习,同时也作为一种习惯,可以督促我学习,是一个激励自己的过程,让我们开始32单片机的学习之路。
   欢迎大家给我提意见,能给我的嵌入式之旅提供方向和路线,现在作为小白,我就先学习32单片机了,就跟着B站上的江协科技开始学习了.
   在这里会记录下江协科技32单片机开发板的配套视频教程所作的实验和学习笔记内容,因为我之前有一个开发板,我大概率会用我的板子模仿着来做.让我们一起加油!
   另外为了增强我的学习效果:每次笔记把我不知道或者问题在后面提出来,再下一篇开头作为解答!

开发板说明

   本人采用的是慧净的开发板,因为这个板子是我N年前就买的板子,索性就拿来用了。另外我也购买了江科大的学习套间。
   原理图如下
1、开发板原理图
在这里插入图片描述
2、STM32F103C6和51对比
在这里插入图片描述
3、STM32F103C6核心板
在这里插入图片描述

视频中的都用这个开发板来实现,如果有资源就利用起来。另外也计划实现江协科技的套件。

下图是实物图
在这里插入图片描述

引用

【STM32入门教程-2023版 细致讲解 中文字幕】
还参考了下图中的书籍:
STM32库开发实战指南:基于STM32F103(第2版)
在这里插入图片描述
数据手册
在这里插入图片描述

解答和科普

一、AD单通道

在这里插入图片描述
PA0口,PA0到PB1这10个引脚是ADC的10个通道,所以可以任意接。
在这里插入图片描述
第一步,开启RCC时钟,包括ADC和GPIO的时钟,另外这里ADCCLK的分频器,也需要设置一下。
第二步,配置GPIO,把需要用的GPIO配置成模拟输入的模式。
第三步,配置这里的多路开关,把左边的通道接入到右边的规则组列表里,这个就是我们之前说的点菜,把各个通道的菜,列在菜单里。
第四步,配置ADC转换器了,在库函数里,是用结构体来配置的,可以配置这一大块电路的参数,包括ADC是单次转换还是连续转换,扫描还是非扫描、有几个通道,触发源是什么,数据对齐是左对齐还是右对齐。
如果你需要模拟看门狗,那会有几个函数用来配置阈值和监测通道的,如果你想开启中断,那就在中断输出控制里用ITConfig函数开启对应的中断输出,然后再在NVIC中,配置一下优先级,这样就能触发中断了。
第五步,开关控制,调用一下ADC_Cmd函数,开启ADC。这样ADC就配置完成了。
当然在开启ADC的时候,还可以进行校准,这样可以减小误差。

在ADC工作的时候,如果想要软件触发转换,那会有函数可以触发,如果想读取转换结果,那也会有函数可以读取结果。

配置ADCCLK分频器,可以对APB2的72Mhz时钟选择2、4、6、8分频,输入到ADCCLK,这就是这个函数的作用,是在RCC库函数里面,不要忘了配置。

void RCC_ADCCLKConfig(uint32_t RCC_PCLK2);

在这里插入图片描述

void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);

用来给ADC上电的,也就是开关控制;

void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState);

开启DMA输出信号的,如果使用DMA转运数据,那就得调用这个函数;

void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState);

用于控制某个中断,能不能通向NVIC;

void ADC_ResetCalibration(ADC_TypeDef* ADCx);
FlagStatus ADC_GetResetCalibrationStatus(ADC_TypeDef* ADCx);
void ADC_StartCalibration(ADC_TypeDef* ADCx);
FlagStatus ADC_GetCalibrationStatus(ADC_TypeDef* ADCx);

控制校准

void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);

软件触发

FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx);

不能判断是不是转换结束,转换开始后马上清除此位,这个函数是返回SWSTART的状态,由于在转换开始后立刻就清零了,所以这个函数的返回值和转换是否结束,毫无关系。

FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);

判断EOC标志位是否为1,判断转换是否结束;

void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number);
void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);

间断模式

void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);

给序列的每个组填写指定的通道,就是填写点菜菜单的过程。
在这里插入图片描述

void ADC_ExternalTrigConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);

是否允许外部触发转换;

uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);

ADC获取转换值,就是获取AD转换的数据寄存器,读取转换结果就要使用这个函数,

uint32_t ADC_GetDualModeConversionValue(void);

ADC获取双模式转换值,这个是双ADC模式读取转换结果的函数;

void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog);
void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold, uint16_t LowThreshold);
void ADC_AnalogWatchdogSingleChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel);

模拟看门狗配置

void ADC_TempSensorVrefintCmd(FunctionalState NewState);
FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);
void ADC_ClearFlag(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);
ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT);
void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT);

时钟开启

void AD_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);		//开启ADC1的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);	//开启GPIOA的时钟
}

配置ADC CLOCK

	RCC_ADCCLKConfig(RCC_PCLK2_Div6);						//分频:72Mhz/6=12Mhz

配置GPIO

	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
	GPIO_InitTypeDef   GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);	

选择规则组的通道

ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);

在这里插入图片描述

现在的配置是:在规则组菜单列表的第一个位置,写入通道0这个通道,就是在序列1的位置,写入通道0,如果你还想在序列2的位置写入其他的通道,那就复制一下这个代码,把这个序列数改为2,然后指定你想要的通道,如果还行继续填充菜单,那就在复制进行配置。

ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);ADC_RegularChannelConfig(ADC1,ADC_Channel_3,2,ADC_SampleTime_55Cycles5);

在这里插入图片描述
结构体初始化ADC

ADC_InitStructure.ADC_ExternalTrigConv=;

在这里插入图片描述
在这里插入图片描述

ADC_InitTypeDef			ADC_InitStructure;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;							//扫描模式ADC_InitStructure.ADC_NbrOfChannel=1;								//通道数目:总共用到几个通道ADC_Init(ADC1,&ADC_InitStructure);ADC_Cmd(ADC1,ENABLE);ADC_ResetCalibration(ADC1);while(ADC_GetResetCalibrationStatus(ADC1)== SET);ADC_StartCalibration(ADC1);while (ADC_GetCalibrationStatus(ADC1)== SET);

获取转换值

uint16_t  AD_GetValue(void)
{ADC_SoftwareStartConvCmd(ADC1,ENABLE);							//软件触发,ADC开始转换while (ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)== RESET);				//查看是否转换完成 68个周期 5.6usreturn ADC_GetConversionValue(ADC1);			//读取DR寄存器,会自动清理EOC标志位,不需要手动清除了
}

在这里插入图片描述

代码
main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.h"
#include "Key.h"
#include "OLED.h"
#include  "AD.h"uint16_t ADValue;
float  Voltage;
int main(void)
{OLED_Init();AD_Init();OLED_ShowString(1,2,"Hello STM32 MCU");OLED_ShowString(2,1,"ADValue:");OLED_ShowString(3,1,"Voltage:0.00V");while(1){ADValue=AD_GetValue();Voltage=(float) ADValue/4095 *3.3 ;OLED_ShowNum(2,9,ADValue,4);OLED_ShowNum(3,9,Voltage,1);OLED_ShowNum(3,11,(uint16_t)(Voltage*100)%100,2);Delay_ms(100);}
}

AD.CH

#include "stm32f10x.h"                  // Device headervoid AD_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);		//开启ADC1的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);	//开启GPIOA的时钟RCC_ADCCLKConfig(RCC_PCLK2_Div6);						//分频:72Mhz/6=12MhzGPIO_InitTypeDef   GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);	ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);ADC_InitTypeDef			ADC_InitStructure;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;							//扫描模式ADC_InitStructure.ADC_NbrOfChannel=1;								//通道数目:总共用到几个通道ADC_Init(ADC1,&ADC_InitStructure);ADC_Cmd(ADC1,ENABLE);ADC_ResetCalibration(ADC1);while(ADC_GetResetCalibrationStatus(ADC1)== SET);ADC_StartCalibration(ADC1);while (ADC_GetCalibrationStatus(ADC1)== SET);
}uint16_t  AD_GetValue(void)
{ADC_SoftwareStartConvCmd(ADC1,ENABLE);							//软件触发,ADC开始转换while (ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)== RESET);				//查看是否转换完成 68个周期 5.6usreturn ADC_GetConversionValue(ADC1);			//读取DR寄存器,会自动清理EOC标志位,不需要手动清除了
}
#ifndef    __AD_H
#define    __AD_Hvoid AD_Init(void);
uint16_t  AD_GetValue(void);#endif

实验现象

AD单通道

连续模式,非扫描
在这里插入图片描述

ADC_InitTypeDef			ADC_InitStructure;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=ENABLE;					//连续转换还是单词转换ADC_InitStructure.ADC_ScanConvMode=DISABLE;							//扫描模式ADC_InitStructure.ADC_NbrOfChannel=1;								//通道数目:总共用到几个通道ADC_Init(ADC1,&ADC_InitStructure);ADC_Cmd(ADC1,ENABLE);ADC_ResetCalibration(ADC1);while(ADC_GetResetCalibrationStatus(ADC1)== SET);ADC_StartCalibration(ADC1);while (ADC_GetCalibrationStatus(ADC1)== SET);ADC_SoftwareStartConvCmd(ADC1,ENABLE);	
uint16_t  AD_GetValue(void)
{return ADC_GetConversionValue(ADC1);			
}

在这里插入图片描述

二、AD多通道

在这里插入图片描述
AO分别接在PA1、PA2、PA3口;

在扫描 模式下,你启动列表之后,它里面每一个单独的通道转换完成之后不会产生标志位,也不会触发中断,你不知道某一个通道是不是转换完成了,它只有在整个列表都转换完成后,才会产生一次EOC标志位,才能触发中断,而这时前面的数据已经被覆盖丢失了。
第二个问题是,AD转换是非常快的,几us,手动转移太高,可以使用间断模式,每转换一个通道就暂停一次,等我们手动转运之后,再继续触发,继续下一次转换;只能通过延迟足够的时间,太蛮烦;

在这里插入图片描述
只需要在每次出发转换之前,手动更改一下列表第一个位置的通道就行了,在转换前,先制定一下通道,再启动转换,就可以实现多通道了。
main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.h"
#include "Key.h"
#include "OLED.h"
#include  "AD.h"uint16_t AD0,AD1,AD2,AD3;int main(void)
{OLED_Init();AD_Init();OLED_ShowString(1,1,"AD0:");OLED_ShowString(2,1,"AD1:");OLED_ShowString(3,1,"AD2:");OLED_ShowString(4,1,"AD3:");while(1){AD0=AD_GetValue( ADC_Channel_0);AD1=AD_GetValue( ADC_Channel_1);AD2=AD_GetValue( ADC_Channel_2);AD3=AD_GetValue( ADC_Channel_3);OLED_ShowNum(1,5,AD0,4);OLED_ShowNum(2,5,AD1,4);OLED_ShowNum(3,5,AD2,4);OLED_ShowNum(4,5,AD3,4);Delay_ms(100);}
}

AD.ch

#include "stm32f10x.h"                  // Device headervoid AD_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);		//开启ADC1的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);	//开启GPIOA的时钟RCC_ADCCLKConfig(RCC_PCLK2_Div6);						//分频:72Mhz/6=12MhzGPIO_InitTypeDef   GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);	ADC_InitTypeDef			ADC_InitStructure;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;							//扫描模式ADC_InitStructure.ADC_NbrOfChannel=1;								//通道数目:总共用到几个通道ADC_Init(ADC1,&ADC_InitStructure);ADC_Cmd(ADC1,ENABLE);ADC_ResetCalibration(ADC1);while(ADC_GetResetCalibrationStatus(ADC1)== SET);ADC_StartCalibration(ADC1);while (ADC_GetCalibrationStatus(ADC1)== SET);
}uint16_t  AD_GetValue(uint8_t ADC_Channel)
{ADC_RegularChannelConfig(ADC1,ADC_Channel,1,ADC_SampleTime_55Cycles5);ADC_SoftwareStartConvCmd(ADC1,ENABLE);							//软件触发,ADC开始转换while (ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)== RESET);				//查看是否转换完成 68个周期 5.6usreturn ADC_GetConversionValue(ADC1);			//读取DR寄存器,会自动清理EOC标志位,不需要手动清除了
}
#ifndef    __AD_H
#define    __AD_Hvoid AD_Init(void);
uint16_t  AD_GetValue(uint8_t ADC_Channel);#endif

实验现象

AD多通道

问题

总结

本节课主要是学习了AD通道的代码配置,如何对每个部分配置:
第一步,开启RCC时钟,包括ADC和GPIO的时钟,另外这里ADCCLK的分频器,也需要设置一下。
第二步,配置GPIO,把需要用的GPIO配置成模拟输入的模式。
第三步,配置这里的多路开关,把左边的通道接入到右边的规则组列表里,这个就是我们之前说的点菜,把各个通道的菜,列在菜单里。
第四步,配置ADC转换器了,在库函数里,是用结构体来配置的,可以配置这一大块电路的参数,包括ADC是单次转换还是连续转换,扫描还是非扫描、有几个通道,触发源是什么,数据对齐是左对齐还是右对齐。
如果你需要模拟看门狗,那会有几个函数用来配置阈值和监测通道的,如果你想开启中断,那就在中断输出控制里用ITConfig函数开启对应的中断输出,然后再在NVIC中,配置一下优先级,这样就能触发中断了。
第五步,开关控制,调用一下ADC_Cmd函数,开启ADC。这样ADC就配置完成了。
当然在开启ADC的时候,还可以进行校准,这样可以减小误差。
最后启动转换,读取转换完成后的值。
多通道是单此转换,把序列1的位置换成要读的通道,实现了AD多通道的读取。

相关文章:

STM32单片机入门学习——第22节: [7-2] AD单通道AD多通道

写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难,但我还是想去做! 本文写于:2025.04.07 STM32开发板学习——第22节: [7-2] AD单通道&AD多通道 前言开发板说明引用解…...

python基础语法1:输入输出

1. 输出 (Output) 1.1 print() 基础 Python 使用 print() 函数向控制台输出内容。 # 输出字符串 print("Hello, World!") # 输出多个值(自动用空格分隔) print("Name:", "Alice", "Age:", 25) # 修改分隔符&…...

对Android中zygote的理解

1. Zygote的作用 Zygote是Android系统的核心进程,核心作用可归纳为以下三点: 核心作用详细说明进程孵化器作为所有应用进程的父进程,通过fork快速创建新进程(避免重复初始化虚拟机)。(system server也由z…...

【Survival Analysis】【机器学习】【1】

前言: 今年在做的一个博士课题项目,主要是利用病人的数据,训练出一个AI模型,做因果分析, 以及个性化治疗。自己一直是做通讯AI方向的,这个系列主要参考卡梅隆大学的教程,以及临床医生的角度 了…...

WebShell详解:原理、分类、攻击与防御

目录 一、WebShell的定义与核心概念 二、WebShell的分类 三、WebShell的攻击原理与常见手法 1. 攻击原理 2. 常见攻击路径 四、WebShell的危害 五、防御与检测策略 六、总结 一、WebShell的定义与核心概念 ​​WebShell​​是一种以ASP、PHP、JSP等网页脚本形式存在的恶…...

JavaScript---原型和原型链

目录 一、引用类型皆为对象 二、原型和原型链是什么 三、__proto__与prototype 总结 四、原型链顶层 五、constructor 六、函数对象的原型链 一、引用类型皆为对象 原型和原型链都是来源于对象而服务于对象: JavaScript中一切引用类型都是对象,…...

离散数学问题集--问题5.9

问题 5.9 综合了计算机组成原理、数字逻辑和离散数学中的关键概念,旨在帮助学生理解二进制算术运算的硬件实现、逻辑门与算术运算的关系,以及如何使用数学方法来验证数字系统的正确性。它强调了从规范到实现再到验证的完整过程。 思想 函数抽象&#xf…...

手游防DDoS攻击SDK接入

在手游中集成防DDoS攻击SDK是抵御流量型和应用层攻击的核心手段之一。以下从​​SDK选型、接入流程、防护策略优化​​三个维度提供完整指南,并附关键代码示例: ​​一、SDK选型与核心能力对比​​ ​​服务商​​​​优势​​​​劣势​​​​适用场景…...

Java—HTML:CSS选择器

今天我要介绍的知识点内容是Java HTML中的CSS选择器; CSS选择器用于定位HTML元素并为其添加样式。它允许我们控制网页的颜色、字体、布局和其他视觉元素。通过分离内容与样式。 下面我将介绍CSS中选择器的使用,并作举例说明; 选择器基本语…...

如何将/dev/ubuntu-vg/lv-data的空间扩展到/dev/ubuntu-vg/ubuntu-lv的空间上

要将 /dev/ubuntu-vg/lv-data 的空间扩展到 /dev/ubuntu-vg/ubuntu-lv 上,实际上是将 lv-data 的空间释放出来,并将其分配给 ubuntu-lv。以下是详细的步骤和操作说明: 已知信息 你有两个逻辑卷: /dev/ubuntu-vg/lv-data/dev/ubun…...

SSM阶段性总结

0 Pojo类 前端给后端:DTO 后端给前端:VO 数据库:PO/VO 业务处理逻辑:BO 统称pojo 1 代理模式 实现静态代理: 1定义接口2实现类3写一个静态代理类4这样在调用时就可以使用这个静态代理类来实现某些功能 实现动态代…...

Qt 5.14.2入门(一)写个Hello Qt!程序

目录 参考链接:一、新建项目二、直接运行三、修改代码增加窗口内容1、Qt 显示一个 QLabel 标签控件窗口2、添加按键 参考链接: Qt5教程(一):Hello World 程序 Qt 编程指南 一、新建项目 1、新建一个项目&#xff08…...

Jmeter分布式测试启动

代理客户端配置 打开jmeter.properties文件,取消注释并设置端口(如server_port1099), 并添加server.rmi.ssl.disabletrue禁用SSL加密。 (Linux系统)修改jmeter-server文件中的RMI_HOST_DEF为代理机实际IP。…...

redis itheima

缓存问题 核心是如何避免大量请求到达数据库 缓存穿透 既不存在于 redis,也不存在于 mysql 的key,被重复请求 public Result queryById(Long id) {String key CACHE_SHOP_KEYid;// 1. redis & mysqlString shopJson stringRedisTemplate.opsFo…...

mysql 执行计划中eq_ref是什么意思?

在 MySQL 的执行计划中,eq_ref 是一种连接类型(type),表示查询优化器在使用**主键(PRIMARY KEY)或唯一索引(UNIQUE INDEX)**进行等值匹配()时,对表…...

QT 调用动态链接库

引入QT提供的动态加载库的类 #include <QLibrary>定义函数指针类型 typedef void (*GetResFunction)(uint8_t*, uint8_t*, int);定义函数指针的主要目的是为了解析和调用动态链接库中的函数。如果你不定义函数指针&#xff0c;就无法直接调用动态链接库中的函数 加载动…...

100天精通Python(爬虫篇)——第122天:基于selenium接管已启动的浏览器(反反爬策略)

文章目录 1、问题描述2、问题推测3、解决方法3.1 selenium自动启动浏览器3.2 selenium接管已启动的浏览器3.3 区别总结 4、代码实战4.1 手动方法&#xff08;手动打开浏览器输入账号密码&#xff09;4.2 自动方法&#xff08;.bat文件启动的浏览器&#xff09; 1、问题描述 使用…...

MPP 架构解析:原理、核心优势与对比指南

一、引言&#xff1a;大数据时代的数据处理挑战 全球数据量正以指数级增长。据 Statista 统计&#xff0c;2010 年全球数据量仅 2ZB&#xff0c;2025 年预计达 175ZB。企业面临的核心挑战已从“如何存储数据”转向“如何快速分析数据”。传统架构在处理海量数据时暴露明显瓶颈…...

GitHub 趋势日报 (2025年04月06日)

GitHub 趋势日报 (2025年04月06日) 本日报由 TrendForge 系统生成 https://trendforge.devlive.org/ &#x1f4c8; 今日整体趋势 Top 10 排名项目名称项目描述今日获星语言1microsoft/markitdownPython tool for converting files and office documents to Markdown.⭐ 548Py…...

Python设计模式-工厂模式

一、模式定义与核心思想 工厂模式&#xff08;Factory Pattern&#xff09;属于创建型设计模式&#xff0c;其核心思想是通过一个"工厂类"来创建对象&#xff0c;而不是直接调用类的构造函数。这种模式将对象的实例化过程封装起来&#xff0c;使系统在实例化对象时能…...

SAP-ABAP:SAP的Open SQL和Native SQL详细对比

在SAP ABAP开发中,Open SQL和Native SQL是两种操作数据库的方式,它们的核心区别在于可移植性、功能范围及底层实现机制。以下是详细对比: 1. Open SQL:深入解析 1.1 核心特性 数据库抽象层 Open SQL 由 SAP 内核的 Database Interface (DBI) 转换为目标数据库的 SQL(如 …...

蓝桥杯 拼数(字符串大小比较)

题目描述 设有 n 个正整数 a1​…an​&#xff0c;将它们联接成一排&#xff0c;相邻数字首尾相接&#xff0c;组成一个最大的整数。 输入格式 第一行有一个整数&#xff0c;表示数字个数 n。 第二行有 n 个整数&#xff0c;表示给出的 n 个整数 ai​。 输出格式 一个正整…...

Server-Sent Events一种允许服务器向客户端发送实时更新的 Web API

Server-Sent Events&#xff08;SSE&#xff09;是一种允许服务器向客户端发送实时更新的 Web API。它基于 HTTP 协议&#xff0c;提供了一种单向的、服务器到客户端的通信机制&#xff0c;客户端可以通过监听服务器发送的事件来接收实时数据。下面从原理、使用场景、代码示例等…...

彻底解决VS2008编译错误:fatal error C1083 无法打开包括文件“stdint.h“

彻底解决VS2008编译错误&#xff1a;fatal error C1083 无法打开包括文件"stdint.h" 一、错误现象与本质原因 当在Visual Studio 2008中编译包含C99标准整数类型&#xff08;如int8_t、uint32_t&#xff09;的代码时&#xff0c;常出现以下编译错误&#xff1a; f…...

react从零开始的基础课

全文约5万字。 1.hello,.. // App.jsx import { useState } from react import reactLogo from ./assets/react.svg import viteLogo from /vite.svg import ./App.cssfunction App() {const [count, setCount] useState(0)return (<><Greeting name"world&qu…...

算法题型讲解

一.双指针 主要分为俩种类型&#xff1a; 1.左右指针&#xff1a;双指针指向开头&#xff0c;以一定标准移动或交换&#xff0c;对区域进行划分&#xff0c;或找到特殊点的位置 &#xff08;如&#xff1a;快慢指针判断有无环&#xff0c;移动零&#xff09; 2.对撞指针&am…...

操作主机的管理

1.在AD林范围内&#xff0c;有哪几个操作主机角色 架构主机&#xff08;Schema Master&#xff09; 功能&#xff1a;负责整个AD林中所有对象和属性的定义&#xff0c;是唯一可以更新目录架构的DC。架构更新会从架构主机复制到目录林中的所有其他域控制器。 作用范围&#xf…...

Redis和数据库一致性问题

操作模拟 1、先更新数据库还是先更新缓存&#xff1f; 1.1先更新缓存&#xff0c;再更新数据库 按并发的角度来说&#xff0c;有两个线程A、B&#xff0c;操作同一个数据&#xff0c;线程A先更新缓存为1&#xff0c;在线程A更新数据库之前&#xff0c;这时候线程B进来&#…...

第R8周:RNN实现阿尔茨海默病诊断(pytorch)

>- **&#x1f368; 本文为[&#x1f517;365天深度学习训练营]中的学习记录博客** >- **&#x1f356; 原作者&#xff1a;[K同学啊]** 本人往期文章可查阅&#xff1a; 深度学习总结 一、准备工作 &#x1f3e1; 我的环境&#xff1a; 语言环境&#xff1a;Python3.1…...

《穿透表象,洞察分布式软总线“无形”之奥秘》

分布式系统已成为众多领域的关键支撑技术&#xff0c;而分布式软总线作为实现设备高效互联的核心技术&#xff0c;正逐渐走入大众视野。它常被描述为一条“无形”的总线&#xff0c;这一独特属性不仅是理解其技术内涵的关键&#xff0c;更是把握其在未来智能世界中重要作用的切…...