这篇文章是嵌入式中我通过大量资料 整合成了一份 系统完整、层次清晰的 ADC 模数转换原理解析 文档。

这里系统地梳理了 STM32F1 系列 ADC 模数转换的核心资料,包括:

1.原理 + 特性
2.通道配置
3.模式选择(单次/连续/扫描)
4.关键寄存器与时序
5.全套库函数调用方式
6.提供示例实验代码

📘 STM32F1 系列 ADC 模数转换原理详解

参考资料:
STM32F1xx官方资料:《STM32中文参考手册V10》-第11章 模拟/数字转换(ADC)

🧩 第一部分:STM32 ADC 基本原理
什么是 ADC?

ADC(Analog to Digital Converter) 是一种将模拟电压信号转换为数字信号的模块。在 STM32 中,ADC 是片上外设,可将 03.3V 的电压转换为 12 位数值(04095)。

ADC 指模/数转换器或者模拟/数字转换器。是指将连续变量的模拟信号转换为离散的数字信号的器件。

典型的模拟数字转换器将模拟信号转换为表示一定比例电压值的数字信号。

为什么需要 ADC?

因为 MCU(如 STM32)只能处理 数字信号(0 和 1),而现实世界中的信号多数是连续的模拟量,如:

模拟信号数字处理需求
温度需要转换为数字量
电压需要转为数字量
光照强度数字化后进行计算
电流数字化后保护电路
ADC 的基本工作过程

🎯 模拟信号 → 数字值:

  • 将输入电压 VIN 转换为一个 数字码值,范围为 0 ~ 2ⁿ - 1,其中 n 为 ADC 的分辨率。
  • 例如在 STM32F1 中,ADC 是 12 位,所以:
    • 数字范围:0 ~ 4095(2¹² - 1)
    • 输入范围:VREF- ~ VREF+(一般为 0V ~ 3.3V)

STM32F10x ADC特点:

12位逐次逼近型的模拟数字转换器。
最多带3个ADC控制器
最多支持18个通道,可最多测量16个外部和2个内部信号源。
支持单次和连续转换模式
转换结束,注入转换结束,和发生模拟看门狗事件时产生中断。
通道0到通道n的自动扫描模式
自动校准
采样间隔可以按通道编程
规则通道和注入通道均有外部触发选项
转换结果支持左对齐或右对齐方式存储在16位数据寄存器
ADC转换时间:最大转换速率 1us。(最大转换速度为1MHz,在ADCCLK=14M,采样周期为1.5个ADC时钟下得到。)
ADC供电要求:2.4V-3.6V
ADC输入范围:VREF- ≤ VIN ≤ VREF+

电压转换公式

V = (ADC_Value / 4096.0) * Vref

假设 Vref = 3.3V,ADC_Value = 2048:则

V = 2048 / 4096 * 3.3 = 1.65V
特性描述
转换精度12位(0~4095)
架构逐次逼近型(SAR)
控制器个数最多 3 个(ADC1~ADC3)
通道数量最多 18 个(16个外部 + 温度 + VREF)
模式单次 / 连续 / 扫描 / 注入
对齐方式左对齐 / 右对齐
校准功能支持自动校准
时钟要求ADCCLK ≤ 14MHz

🧩 第二部分:通道与引脚对应关系(如下图示)
STM32F10x大容量芯片带3个ADC控制器

在这里插入图片描述
其中144脚芯片因为带PF脚,所以多5个通道,为21个外部通道。小于144脚芯片只有16个外部通道。

【转换通道结构】
通道类型		最大通道数		特点
规则通道		16 个			正常顺序转换
注入通道		4 个			类似中断处理,可打断规则通道
内部通道		2 个			温度(ch16)、VREF(ch17)
STM32F10x系列芯片ADC通道和引脚对应关系

在这里插入图片描述

ADC引脚

在这里插入图片描述

ADC 模块框图(ADC 寄存器结构 + 模式)

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

ADC的模块包含:输入多路选择器模拟至数字转换器(SAR)控制逻辑(触发、注入/规则选择)数据寄存器(ADC_DR、JDRx)状态寄存器(ADC_SR)

📦 核心模块说明:

模块功能
多路复用器(MUX)选择当前要转换的通道
采样保持电路暂存输入电压,稳定后再转换
SAR ADC逐次逼近型 ADC,12 位精度
控制器控制转换模式、触发方式、通道顺序等
数据缓冲存储转换结果(ADC_DR)
STM32通道组

