STM32标准库-ADC数模转换器

文章目录

  • 一、ADC
    • 1.1简介
    • [1. 2逐次逼近型ADC](#1. 2逐次逼近型ADC)
    • 1.3ADC框图
    • 1.4ADC基本结构
      • [1.4.1 信号 "上车点":输入模块(GPIO、温度、V_REFINT)](#1.4.1 信号 “上车点”:输入模块(GPIO、温度、V_REFINT))
      • [1.4.2 信号 "调度站":多路开关](#1.4.2 信号 “调度站”:多路开关)
      • [1.4.3 信号 "加工厂":ADC 转换器(规则组 + 注入组)](#1.4.3 信号 “加工厂”:ADC 转换器(规则组 + 注入组))
      • [1.4.4信号 "暂存柜":AD 数据寄存器](#1.4.4信号 “暂存柜”:AD 数据寄存器)
      • [1.4.5 信号 "监督员":模拟看门狗](#1.4.5 信号 “监督员”:模拟看门狗)
      • [1.4.6信号 "报警器":中断输出控制 + NVIC](#1.4.6信号 “报警器”:中断输出控制 + NVIC)
      • [1.4.7 系统 "动力源":触发控制 + RCC](#1.4.7 系统 “动力源”:触发控制 + RCC)
      • [1.4.8系统 "总开关":开关控制](#1.4.8系统 “总开关”:开关控制)
    • 1.5输入通道
    • 1.6转换模式
    • 1.7触发控制
    • 1.8数据对齐
    • 1.9转换时间
    • 1.10校准
    • 1.11硬件电路
  • 二、AD单通道
    • 2.1接线图
    • 2.2代码
    • [2.3ADC 相关 API 函数](#2.3ADC 相关 API 函数)
        • [1. 时钟配置函数](#1. 时钟配置函数)
        • [2. GPIO 配置函数](#2. GPIO 配置函数)
        • [3. ADC 配置函数](#3. ADC 配置函数)
        • [4. ADC 控制函数](#4. ADC 控制函数)
        • [5. 状态和数据读取函数](#5. 状态和数据读取函数)
    • 2.4工作现象
  • 三、AD多通道
    • 3.1接线图
    • 3.2代码
    • [3.3AD单通道未提及的关键 API](#3.3AD单通道未提及的关键 API)
        • [1. ADC 通道配置函数](#1. ADC 通道配置函数)
        • [2. 采样时间说明](#2. 采样时间说明)
        • [3. ADC 状态标志位](#3. ADC 状态标志位)
    • 3.4工作现象
        • [1. **光敏传感器(AO 接 ADC 通道,如 PA0)**](#1. 光敏传感器(AO 接 ADC 通道,如 PA0))
        • [2. **声音传感器(AO 接 ADC 通道,如 PA1)**](#2. 声音传感器(AO 接 ADC 通道,如 PA1))
        • [3. **红外避障传感器(AO 接 ADC 通道,如 PA2)**](#3. 红外避障传感器(AO 接 ADC 通道,如 PA2))
        • [4. **电位器(中间引脚接 ADC 通道,如 PA3)**](#4. 电位器(中间引脚接 ADC 通道,如 PA3))

一、ADC

1.1简介

1. 2逐次逼近型ADC

1.3ADC框图

1.4ADC基本结构

以下用更通俗的 "信号 journey(旅程)" 逻辑,拆解各模块咋连接、咋配合干活:

1.4.1 信号 "上车点":输入模块(GPIO、温度、V_REFINT)

  • GPIO(16 路):像 16 个 "小天线",能接外部五花八门的模拟信号(比如传感器电压、旋钮调节的电平 ),是最常用的信号入口。
  • 温度传感器:专门测温度,把温度变化转成电压信号,相当于 "温度→电信号" 翻译器。
  • V_REFINT:内部精准参考电压,像 "标准尺",给 ADC 转换当基准(比如转换时拿信号和它比,确定数字值 )。

这些信号要先 "排队上车",统一交给 多路开关(下面讲它的作用 )。

1.4.2 信号 "调度站":多路开关

  • 作用:当 "交通调度员",决定让哪路信号进 ADC 转换器。
  • 逻辑:比如同时有 GPIO、温度传感器的信号,它选 1 路(规则组模式)或几路(注入组模式 ),送往后边的 ADC 转换器。

1.4.3 信号 "加工厂":ADC 转换器(规则组 + 注入组)

  • 规则组(最多 16 路):常规 "生产线",按预设顺序、节奏转换信号(比如循环采集 16 路 GPIO ),适合普通、批量的转换需求。
  • 注入组(最多 4 路):"加急生产线",优先级更高!遇到紧急信号(比如关键传感器超阈值 ),能插队先转换,灵活处理特殊需求。

不管规则组还是注入组,干的事一样:把模拟信号(连续电压 )切成数字信号(0 和 1 组成的编码 )。

1.4.4信号 "暂存柜":AD 数据寄存器

  • 转换完的数字信号,得找地方 "临时存一下":
    • 规则组结果:存在 "规则结果 ×1" 里(1 组数据对应 1 个寄存器 )。
    • 注入组结果:存在 "注入结果 ×4" 里(最多存 4 组,方便快速连续处理 )。
  • 就像工厂生产完零件,先放仓库,等 CPU 来 "取货" 处理。

1.4.5 信号 "监督员":模拟看门狗

  • 作用:当 "质量检测员",盯着转换后的数字信号,看是否超出你设定的范围(比如温度不能太高 / 太低 )。
  • 触发:一旦超范围,立马发信号(相当于 "报警" ),告诉系统 "这信号有问题!"

1.4.6信号 "报警器":中断输出控制 + NVIC

  • 中断输出控制:收到模拟看门狗的 "报警" 后,整理信号,决定咋通知系统。
  • NVIC(嵌套向量中断控制器):系统的 "总调度台",收到中断信号后,暂停当前任务,优先处理 "信号异常" 事件(比如触发紧急程序、记录日志 )。

1.4.7 系统 "动力源":触发控制 + RCC

  • RCC(时钟控制器):给 ADC 整个系统提供 "心跳"(时钟信号 ),所有模块得跟着时钟节奏干活,否则会乱套。
  • 触发控制:决定啥时候启动 ADC 转换,像 "开关":可以软件手动触发(程序里写代码启动 ),也能硬件触发(比如定时器定时启动 ),发的信号叫 "START"。

1.4.8系统 "总开关":开关控制

  • 简单粗暴:控制 ADC 模块整体 "开 / 关"。不用 ADC 时,关掉省点电;要用时,打开干活。

1.5输入通道

1.6转换模式

1.7触发控制

1.8数据对齐

1.9转换时间

1.10校准

1.11硬件电路

二、AD单通道

2.1接线图

2.2代码

main.c

c 复制代码
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "AD.h"

uint16_t ADValue;			//定义AD值变量
float Voltage;				//定义电压变量

int main(void)
{
	/*模块初始化*/
	OLED_Init();			//OLED初始化
	AD_Init();				//AD初始化
	
	/*显示静态字符串*/
	OLED_ShowString(1, 1, "ADValue:");
	OLED_ShowString(2, 1, "Voltage:0.00V");
	
	while (1)
	{
		ADValue = AD_GetValue();					//获取AD转换的值
		Voltage = (float)ADValue / 4095 * 3.3;		//将AD值线性变换到0~3.3的范围,表示电压
		
		OLED_ShowNum(1, 9, ADValue, 4);				//显示AD值
		OLED_ShowNum(2, 9, Voltage, 1);				//显示电压值的整数部分
		OLED_ShowNum(2, 11, (uint16_t)(Voltage * 100) % 100, 2);	//显示电压值的小数部分
		
		Delay_ms(100);			//延时100ms,手动增加一些转换的间隔时间
	}
}

AD.c

c 复制代码
#include "stm32f10x.h"                  // Device header

/**
  * 函    数:AD初始化
  * 参    数:无
  * 返 回 值:无
  */
void AD_Init(void)
{
	/*开启时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);	//开启ADC1的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//开启GPIOA的时钟
	
	/*设置ADC时钟*/
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);						//选择时钟6分频,ADCCLK = 72MHz / 6 = 12MHz
	
	/*GPIO初始化*/
	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);					//将PA0引脚初始化为模拟输入
	
	/*规则组通道配置*/
	ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);		//规则组序列1的位置,配置为通道0
	
	/*ADC初始化*/
	ADC_InitTypeDef ADC_InitStructure;						//定义结构体变量
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;		//模式,选择独立模式,即单独使用ADC1
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;	//数据对齐,选择右对齐
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;	//外部触发,使用软件触发,不需要外部触发
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;		//连续转换,失能,每转换一次规则组序列后停止
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;			//扫描模式,失能,只转换规则组的序列1这一个位置
	ADC_InitStructure.ADC_NbrOfChannel = 1;					//通道数,为1,仅在扫描模式下,才需要指定大于1的数,在非扫描模式下,只能是1
	ADC_Init(ADC1, &ADC_InitStructure);						//将结构体变量交给ADC_Init,配置ADC1
	
	/*ADC使能*/
	ADC_Cmd(ADC1, ENABLE);									//使能ADC1,ADC开始运行
	
	/*ADC校准*/
	ADC_ResetCalibration(ADC1);								//固定流程,内部有电路会自动执行校准
	while (ADC_GetResetCalibrationStatus(ADC1) == SET);
	ADC_StartCalibration(ADC1);
	while (ADC_GetCalibrationStatus(ADC1) == SET);
}

/**
  * 函    数:获取AD转换的值
  * 参    数:无
  * 返 回 值:AD转换的值,范围:0~4095
  */
uint16_t AD_GetValue(void)
{
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);					//软件触发AD转换一次
	while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);	//等待EOC标志位,即等待AD转换结束
	return ADC_GetConversionValue(ADC1);					//读数据寄存器,得到AD转换的结果
}

2.3ADC 相关 API 函数

1. 时钟配置函数

c

运行

c 复制代码
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
  • 功能:启用或禁用 APB2 总线上的外设时钟(如 ADC1、GPIOA)。

  • 参数 :

    • RCC_APB2Periph:外设选择(如RCC_APB2Periph_ADC1RCC_APB2Periph_GPIOA)。
    • NewStateENABLEDISABLE

c

运行

c 复制代码
void RCC_ADCCLKConfig(uint32_t RCC_PCLK2);
  • 功能:配置 ADC 时钟分频(ADC 时钟必须 ≤ 14MHz)。

  • 参数 :

    • RCC_PCLK2:分频选项(如RCC_PCLK2_Div6表示 72MHz/6=12MHz)。
2. GPIO 配置函数

c

运行

c 复制代码
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
  • 功能:初始化 GPIO 引脚。

  • 参数 :

    • GPIOx:GPIO 端口(如GPIOA)。
    • GPIO_InitStruct:GPIO 配置结构体(模式、引脚、速度)。
3. ADC 配置函数

c

运行

c 复制代码
void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);
  • 功能:配置规则组通道的转换顺序和采样时间。

  • 参数 :

    • ADCx:ADC 外设(如ADC1)。
    • ADC_Channel:通道号(如ADC_Channel_0对应 PA0)。
    • Rank:序列位置(1~16)。
    • ADC_SampleTime:采样周期(如ADC_SampleTime_55Cycles5)。

c

运行

c 复制代码
void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);
  • 功能:初始化 ADC 参数。

  • 参数 :

    • ADCx:ADC 外设。
    • ADC_InitStruct:ADC 配置结构体(模式、对齐方式、触发方式等)。
4. ADC 控制函数

c

运行

c 复制代码
void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);
  • 功能:启用或禁用 ADC。

  • 参数 :

    • ADCx:ADC 外设。
    • NewStateENABLEDISABLE

c

运行

c 复制代码
void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
  • 功能:软件触发 ADC 转换。

  • 参数 :

    • ADCx:ADC 外设。
    • NewStateENABLE触发一次转换。

c

运行

c 复制代码
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 校准流程(复位校准、获取复位状态、开始校准、获取校准状态)。
5. 状态和数据读取函数

c

运行

c 复制代码
FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);
  • 功能 :检查 ADC 标志位状态(如转换完成标志ADC_FLAG_EOC)。

  • 参数 :

    • ADCx:ADC 外设。
    • ADC_FLAG:标志位类型。

c

运行

c 复制代码
uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);
  • 功能:获取 ADC 转换结果(0~4095,12 位分辨率)。

  • 参数 :

    • ADCx:ADC 外设。
      AD.h
c 复制代码
#ifndef __AD_H
#define __AD_H

void AD_Init(void);
uint16_t AD_GetValue(void);

#endif

2.4工作现象

  1. 初始化阶段
    • 调用AD_Init()后,ADC1 时钟开启,GPIOA 引脚配置为模拟输入模式,规则组通道 0(PA0)完成配置,ADC 进入就绪状态。
    • 校准过程中,ADC_ResetCalibrationADC_StartCalibration会触发内部校准电路工作,校准完成后标志位自动清除。
  2. 转换阶段
    • 调用AD_GetValue()时,软件触发转换(ADC_SoftwareStartConvCmd),ADC_FLAG_EOC标志位在转换完成后置 1,返回值在 0~4095 范围内(对应输入电压 0~3.3V)。
    • 若输入电压稳定(如接固定电阻分压),多次读取的 ADC 值波动较小(通常≤±3LSB)。
  3. 数据对应关系

三、AD多通道

3.1接线图

3.2代码

main.c

c 复制代码
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "AD.h"

uint16_t AD0, AD1, AD2, AD3;	//定义AD值变量

int main(void)
{
	/*模块初始化*/
	OLED_Init();				//OLED初始化
	AD_Init();					//AD初始化
	
	/*显示静态字符串*/
	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);		//单次启动ADC,转换通道0
		AD1 = AD_GetValue(ADC_Channel_1);		//单次启动ADC,转换通道1
		AD2 = AD_GetValue(ADC_Channel_2);		//单次启动ADC,转换通道2
		AD3 = AD_GetValue(ADC_Channel_3);		//单次启动ADC,转换通道3
		
		OLED_ShowNum(1, 5, AD0, 4);				//显示通道0的转换结果AD0
		OLED_ShowNum(2, 5, AD1, 4);				//显示通道1的转换结果AD1
		OLED_ShowNum(3, 5, AD2, 4);				//显示通道2的转换结果AD2
		OLED_ShowNum(4, 5, AD3, 4);				//显示通道3的转换结果AD3
		
		Delay_ms(100);			//延时100ms,手动增加一些转换的间隔时间
	}
}

AD.c

c 复制代码
#include "stm32f10x.h"                  // Device header

/**
  * 函    数:AD初始化
  * 参    数:无
  * 返 回 值:无
  */
void AD_Init(void)
{
	/*开启时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);	//开启ADC1的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//开启GPIOA的时钟
	
	/*设置ADC时钟*/
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);						//选择时钟6分频,ADCCLK = 72MHz / 6 = 12MHz
	
	/*GPIO初始化*/
	GPIO_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);					//将PA0、PA1、PA2和PA3引脚初始化为模拟输入
	
	/*不在此处配置规则组序列,而是在每次AD转换前配置,这样可以灵活更改AD转换的通道*/
	
	/*ADC初始化*/
	ADC_InitTypeDef ADC_InitStructure;						//定义结构体变量
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;		//模式,选择独立模式,即单独使用ADC1
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;	//数据对齐,选择右对齐
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;	//外部触发,使用软件触发,不需要外部触发
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;		//连续转换,失能,每转换一次规则组序列后停止
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;			//扫描模式,失能,只转换规则组的序列1这一个位置
	ADC_InitStructure.ADC_NbrOfChannel = 1;					//通道数,为1,仅在扫描模式下,才需要指定大于1的数,在非扫描模式下,只能是1
	ADC_Init(ADC1, &ADC_InitStructure);						//将结构体变量交给ADC_Init,配置ADC1
	
	/*ADC使能*/
	ADC_Cmd(ADC1, ENABLE);									//使能ADC1,ADC开始运行
	
	/*ADC校准*/
	ADC_ResetCalibration(ADC1);								//固定流程,内部有电路会自动执行校准
	while (ADC_GetResetCalibrationStatus(ADC1) == SET);
	ADC_StartCalibration(ADC1);
	while (ADC_GetCalibrationStatus(ADC1) == SET);
}

/**
  * 函    数:获取AD转换的值
  * 参    数:ADC_Channel 指定AD转换的通道,范围:ADC_Channel_x,其中x可以是0/1/2/3
  * 返 回 值:AD转换的值,范围:0~4095
  */
uint16_t AD_GetValue(uint8_t ADC_Channel)
{
	ADC_RegularChannelConfig(ADC1, ADC_Channel, 1, ADC_SampleTime_55Cycles5);	//在每次转换前,根据函数形参灵活更改规则组的通道1
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);					//软件触发AD转换一次
	while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);	//等待EOC标志位,即等待AD转换结束
	return ADC_GetConversionValue(ADC1);					//读数据寄存器,得到AD转换的结果
}

AD.h

c 复制代码
#ifndef __AD_H
#define __AD_H

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

#endif

3.3AD单通道未提及的关键 API

除了之前提到的 ADC API,这段代码还涉及以下未详细说明的函数:

1. ADC 通道配置函数

c

运行

c 复制代码
void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);
  • 功能:配置规则组序列中的通道及其采样时间。

  • 参数 :

    • ADC_Channel:通道号(如ADC_Channel_0~ADC_Channel_17)。
    • Rank:序列位置(1~16,单通道模式下固定为 1)。
    • ADC_SampleTime:采样周期(如ADC_SampleTime_55Cycles5)。
2. 采样时间说明

ADC 采样时间影响转换精度和速度,可选值包括:

c

运行

c 复制代码
ADC_SampleTime_1Cycles5   // 1.5个ADC时钟周期(最快)
ADC_SampleTime_7Cycles5   // 7.5个周期
ADC_SampleTime_13Cycles5  // 13.5个周期
ADC_SampleTime_28Cycles5  // 28.5个周期
ADC_SampleTime_41Cycles5  // 41.5个周期
ADC_SampleTime_55Cycles5  // 55.5个周期
ADC_SampleTime_71Cycles5  // 71.5个周期
ADC_SampleTime_239Cycles5 // 239.5个周期(最慢,抗干扰最强)
3. ADC 状态标志位

c

运行

c 复制代码
FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);
  • 常用标志位 :

    • ADC_FLAG_EOC:规则组转换完成标志(代码中使用)。
    • ADC_FLAG_AWD:模拟看门狗触发标志(需额外配置)。
    • ADC_FLAG_OVR:数据溢出标志(连续转换模式下可能出现)。

3.4工作现象

  • 初始化后 :ADC1 和 GPIOA 时钟开启,PA0~PA3 配置为模拟输入模式,ADC 处于就绪状态但未开始转换(需调用AD_GetValue()触发)。

  • 动态通道选择 :每次调用AD_GetValue(channel)时,会临时配置规则组序列 1 为指定通道(如ADC_Channel_2对应 PA2),然后触发单次转换。

  • 转换结果

    :返回值范围为 0~4095,对应输入电压 0~3.3V(假设 VREF 为 3.3V)。例如:

    • 输入 1.65V → 返回值约为 2048(1.65V/3.3V × 4095 ≈ 2048)。
    • 输入悬空(无信号)→ 返回随机值(受噪声影响)。
1. 光敏传感器(AO 接 ADC 通道,如 PA0)
  • 现象 :

    • 光照越强(如手电筒照射),ADC 值 越大(对应电压越高,假设传感器输出与光照正相关);
    • 光照越弱(手遮挡),ADC 值 越小,OLED / 串口数据同步变化。
  • 原理:光敏电阻阻值随光照变化,转换为电压信号被 ADC 采集。

2. 声音传感器(AO 接 ADC 通道,如 PA1)
  • 现象 :

    • 安静时,ADC 值 稳定在低范围(背景噪声小);
    • 拍手 / 说话时,ADC 值 瞬间跳升(声音越强,跳升幅度越大),数据波动明显。
  • 原理:咪头采集声波,转换为电压波动,ADC 捕捉瞬时变化。

3. 红外避障传感器(AO 接 ADC 通道,如 PA2)
  • 现象 :

    • 无遮挡时,ADC 值 接近最大值(红外反射强,输出电压高);
    • 手靠近遮挡时,ADC 值 骤降(反射弱,电压低),响应迅速。
  • 原理:红外发射 + 接收,距离 / 遮挡影响反射强度,转换为电压变化。

4. 电位器(中间引脚接 ADC 通道,如 PA3)
  • 现象 :

    • 顺时针旋转:ADC 值 从 0→4095 线性递增(或递减,取决于接线方向);
    • 逆时针旋转:ADC 值 反向递减 / 递增,变化平滑无跳变。
  • 原理:电位器分压,输出电压与旋转角度线性相关。

相关推荐
passer__jw7671 小时前
【51单片机】2. 进阶点灯大师
单片机·51单片机
Immortals_wang2 小时前
MCU Keil中支持的变量类型和定义方法
单片机·嵌入式硬件
胡Jason2 小时前
GPIO_Analog与ADC什么区别
单片机·嵌入式硬件
Fang_pi_dai_zhi2 小时前
经典的多位gpio初始化操作
单片机·嵌入式硬件
技术流浪者3 小时前
PCB设计实践(三十五)STM32与ESP32的核心应用场景及选型
嵌入式硬件·硬件工程·pcb设计
Jack153027682794 小时前
GC1808:高性能音频ADC的卓越之选
单片机·嵌入式硬件·音视频·医疗器械·电动工具·家电产品
NEWEVA__zzera225 小时前
在写外部FLASH的应用时发现一些问题,在这里分享一下我的想法
c语言·经验分享·单片机
hlpinghcg5 小时前
CanFestival移植到STM32G4
stm32·canopen
passer__jw7676 小时前
【51单片机】1. 基础点灯大师
单片机·51单片机
WIZnet 中国社区官方博客6 小时前
第十六章 I2C
嵌入式硬件·wiznet·高性能以太网单片机·w55mh32·单片机外设·i2c通讯·i2c主从模式