【STM32】ADC模数转换基本原理(提供完整实例代码)

发布于:2025-07-10 ⋅ 阅读:(23) ⋅ 点赞:(0)

这篇文章是嵌入式中我通过大量资料 整合成了一份 系统完整、层次清晰的 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_JSQ R注入系列寄存器
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 设置值 采样时间(周期) 说明
000 1.5 快速采样,低精度
111 239.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:CONT
  uint32_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. 复位 ADC1
    ADC_DeInit(ADC1);

    // 4. 初始化 ADC1
    ADC_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. 使能 ADC1
    ADC_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 初始化 ADC ADC_Init()
3 开启 ADC ADC_Cmd(ADC1, ENABLE)
4 校准 ADC ADC_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 软件中,函数设计是模块划分的(代码整理):

📄 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;		//翻转速度 50MHz
	
	GPIO_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 );								//使能 ADC1
	
	ADC_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);  //中断使用分组2
	
	Systick_Initerupt_Init();
	MX_EXTI0_Init();
	MX_USART1_Init(115200);
	USART1_NVIC_Init(1,1);
	MX_TIM3_PWM_Init(20000 -1, 72-1);		//周期 xx/ms
	MX_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 系列 的实现机制 涵盖 理论、硬件架构、采样机制及转换过程 的原理。

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


网站公告

今日签到

点亮在社区的每一天
去签到