规则通道组: 相当正常运行的程序。最多16个通道。
规则通道和它的转换顺序在ADC_SQRx寄存器中选择,规则组转换的总数应写入ADC_SQR1寄存器的 L[3:0] 中。
注入通道组: 相当于中断。最多4个通道。
注入组和它的转换顺序在ADC_JSQR寄存器中选择。注入组里转化的总数应写入ADC_JSQR寄存器的 L[1:0] 中。

在这里插入图片描述
STM32F1的ADC的各通道可以单次,连续,扫描或者间断模式执行。


🧩 第三部分:模式选择(单次/连续/扫描)
转换模式:
模式描述
单次转换(Single)一次启动 → 一次转换,手动触发
连续转换(Continuous)自动重复转换,同一通道
扫描模式(Scan)多通道自动轮询
注入模式(Injected)类似中断方式,打断规则组转换
软件触发SWSTART 启动(程序调用触发)
外部触发定时器、外部引脚等外设触发(EXTSEL)
单次转化 VS 连续转换

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

扫描模式

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

ADC中断

在这里插入图片描述

ADC时钟配置
RCC_ADCCLKConfig(RCC_PCLK2_Div6); 

在这里插入图片描述

不要让ADC时钟超过14MHz,否则可能不准。


🧩 第四部分:关键寄存器与时序
📌 ADC 核心寄存器说明(简表)
寄存器作用
ADC_CR1模式选择,扫描模式使能,EOC中断
ADC_CR2启动控制、触发源、数据对齐、CONT
ADC_SQRx通道顺序配置
ADC_SMPRx通道采样时间配置
ADC_JSQR注入系列寄存器
ADC_DR转换结果数据寄存器
ADC_JDR注入通道数据寄存器
ADC_SR状态标志(EOC、AWD等)
ADC_CR1寄存器

在扫描模式下,由ADC_SQRx或者ADC_JSQRx寄存器选中的通道被转换。如果设置了EOCIE或者JEOCIE,在最后一个通道转换完毕后才会产生EOC或者JEOC中断。

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

ADC_CR2寄存器

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

数据对齐方式:
在这里插入图片描述

ADC_SMPR1寄存器

在这里插入图片描述

ADC_SMPR2寄存器

在这里插入图片描述

ADC的采样时间:
在这里插入图片描述
最小采样时间1us(ADC时钟=14MHz,采样周期为1.5周期下得到)

采样时间(Sample Time)选择:

SMPx 设置值采样时间(周期)说明
0001.5快速采样,低精度
111239.5高阻抗信号推荐

总转换时间 = 采样周期 + 12.5 周期


ADC 对输入电压采样的时间长度,单位为 ADC 时钟周期(如 1.5 周期、7.5 周期等)。
采样时间越长:精度越高、可适配输入阻抗大的传感器。

ADC 采样时间建议:

采样时间必须根据输入阻抗、电压变化速度、ADC 时钟等参数合理选择。

采样周期建议用途
1.5 周期高频快速采样,精度低,输入阻抗需小
71.5 周期推荐默认
239.5 周期输入阻抗高/慢信号更稳
✅ 示例:读取 PA1 电压值
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
ADC_GPIO_Init(); // PA1 模拟输入
ADC1_SingleChannel_Init();ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5);
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
uint16_t value = ADC_GetConversionValue(ADC1);
float voltage = (value / 4096.0f) * 3.3f;

ADC_SQRx:ADC_SQR1/SQR2/SQR3规则序列寄存器

在这里插入图片描述

ADC_JSQR注入系列寄存器

在这里插入图片描述

ADC_DR规则通道数据寄存器

在这里插入图片描述

ADC_JDR注入通道数据寄存器

在这里插入图片描述

ADC_SR状态寄存器

在这里插入图片描述

配置流程
🧾 1. RCC 时钟设置

ADC 时钟不能超 14MHz,推荐如下设置:

