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 综合了计算机组成原理、数字逻辑和离散数学中的关键概念,旨在帮助学生理解二进制算术运算的硬件实现、逻辑门与算术运算的关系,以及如何使用数学方法来验证数字系统的正确性。它强调了从规范到实现再到验证的完整过程。 思想 函数抽象…...
手游防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、新建一个项目(…...
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);定义函数指针的主要目的是为了解析和调用动态链接库中的函数。如果你不定义函数指针,就无法直接调用动态链接库中的函数 加载动…...
100天精通Python(爬虫篇)——第122天:基于selenium接管已启动的浏览器(反反爬策略)
文章目录 1、问题描述2、问题推测3、解决方法3.1 selenium自动启动浏览器3.2 selenium接管已启动的浏览器3.3 区别总结 4、代码实战4.1 手动方法(手动打开浏览器输入账号密码)4.2 自动方法(.bat文件启动的浏览器) 1、问题描述 使用…...
MPP 架构解析:原理、核心优势与对比指南
一、引言:大数据时代的数据处理挑战 全球数据量正以指数级增长。据 Statista 统计,2010 年全球数据量仅 2ZB,2025 年预计达 175ZB。企业面临的核心挑战已从“如何存储数据”转向“如何快速分析数据”。传统架构在处理海量数据时暴露明显瓶颈…...
GitHub 趋势日报 (2025年04月06日)
GitHub 趋势日报 (2025年04月06日) 本日报由 TrendForge 系统生成 https://trendforge.devlive.org/ 📈 今日整体趋势 Top 10 排名项目名称项目描述今日获星语言1microsoft/markitdownPython tool for converting files and office documents to Markdown.⭐ 548Py…...
Python设计模式-工厂模式
一、模式定义与核心思想 工厂模式(Factory Pattern)属于创建型设计模式,其核心思想是通过一个"工厂类"来创建对象,而不是直接调用类的构造函数。这种模式将对象的实例化过程封装起来,使系统在实例化对象时能…...
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,将它们联接成一排,相邻数字首尾相接,组成一个最大的整数。 输入格式 第一行有一个整数,表示数字个数 n。 第二行有 n 个整数,表示给出的 n 个整数 ai。 输出格式 一个正整…...
Server-Sent Events一种允许服务器向客户端发送实时更新的 Web API
Server-Sent Events(SSE)是一种允许服务器向客户端发送实时更新的 Web API。它基于 HTTP 协议,提供了一种单向的、服务器到客户端的通信机制,客户端可以通过监听服务器发送的事件来接收实时数据。下面从原理、使用场景、代码示例等…...
彻底解决VS2008编译错误:fatal error C1083 无法打开包括文件“stdint.h“
彻底解决VS2008编译错误:fatal error C1083 无法打开包括文件"stdint.h" 一、错误现象与本质原因 当在Visual Studio 2008中编译包含C99标准整数类型(如int8_t、uint32_t)的代码时,常出现以下编译错误: 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…...
算法题型讲解
一.双指针 主要分为俩种类型: 1.左右指针:双指针指向开头,以一定标准移动或交换,对区域进行划分,或找到特殊点的位置 (如:快慢指针判断有无环,移动零) 2.对撞指针&am…...
操作主机的管理
1.在AD林范围内,有哪几个操作主机角色 架构主机(Schema Master) 功能:负责整个AD林中所有对象和属性的定义,是唯一可以更新目录架构的DC。架构更新会从架构主机复制到目录林中的所有其他域控制器。 作用范围…...
Redis和数据库一致性问题
操作模拟 1、先更新数据库还是先更新缓存? 1.1先更新缓存,再更新数据库 按并发的角度来说,有两个线程A、B,操作同一个数据,线程A先更新缓存为1,在线程A更新数据库之前,这时候线程B进来&#…...
第R8周:RNN实现阿尔茨海默病诊断(pytorch)
>- **🍨 本文为[🔗365天深度学习训练营]中的学习记录博客** >- **🍖 原作者:[K同学啊]** 本人往期文章可查阅: 深度学习总结 一、准备工作 🏡 我的环境: 语言环境:Python3.1…...
《穿透表象,洞察分布式软总线“无形”之奥秘》
分布式系统已成为众多领域的关键支撑技术,而分布式软总线作为实现设备高效互联的核心技术,正逐渐走入大众视野。它常被描述为一条“无形”的总线,这一独特属性不仅是理解其技术内涵的关键,更是把握其在未来智能世界中重要作用的切…...
