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

ADC模数转换器概念函数及应用

ADC模数转换器概念函数及应用

文章目录

  • ADC模数转换器概念函数及应用
    • 1.ADC简介
    • 2.逐次逼近型ADC
      • 2.1逐次逼近型ADC
      • 2.2stm32逐次逼近型
      • 2.3ADC基本结构
      • 2.4十六个通道
    • 3.规则组的4种转换模式
      • 3.1单次转换,非扫描模式
      • 3.2连续转换,非扫描模式
      • 3.3单次转换,扫描模式
      • 3.4连续转换,扫描模式
    • 4.触发控制
    • 5.数据对齐
    • 6.转换时间
    • 7.校准(了解)
    • 8.硬件电路
    • 9.相关函数说明
      • RCC的函数
      • ADC的函数
      • 控制校准的函数
      • 软件触发的函数
      • 获取标志位状态
      • 配置间断模式
      • ADC规则组通道配置
      • ADC获取转换值
      • ADC注入组的配置(了解)
      • 模拟看门狗的配置
      • ADC温度传感器,内部电压控制
      • 标志位相关
    • 9.实操图
    • 10.AD单通道
      • 10.1接线图
      • 10.2代码编写
        • 10.2.1主程序main.c
        • 10.2.2函数定义AD.c
        • 10.2.3函数声明AD.h
    • 11.AD多通道
      • 11.1接线图
      • 11.2代码编写
        • 11.2.1主程序main.c
        • 11.2.2函数定义AD.c
        • 11.2.3函数声明AD.h
    • n.实现步骤
      • n.1ADC配置的步骤
      • n.2校准的4个步骤
    • n.实现步骤
      • n.1ADC配置的步骤
      • n.2校准的4个步骤

1.ADC简介

  • ADC(Analog-Digital Converter)模拟-数字转换器
  • ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量,建立模拟电路到数字电路的桥梁
  • 12位逐次逼近型ADC,1us转换时间
  • 输入电压范围:0~3.3V,转换结果范围:0~4095
  • 18个输入通道,可测量16个外部和2个内部信号源(16个外部就是16个GPIO口,2个内部信号源是内部温度传感器内部参考电压)
  • 规则组(常规使用)和注入组(用于突发事件)两个转换单元
  • 模拟看门狗自动监测输入电压范围
  • STM32F103C8T6 ADC资源:ADC1、ADC2,10个外部输入通道

STM32主要是数字电路,数字电路只有高低电平,没有几v电压的概念

2.逐次逼近型ADC

2.1逐次逼近型ADC

逐次逼近型

2.2stm32逐次逼近型

stm32逐次逼近型

2.3ADC基本结构

ADC基本结构

2.4十六个通道

通道ADC1ADC2ADC3
通道0PA0PA0PA0
通道1PA1PA1PA1
通道2PA2PA2PA2
通道3PA3PA3PA3
通道4PA4PA4PF6
通道5PA5PA5PF7
通道6PA6PA6PF8
通道7PA7PA7PF9
通道8PB0PB0PF10
通道9PB1PB1
通道10PC0PC0PC0
通道11PC1PC1PC1
通道12PC2PC2PC2
通道13PC3PC3PC3
通道14PC4PC4
通道15PC5PC5
通道16温度传感器
通道17内部参考电压

3.规则组的4种转换模式

EOC在规则或注入通道组结束时设置,由软件清除或由读取ADC_DR时清除

3.1单次转换,非扫描模式

单次,非扫描

3.2连续转换,非扫描模式

连续,非扫描

3.3单次转换,扫描模式

单次,扫描

3.4连续转换,扫描模式

连续扫描

4.触发控制

触发控制

5.数据对齐

  • 数据右对齐

右对齐

  • 数据左对齐

左对齐

左对齐的作用:如果不想要右对齐那么高的分辨率,0~4095数太大了,可以选择左对齐将数据的高8位取出来,舍弃后面4位的精度,将12位的ADC退化为8位的ADC

6.转换时间

  • AD转换的步骤:采样,保持,量化,编码

  • STM32 ADC的总转换时间为:

    TCONV = 采样时间 + 12.5个ADC周期

  • 例如:当ADCCLK=14MHz,采样时间为1.5个ADC周期

    TCONV = 1.5 + 12.5 = 14个ADC周期 = 1μs

量化:ADC逐次比较的过程,位数越多时间越长,