RCC_ADCCLKConfig(RCC_PCLK2_Div6); // 72MHz/6 = 12MHz
🧾 2. ADC 初始化结构体
ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
🧾 3. 通道配置 + 采样时间
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5);
通道按 Rank 顺序决定转换顺序
采样时间越长,精度越高,输入阻抗越能适应
🧾 4. 启动转换流程
// 开启ADC
ADC_Cmd(ADC1, ENABLE);// 校准
ADC_ResetCalibration(ADC1);
while (ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while (ADC_GetCalibrationStatus(ADC1));// 软件启动转换
ADC_SoftwareStartConvCmd(ADC1, ENABLE);// 等待完成
while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));// 读取结果
uint16_t value = ADC_GetConversionValue(ADC1);

🧩 第五部分:全套库函数调用方式
常用库函数
void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);
void ADC_DeInit(ADC_TypeDef* ADCx)
void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState);
void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);
uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);void ADC_ResetCalibration(ADC_TypeDef* ADCx);
FlagStatus ADC_GetResetCalibrationStatus(ADC_TypeDef* ADCx);
void ADC_StartCalibration(ADC_TypeDef* ADCx);
FlagStatus ADC_GetCalibrationStatus(ADC_TypeDef* ADCx);
函数功能
ADC_Init()初始化结构体配置
ADC_Cmd()启用 ADC
ADC_ResetCalibration() / StartCalibration()复位校准 / 启用校准
ADC_SoftwareStartConvCmd()软件触发
ADC_RegularChannelConfig()配置通道顺序与采样时间
ADC_SoftwareStartConvCmd()启动转换(软件)
ADC_GetConversionValue()获取转换结果(12位)
(右对齐/左对齐)
ADC初始化函数ADC_Init
void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);
typedef struct
{uint32_t ADC_Mode;//ADC模式:配置ADC_CR1寄存器的位[19:16]  :DUALMODE[3:0]位FunctionalState ADC_ScanConvMode; //是否使用扫描模式。ADC_CR1位8:SCAN位 FunctionalState ADC_ContinuousConvMode; //单次转换OR连续转换:ADC_CR2的位1:CONTuint32_t ADC_ExternalTrigConv;  //触发方式:ADC_CR2的位[19:17] :EXTSEL[2:0]                uint32_t ADC_DataAlign;   //对齐方式:左对齐还是右对齐:ADC_CR2的位11:ALIGN         uint8_t ADC_NbrOfChannel;//规则通道序列长度:ADC_SQR1的位[23:20]: L[3:0]       
}ADC_InitTypeDef;
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式ADC_InitStructure.ADC_ScanConvMode = DISABLE;	//不开启扫描 
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//单次转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//触发软件 
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//ADC数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1;//顺序进行规则转换的ADC通道的数目
ADC_Init(ADC1, &ADC_InitStructure);	
ADC使能函数 ADC_Cmd();
void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);
ADC_Cmd(ADC1, ENABLE);	//使能指定的ADC1
ADC使能软件转换函数 ADC_SoftwareStartConvCmd
void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx,FunctionalState NewState);
ADC_SoftwareStartConvCmd(ADC1, ENABLE);//使能ADC1的软件转换启动
ADC 规则通道配置函数ADC_RegularChannelConfig
void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5 );
ADC 获取转换结果函数ADC_GetConversionValue
uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);
ADC_GetConversionValue(ADC1);//获取ADC1转换结果

🧩 第六部分:这是一个完整的 STM32F103 系列 ADC 实验代码
🎯 实验目标

使用 ADC1 的通道1(PA1)
采用 单次转换模式
软件触发转换,读取电压值
将 ADC 值输出到串口或用作其他逻辑判断

项目条件:
模拟输入范围VREF- ≤ VIN ≤ VREF+(默认 VSSA~VDDA)
分辨率:12 位,转换结果范围:0 ~ 4095
输入引脚:通道 1 → PA1
模式:单次转换、软件触发、右对齐
时钟要求:ADC 时钟 ≤ 14MHz,推荐 RCC_ADCCLKConfig(RCC_PCLK2_Div6)
数据读取方式:轮询 ADC_SR.EOC 位,或使用中断(本例使用轮询)

📦 使用外设:

ADC1
GPIOA(PA1)
RCC(时钟配置)

#include "stm32f10x.h"// 延时函数(用于测试)
void delay_ms(uint32_t ms)
{SysTick->LOAD = 72000 - 1;SysTick->VAL = 0;SysTick->CTRL = 0x5;while (ms--){while (!(SysTick->CTRL & (1 << 16)));}SysTick->CTRL = 0;
}// UART 打印函数可自行添加// 初始化 PA1 为模拟输入
void ADC_GPIO_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef gpio;gpio.GPIO_Pin = GPIO_Pin_1;gpio.GPIO_Mode = GPIO_Mode_AIN; // 模拟输入GPIO_Init(GPIOA, &gpio);
}// 配置 ADC1 通道1
void ADC1_SingleChannel_Init(void)
{// 1. 开启 ADC1 时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);// 2. 设置 ADC 时钟分频(PCLK2/6 = 12MHz)RCC_ADCCLKConfig(RCC_PCLK2_Div6);// 3. 复位 ADC1ADC_DeInit(ADC1);// 4. 初始化 ADC1ADC_InitTypeDef adc;adc.ADC_Mode = ADC_Mode_Independent;               // 独立模式adc.ADC_ScanConvMode = DISABLE;                    // 禁用扫描adc.ADC_ContinuousConvMode = DISABLE;              // 单次转换adc.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; // 软件触发adc.ADC_DataAlign = ADC_DataAlign_Right;           // 右对齐adc.ADC_NbrOfChannel = 1;                          // 仅一个通道ADC_Init(ADC1, &adc);// 5. 使能 ADC1ADC_Cmd(ADC1, ENABLE);// 6. 复位校准ADC_ResetCalibration(ADC1);while (ADC_GetResetCalibrationStatus(ADC1));// 7. 启动校准ADC_StartCalibration(ADC1);while (ADC_GetCalibrationStatus(ADC1));
}// 读取 ADC1 通道1 的电压值(0~4095)
uint16_t ADC1_Read_PA1(void)
{// 1. 配置规则通道:ADC1, 通道1, 第1个转换,采样时间 239.5周期ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5);// 2. 软件触发转换ADC_SoftwareStartConvCmd(ADC1, ENABLE);// 3. 等待转换完成(EOC 置位)while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));// 4. 读取转换结果return ADC_GetConversionValue(ADC1);
}int main(void)
{SystemInit();ADC_GPIO_Init();ADC1_SingleChannel_Init();uint16_t adc_value;while (1){adc_value = ADC1_Read_PA1(); // 读取ADC值(0~4095)// 比如输出到串口,或控制LED亮灭// printf("ADC Value = %d\r\n", adc_value);delay_ms(500);}
}
ADC 寄存器与控制流程(以规则通道为例)(初始化流程图)

流程(简化版):

模拟输入  →  采样保持电路  →  SAR ADC(12位)  →  数据寄存器(ADC_DR)↑                    |通道选择器(MUX)    控制逻辑(触发、扫描、注入)
RCC 配置 ADC 时钟
↓
GPIO 配置为模拟输入
↓
ADC_Init() 初始化结构体
↓
ADC 校准(ResetCalibration + StartCalibration)
↓
ADC 配置通道 + 采样时间
↓
启动转换(软件/外部)
↓
等待 EOC 标志
↓
读取 ADC_DR 寄存器

总结 ADC 配置过程要点

步骤操作对应函数或寄存器
1设置时钟分频RCC_ADCCLKConfig(RCC_PCLK2_Div6)
2初始化 ADCADC_Init()
3开启 ADCADC_Cmd(ADC1, ENABLE)
4校准 ADCADC_Reset/StartCalibration()
5配置通道ADC_RegularChannelConfig()
6软件触发ADC_SoftwareStartConvCmd()
7等待转换完成ADC_FLAG_EOC
8获取数据ADC_GetConversionValue()

结果转换公式:

// 假设参考电压为 3.3V
float voltage = adc_value * 3.3 / 4096;

实验完整代码(标准库实现)(模块化)

因为在 Keil 软件中,函数设计是模块划分的(代码整理):

实验目的:ADC1的通道1(PA1)进行单次转化

流程:
① 开启PA口时钟和ADC1时钟,设置PA1为模拟输入。
GPIO_Init();
APB2PeriphClockCmd();
② 复位ADC1,同时设置ADC1分频因子。
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
ADC_DeInit(ADC1);
③ 初始化ADC1参数,设置ADC1的工作模式以及规则序列的相关信息。
void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);
④ 使能ADC并校准。
ADC_Cmd(ADC1, ENABLE);
⑤ 配置规则通道参数:
ADC_RegularChannelConfig();
⑥开启软件转换:ADC_SoftwareStartConvCmd(ADC1);
⑦等待转换完成,读取ADC值。
ADC_GetConversionValue(ADC1);