采样时间:采样保持花费的时间,采样时间越长,越能避免一些毛刺信号的干扰

12.5个ADC周期:量化编码花费的时间,因为是12位的ADC,所以需要花费12个周期

ADC周期:就是从RCC分频过来的ADCCLK

14MHz:最大,最快的转换速度

7.校准(了解)

固定过程,了解即可

  • ADC有一个内置自校准模式。校准可大幅减小因内部电容器组的变化而造成的准精度误差。校准期间,在每个电容器上都会计算出一个误差修正码(数字值),这个码用于消除在随后的转换中每个电容器上产生的误差
  • 建议在每次上电后执行一次校准
  • 启动校准前, ADC必须处于关电状态超过至少两个ADC时钟周期

8.硬件电路

硬件电路

9.相关函数说明

RCC的函数

void RCC_ADCCLKConfig(uint32_t RCC_PCLK2);
  1. void RCC_ADCCLKConfig(uint32_t RCC_PCLK2);配置ADCCLK预分频器,可以对APB2的72MHz时钟选择2、4、6、8分频,输入到ADCCLK

ADC的函数

void ADC_DeInit(ADC_TypeDef* ADCx);
void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);
void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct);
void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState);
  1. void ADC_DeInit(ADC_TypeDef* ADCx);恢复缺省配置
  2. void **ADC_Init (ADC_TypeDef ADCx, ADC_InitTypeDef ADC_InitStruct);初始化
  3. void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct);结构体初始化
  4. void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);给ADC上电的,就是开关控制
  5. void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState);用于开启DMA输出信号,使用DMA转运数据,就得调用这个函数
  6. 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);
  1. void ADC_ResetCalibration(ADC_TypeDef* ADCx);复位校准
  2. FlagStatus ADC_GetResetCalibrationStatus(ADC_TypeDef* ADCx);获取复位校准状态
  3. void ADC_StartCalibration(ADC_TypeDef* ADCx);开始校准
  4. FlagStatus ADC_GetCalibrationStatus(ADC_TypeDef* ADCx);获取开始校准状态

在ADC初始化后依次调用即可

软件触发的函数

void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx);//一般不会用到
  1. void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);用于软件触发的函数,设置SWSTART为1
  2. FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx);返回SWSTART的状态,与转换是否结束无关

获取标志位状态

FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);
  1. FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);参数给EOC的标志位判断EOC标志位是不是置1

如何判断转换是否结束:

调用ADC_GetFlagStatus函数获取标志位状态,判断EOC标志位是不是置1了,如果转换结束,EOC标志位置1,然后调用这个函数判断标志位

配置间断模式

void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number);
void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
  1. void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number);每隔几个通道间断一次
  2. void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);是不是启用间断模式

ADC规则组通道配置

void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);
  1. void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);给序列的每个位置填写指定通道,参数1ADCx,参数2ADC_Channel你想指定的通道,参数三Rank:序列几的位置(规则器中的序列),参数四SampleTime指定通道的采样时间(数值小的转换快,数值大的稳定)
void ADC_ExternalTrigConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);

  1. void ADC_ExternalTrigConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);ADC外部触发转换控制,就是是否允许外部触发转换

ADC获取转换值

uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);
uint32_t ADC_GetDualModeConversionValue(void);
  1. uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);就是获取AD转换的数据寄存器,读取转换结果就使用该函数
  2. uint32_t ADC_GetDualModeConversionValue(void);ADC获取双模式转换值,双ADC模式读取转换结果的函数

以上所有函数都是对ADC基本功能和规则组的配置

ADC注入组的配置(了解)

void ADC_AutoInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_InjectedDiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_ExternalTrigInjectedConvConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConv);
void ADC_ExternalTrigInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_SoftwareStartInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
FlagStatus ADC_GetSoftwareStartInjectedConvCmdStatus(ADC_TypeDef* ADCx);
void ADC_InjectedChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);
void ADC_InjectedSequencerLengthConfig(ADC_TypeDef* ADCx, uint8_t Length);
void ADC_SetInjectedOffset(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel, uint16_t Offset);
uint16_t ADC_GetInjectedConversionValue(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel);

模拟看门狗的配置

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);
  1. void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog);是否启动模拟看门狗
  2. void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold, uint16_t LowThreshold);配置高低阈值
  3. voidADC_AnalogWatchdogSingleChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel);配置看门的通道