📄 adc.h

#ifndef _ADC_H_
#define _ADC_H_#include "stm32f10x.h"
#include <stdio.h>void MX_ADC_Init(void);uint16_t Get_ADC(ADC_TypeDef* ADCx, uint8_t ADC_Channel);#endif

📄 adc.c

#include "adc.h"void MX_ADC_Init(void)
{//-------------------------------------GPIO Init---------------------------------------//GPIO_InitTypeDef GPIO_InitStruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_ADC1, ENABLE);GPIO_InitStruct.GPIO_Mode 	= GPIO_Mode_AIN;			//配置为模拟输入GPIO_InitStruct.GPIO_Pin 		= GPIO_Pin_0;					//配置 0 管脚GPIO_InitStruct.GPIO_Speed 	= GPIO_Speed_50MHz;		//翻转速度 50MHzGPIO_Init(GPIOC, &GPIO_InitStruct);GPIO_WriteBit(GPIOC, GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9, Bit_SET);//-------------------------------------GPIO Init---------------------------------------//RCC_ADCCLKConfig(RCC_PCLK2_Div6);		//设置ADC时钟 6 分频ADC_InitTypeDef ADC_InitStruct;ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;										//不使用连续转换ADC_InitStruct.ADC_DataAlign					= ADC_DataAlign_Right;				//ADC 数据右对齐ADC_InitStruct.ADC_ExternalTrigConv   = ADC_ExternalTrigConv_None;	//转换由软件而不是外部触发启动ADC_InitStruct.ADC_Mode								=	ADC_Mode_Independent;				//ADC1 和 ADC2 工作在独立模式ADC_InitStruct.ADC_NbrOfChannel				= 1;													//仅使用了通道10。规定了顺序进行规则转换的 ADC 通道的数目。这个数目的取值范围是 1 到 16。ADC_InitStruct.ADC_ScanConvMode				=	DISABLE;										//不使用扫描模式ADC_Init( ADC1, &ADC_InitStruct);ADC_Cmd( ADC1, ENABLE );								//使能 ADC1ADC_ResetCalibration( ADC1 );						//重置指定的 ADC 的校准寄存器while(ADC_GetResetCalibrationStatus( ADC1 ) == SET ){};   //等待校准完成 --ADC 重置校准寄存器的新状态(SET 或者 RESET)ADC_StartCalibration( ADC1 );						//开启校准while(ADC_GetCalibrationStatus( ADC1 ) == SET){};	//等待校准完成}uint16_t Get_ADC(ADC_TypeDef* ADCx, uint8_t ADC_Channel)
{ADC_RegularChannelConfig( ADCx, ADC_Channel, 1, ADC_SampleTime_239Cycles5);	//配置好ADC的规则通道ADC_SoftwareStartConvCmd( ADCx, ENABLE);	//开启ADC转换while(ADC_GetSoftwareStartConvStatus( ADCx ) == SET){};	//等待转换完成return ADC_GetConversionValue( ADCx );
}

📄 main.c

/********************************************************************************* @file    Project/STM32F10x_StdPeriph_Template/main.c * @author  MCD Application Team* @version V3.5.0* @date    08-April-2011* @brief   Main program body******************************************************************************* @attention** THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.** <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>*******************************************************************************/  /* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "stdio.h"
#include "gpio.h"
#include "systick.h"
#include "exti.h"
#include "usart.h"
#include "string.h"
#include "wdg.h"
#include "tim.h"
#include "pwm.h"
#include "adc.h"int main()
{
//	uint16_t Compare2 = 0;
//	bool Dir = 0;uint32_t ADC1_ts = 0;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //中断使用分组2Systick_Initerupt_Init();MX_EXTI0_Init();MX_USART1_Init(115200);USART1_NVIC_Init(1,1);MX_TIM3_PWM_Init(20000 -1, 72-1);		//周期 xx/msMX_ADC_Init();printf("System Init OK! \r\n");while(1){Get_ADC(ADC1, ADC_Channel_10);if(GetTick() - ADC1_ts > 500){ADC1_ts = GetTick();printf("ADC = %d \r\n", Get_ADC(ADC1, ADC_Channel_10));}}
}/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

在这里插入图片描述

以上,便是 ADC(模数转换器)基本原理 的系统性说明,结合 STM32F1 系列 的实现机制 涵盖 理论、硬件架构、采样机制及转换过程 的原理。

以上,欢迎有从事同行业的电子信息工程、互联网通信、嵌入式开发的朋友共同探讨与提问,我可以提供实战演示或模板库。希望内容能够对你产生帮助!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/913786.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/913786.shtml
英文地址,请注明出处:http://en.pswp.cn/news/913786.shtml

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

相关文章

图神经网络 gnn 应用到道路网络拓扑结构与交通碳排放相关性。,拓扑指标量化、时空关联模型及演化机制分析

针对您提出的“道路网络拓扑结构与交通碳排放相关框架&#xff0c;以下结合研究目标、数据与方法进行系统性深化设计&#xff0c;重点强化拓扑指标量化、时空关联模型及演化机制分析&#xff1a;一、核心研究问题深化 静态关联&#xff1a;不同拓扑结构&#xff08;方格网/环射…

7.6 优先队列| dijkstra | hash | rust

lc1337pair存入&#xff0c;lambda sort后取出&#xff0c;最开始想用hash&#xff0c;写一半感觉写复杂了class Solution {public:vector<int> kWeakestRows(vector<vector<int>>& mat, int k) {int m mat.size();int n mat[0].size();vector<pair…

最新 HarmonyOS API 20 知识库 重磅推出

最新 HarmonyOS API 20 知识库 重磅推出 前言 最近整理下 华为开发者联盟最新的 API 20的鸿蒙应用开发文档&#xff0c;这次的API 20 相比较之前的文档&#xff0c;要多了不少内容&#xff0c;目前整理后是9000千多篇&#xff0c;不容易呀。 如何使用 基于腾讯的知识库工具 …

uniapp 监听物理返回按钮

import {onShow,onHide,onLoad,onReady,onBackPress} from "dcloudio/uni-app"onBackPress((e) > {showLog("返回按钮触发")if(e.frombackbutton){//开始干活}})参数说明属性类型说明fromString触发返回行为的来源&#xff1a;backbutton——左上角导航…

多线程(2)

多线程&#xff08;2&#xff09; &#x1f534;&#x1f7e0;&#x1f7e1;&#x1f7e2;&#x1f535;&#x1f7e3;&#x1f534;&#x1f534;&#x1f7e0;&#x1f7e1;&#x1f7e2;&#x1f535;&#x1f7e3;&#x1f534;&#x1f534;&#x1f7e0;&#x1f7e1;&am…

网关助力航天喷涂:Devicenet与Modbus TCP的“跨界对话“

在航空航天领域&#xff0c;飞机、航天器的制造过程有着极高的精度与安全性要求。以飞机、航天器表面喷涂作业为例&#xff0c;不仅要进行严格的防腐蚀处理&#xff0c;而且对表面光滑度要求极高&#xff0c;这直接关系到飞行器的空气动力学性能和使用寿命。为确保作业安全与质…

从传统项目管理到敏捷DevOps:如何转向使用DevOps看板工具进行工作流管理

在DevOps实践中&#xff0c;DevOps看板工具成为了开发与运维团队之间高效协作的关键。随着企业对敏捷开发和持续交付的需求日益增长&#xff0c;DevOps看板工具通过可视化的管理方法&#xff0c;帮助团队在繁杂的任务中保持高效的工作节奏和清晰的进度跟踪。 具体而言&#xff…

【leetcode100】下一个排列

1、题目描述 整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。 例如&#xff0c;arr [1,2,3] &#xff0c;以下这些都可以视作 arr 的排列&#xff1a;[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。 整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。更正…

Flink-Source算子状态恢复分析

背景 修改 source 算子 kafka_old_topic 消费任务运行一段时间后&#xff0c;暂停状态并保留。然后将 uid 和 topic 都改了&#xff0c;消费者 offset 会从 earliest 开始。 // before FlinkKafkaConsumer consumer KafkaConfig.getConsumer("kafka_old_topic");…

IDEA中application.yml配置文件不自动提示解决办法

今天在自己的电脑上使用IDEA的时候&#xff0c;发现在application配置文件里面输入配置项的时候没有提示&#xff0c;网上找了一圈也没解决&#xff0c;最后自己试出来了。 解决办法&#xff1a; 鼠标移动到配置文件上&#xff0c;单击右键-重写文件类型、选择YAML(捆绑)&#…

Vite 完整功能详解与 Vue 项目实战指南

Vite 完整功能详解与 Vue 项目实战指南 Vite 是下一代前端开发工具&#xff0c;由 Vue 作者尤雨溪开发&#xff0c;提供极速的开发体验和高效的生产构建。以下是完整功能解析和实战示例&#xff1a;一、Vite 核心功能亮点闪电般冷启动 基于原生 ES 模块&#xff08;ESM&#xf…

Vue 3 中使用路由参数跳转时 watch 触发重复请求问题详解

&#x1f4d8;Vue 3 中使用路由参数跳转时 watch 触发重复请求问题详解&#x1f516; 收藏 点赞 关注&#xff0c;掌握 Vue 3 路由参数监听中的隐藏陷阱&#xff0c;避免详情页、嵌套路由页误触发重复请求&#xff01;&#x1f9e9; 一、问题背景 在 Vue 3 项目中&#xff0c…

前端 项目更新通知 (plugin-web-update-notification)

项目版本更新迭代时&#xff0c;需提示用户更新系统&#xff0c;不然早时间不更新对用户体验很不好&#xff0c;所以在每次部署后需要提示用户&#xff0c;刷新静态资源。推荐插件 plugin-web-update-notification .具体配置 vite.config.js文件中 import { webUpdateNotice …

【力扣(LeetCode)】数据挖掘面试题0002:当面对实时数据流时您如何设计和实现机器学习模型?

文章大纲一、实时数据处理&#xff1a;构建低延迟的数据管道1. 数据接入与缓冲2. 实时清洗与校验3. 特征标准化与对齐二、模型设计&#xff1a;选择适配实时场景的模型架构1. 模型选择原则三、训练与更新策略&#xff1a;离线与在线协同&#xff0c;应对概念漂移1. 离线-在线协…

TongWeb8.0.9.0.3部署后端应用,前端访问后端报405(by sy+lqw)

问题描述&#xff1a; 客户前端部署在nginx上&#xff0c;后端部署在tongweb8上&#xff08;相当于前后端分离&#xff09;&#xff0c;登录的时候报错&#xff0c;f12看network&#xff0c;状态码405&#xff0c;如下所示&#xff1a;看console&#xff0c;如下所示&#xff1…

mysql互为主从失效,重新同步

一、分别登录服务器A和服务器B的mysqlmysql -u root -p 123456789二、分别查看数据库状态信息,下边两项参数有一项为NO就表示同步异常Slave_IO_Running:从服务器&#xff08;Slave&#xff09;中的 I/O 线程的运行状态Slave_SQL_Running:从服务器上的 SQL 线程是否正在运行mysq…

板凳-------Mysql cookbook学习 (十一--------6)

https://blog.csdn.net/weixin_43236925/article/details/146382981 清晰易懂的 PHP 安装与配置教程 12.6 查找每组行中含有最大或最小值的行 mysql> set max_price (select max(price) from painting); Query OK, 0 rows affected (0.01 sec)mysql> select artist.name…

ECS由浅入深第四节:ECS 与 Unity 传统开发模式的结合?混合架构的艺术

ECS由浅入深第一节 ECS由浅入深第二节 ECS由浅入深第三节 ECS由浅入深第四节 ECS由浅入深第五节 尽管 ECS 带来了显著的性能和架构优势&#xff0c;但在实际的 Unity 项目中&#xff0c;完全摒弃 GameObject 和 MonoBehaviour 往往是不现实的。Unity 引擎本身的大部分功能&…

Mac关闭触控板

打开 “有鼠标或无线触控板时忽略内建触控板”选项即可 参考&#xff1a;Mac如何关闭触控板防止误触&#xff1f;内置的设置就可以达成 - Mac天空

Python:Rich 终端富文本与界面样式工具库

🖌️ 1、简述 Rich 是一个强大的 Python 库,用于在终端中呈现富文本和精美的格式,让命令行界面(CLI)应用拥有现代、美观的输出效果。本文将深入介绍 Rich 的核心功能,并通过一系列实际示例展示其强大能力。 Rich 由 Will McGugan 开发,主要特点包括: 丰富的文本样式:支…