ADC温度传感器,内部电压控制

void ADC_TempSensorVrefintCmd(FunctionalState NewState);
  1. 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);
  1. FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);获取标志位状态
  2. void ADC_ClearFlag(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);清楚标志位
  3. ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT);获取中断状态
  4. void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT);清除中断挂起位

9.实操图

实操图

10.AD单通道

10.1接线图

单通道

根据引脚定义表,PA0到PB1这10个引脚是ADC的10个通道,其他的引脚不是ADC引脚,不能接模拟电压

10.2代码编写

10.2.1主程序main.c
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.h"
#include "KEY.h"
#include "OLED.h"
//#include "OLED_Font.h"
#include "AD.h"

uint16_t AD_Value;
float Voltage;

int main(void){
	
	OLED_Init();
	AD_Init();
	OLED_ShowString(1,1,"ADValue:");
	OLED_ShowString(2,1,"Voltage:0.00V");
	while(1){
		AD_Value = ADC_GetValue();
		Voltage = (float)AD_Value/4095*3.3;
		OLED_ShowNum(1,9,AD_Value,4);
		//ADC值为整数,直接除不准确,所以需要强制类型转换,虽然还是有偏差
		OLED_ShowNum(2,9,Voltage,1);//显示整数部分
		OLED_ShowNum(2,11,(uint16_t)(Voltage*100)%100,2);//显示小数部分
		Delay_ms(100);
	}
}

10.2.2函数定义AD.c
#include "stm32f10x.h"                  // Device header

void AD_Init(void){
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	//开启ADC时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	//配置ADCCLK
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);//ADCCLK=72MHz/6=12MHz
	
	//GPIO初始化
	GPIO_InitTypeDef GPIO_InitStructure;
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//防止干扰模拟电压
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
 	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	//配置规则组输入通道(ADC通道,通道,序列,采样时间参数)
	ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);//这里的ADCCLK的采样时间就是55.5个ADCCLK周期
	
	//ADC初始化
	ADC_InitTypeDef ADC_InitStructure;
	ADC_InitStructure.ADC_ContinuousConvMode =ENABLE;//连续转换模式,选择连续或单次转换
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//数据对齐
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//外部触发转换选择,对应框图的左下角,None不使用外部触发,使用软件触发
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//模式选择:独立模式
	ADC_InitStructure.ADC_NbrOfChannel = 1;//通道数目,一共扫描几个通道
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;//扫描转换模式
	ADC_Init(ADC1,&ADC_InitStructure);
	
	ADC_Cmd(ADC1,ENABLE);
	
	//校准
	ADC_ResetCalibration(ADC1);//复位校准
	while(ADC_GetResetCalibrationStatus(ADC1) == SET);//复位完成后系统会自动置为0
	ADC_StartCalibration(ADC1);//开始校准
	while(ADC_GetCalibrationStatus(ADC1)==SET);
	
}

//获取ADC值
uint16_t ADC_GetValue(void){
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);//软件触发获取ADC值的函数
	//获取标志位状态
	while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET);//等待时间:采样周期55.5,转换周期固定为12.5,55.5+12.5=68,76/6=12(6分频),(1/12)*68=5.6us
	return ADC_GetConversionValue(ADC1);
}

PCLK2就是APB2时钟的意思

AIN模式下,GPIO口是无效的,断开GPIO,防止GPIO口的输入输出对模拟电压造成干扰

10.2.3函数声明AD.h
#ifndef __AD_H
#define __AD_H

void AD_Init(void);
uint16_t ADC_GetValue(void);

#endif

11.AD多通道

11.1接线图

多通道

11.2代码编写

11.2.1主程序main.c
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.h"
#include "KEY.h"
#include "OLED.h"
//#include "OLED_Font.h"
#include "AD.h"

uint8_t AD0;
uint8_t AD1;
uint8_t AD2;
uint8_t 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 = ADC_GetValue(ADC_Channel_0);
		AD1 = ADC_GetValue(ADC_Channel_1);
		AD2 = ADC_GetValue(ADC_Channel_2);
		AD3 = ADC_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);
	}
}

11.2.2函数定义AD.c

主要是在获取AD值时对通道进行修改,实现动态单通道获取多个通道

#include "stm32f10x.h"                  // Device header

void AD_Init(void){
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	//开启ADC时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	//配置ADCCLK
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);//ADCCLK=72MHz/6=12MHz
	
	//GPIO初始化
	GPIO_InitTypeDef GPIO_InitStructure;
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
 	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	
	
	//ADC初始化
	ADC_InitTypeDef ADC_InitStructure;
	ADC_InitStructure.ADC_ContinuousConvMode =ENABLE;
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
	ADC_InitStructure.ADC_NbrOfChannel = 1;
	ADC_InitStructure.ADC_ScanConvMode = DISABLE; 
	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值
uint16_t ADC_GetValue(uint8_t ADC_Channel){
	//每次都重新指定通道,来实现多通道
	ADC_RegularChannelConfig(ADC1,ADC_Channel,1,ADC_SampleTime_55Cycles5);//使用参数来修改通道
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);
	//获取标志位状态
	while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET);
	return ADC_GetConversionValue(ADC1);
}

11.2.3函数声明AD.h
#ifndef __AD_H
#define __AD_H

void AD_Init(void);
uint16_t ADC_GetValue(uint8_t ADC_Channel);

#endif

n.实现步骤

n.1ADC配置的步骤

  1. 开启RCC时钟,包括ADC和GPIO的时钟,另外。ADCCLK的分频器时钟
  2. 配置GPIO,把需要的GPIO配置成模拟输入的模式
  3. 选择规则组的输入通道
  4. 配置多路开关,把左边的通道接入右边的规则组列表里
  5. 配置ADC转换器
  6. 开关控制,调用ADC_Cmd函数,开启ADC

n.2校准的4个步骤

调用4个函数即可

  1. 复位校准
  2. 等待校准完成
  3. 开始校准
  4. 等待校准完成
    e(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET);
    return ADC_GetConversionValue(ADC1);
    }

#### 11.2.3函数声明AD.h

```c
#ifndef __AD_H
#define __AD_H

void AD_Init(void);
uint16_t ADC_GetValue(uint8_t ADC_Channel);

#endif

n.实现步骤

n.1ADC配置的步骤

  1. 开启RCC时钟,包括ADC和GPIO的时钟,另外。ADCCLK的分频器时钟
  2. 配置GPIO,把需要的GPIO配置成模拟输入的模式
  3. 选择规则组的输入通道
  4. 配置多路开关,把左边的通道接入右边的规则组列表里
  5. 配置ADC转换器
  6. 开关控制,调用ADC_Cmd函数,开启ADC

n.2校准的4个步骤

调用4个函数即可

  1. 复位校准
  2. 等待校准完成
  3. 开始校准
  4. 等待校准完

http://www.kler.cn/a/536175.html

相关文章:

  • Maven 依赖管理全面解析
  • 0008—常量和变量
  • 判断您的Mac当前使用的是Zsh还是Bash:echo $SHELL、echo $0
  • 【AI大模型】Ubuntu18.04安装deepseek-r1模型+服务器部署+内网访问
  • 20240206 adb 连不上手机解决办法
  • 【Prometheus】如何通过golang生成prometheus格式数据
  • Android 实现首页Tab切换并且支持懒加载功能详解
  • 【hadoop】隐藏 hadoop/hive/spark/fink 等日志
  • 【信息系统项目管理师】第22章:组织通用治理 详解
  • 【前端】【面试】【知识点总结】react知识点大纲
  • 云轴科技ZStack+海光DCU:率先推出DeepSeek私有化部署方案
  • 【电机控制器】STC8H1K芯片——低功耗
  • ReactNative进阶(五十九):存量 react-native 项目适配 HarmonyOS NEXT
  • Java中的按值传递和引用传递
  • 【AcWing】蓝桥杯辅导课-二分与前缀和
  • 虚基类和虚继承
  • 安卓7以上抓包证书安装
  • 2021 年 12 月青少年软编等考 C 语言五级真题解析
  • 《Kettle实操案例一(全量/增量更新与邮件发送)》
  • 深度学习-105-RAG技术之嵌入模型安装部署应用的三种方式
  • 初窥强大,AI识别技术实现图像转文字(OCR技术)
  • Mac下使用Docker安装CREMEB-PRO宝塔环境
  • 【Leetcode 每日一题】59. 螺旋矩阵 II
  • 广度优先搜索(BFS)算法详解——以走迷宫问题为例
  • 【JS】element-ui table展示勾选状态
  • AI工具——Cherry Studio,搭建满血DeepSeek R1的AI对话客户端