STM32学习笔记(六)ADC模数转换器

该系列为笔者在学习STM32过程(主线是江科大的视频)中的记录与发散思考。

初学难免有所纰漏、错误,还望大家不吝指正,感谢~


1. ADC简介

模拟信号(如引脚上的模拟电压)通常以连续的形式存在,而计算机处理的数据必须是离散的数字信号。ADC(Analog-to-Digital Converter,模数转换器)就是将模拟信号转换为数字信号的关键组件。STM32内部集成了高性能的ADC模块,可以用于各种需要模拟信号采集的应用,如传感器数据读取、信号处理、音频采集等。

(其他信息如图)

2. 逐次逼近型ADC

逐次逼近型ADC的工作原理

  1. 比较器:将输入的模拟信号与一个逐步变化的参考信号进行比较。
  2. 逐次逼近寄存器(SAR):逐步逼近并寻找最接近输入信号的数字值,每次比较后都缩小输入信号与数字值之间的误差。
  3. 时钟控制:通过时钟控制每一步的操作,最终将模拟信号转换为一个数字值。

3. ADC框图

STM32的ADC模块具有丰富的功能,通常包括以下几个关键部分:

  • 输入通道:接收模拟信号。
  • 采样保持电路:将输入信号保持一定时间,以便ADC进行转换。
  • 逐次逼近寄存器(SAR):执行逐步逼近转换的过程。
  • 比较器:比较输入信号与参考电压。
  • 数字化输出:输出最终的数字信号。
  • 注入通道:最多可应用四条通道,寄存器可容纳四个通道的数据(完美适配( •̀ ω •́ )y,但老师说不常用=-=)
  • 规则通道:最多可应用十六条通道,但相应寄存器同时只能容纳一个通道数据(常配合DMA使用)

(这块有需要复习需要的话去再听一遍老师讲课吧 目前我还是一知半解TT)

4. ADC基本结构

STM32的ADC模块结构通常包括以下几个部分:

  • 输入通道:用于连接模拟信号。
  • 采样保持电路:负责保持输入信号的值,以便ADC完成采样。
  • 转换器:进行ADC的转换过程。
  • 数据寄存器:存储转换后的数字值。
  • 时钟源:为ADC模块提供时钟信号,决定ADC的转换速度。

(一般使用规则组就够了┗|`O′|┛ ~~)

5. 输入通道

STM32的ADC支持多个输入通道,可以接收不同来源的模拟信号。常见的输入通道包括:

  • GPIO引脚:STM32的某些GPIO引脚(如图)支持模拟输入,可以通过配置这些引脚连接外部传感器。
  • 内部通道:STM32还具有内部电压参考源、温度传感器等内部模拟信号源,可以用于系统状态监测。

6. 转换模式

STM32的ADC支持多种转换模式,主要包括:

6.1 单次转换

在单次转换模式下,ADC只进行一次转换。每次启动ADC后,它会转换一个输入信号的值,并将转换结果存储在数据寄存器中。单次转换模式适用于不需要连续采样的应用场合。

6.2 连续转换

在连续转换模式下,ADC会持续不断地进行转换。每当转换完成后,ADC会自动开始下一个转换。此模式适用于需要持续采样的应用,例如实时监测和信号处理。

6.3 扫描模式

扫描模式是一种多通道采样模式。在扫描模式下,ADC会依次对多个通道进行转换。扫描模式适用于需要采集多个信号的场合,例如多通道传感器数据读取。

6.4 非扫描模式

非扫描模式下,ADC仅采样一个通道的输入信号。该模式适用于只需要读取一个信号的应用场景。

连续转换扫描模式图如下(其他三种大家自行想象吧 ┑( ̄Д  ̄)┍)

7. 触发控制

STM32的ADC支持多种触发方式,用于控制何时启动转换。常见的触发方式包括:

  • 软件触发:通过软件命令启动转换。
  • 外部事件触发:通过外部信号(如定时器溢出、外部中断等)触发ADC转换。
  • 定时器触发:通过定时器产生的事件触发ADC转换,常用于周期性采样。

触发方式可以通过配置ADC的触发源和触发极性来进行设置。

8. 数据对齐

ADC的转换结果需要存储在数据寄存器中,STM32支持两种数据对齐方式:

  • 右对齐:转换结果的最低位对齐到数据寄存器的最低位。
  • 左对齐:转换结果的最高位对齐到数据寄存器的最高位。

右对齐是默认的对齐方式,它适用于大多数应用场景。左对齐适用于需要精确控制数据格式的应用。

9. 转换时间

ADC的转换时间取决于多个因素,包括:

  • 采样时间:用于采样信号的时间,通常由硬件配置。采样时间越长,转换的精度越高。
  • 分辨率:ADC的分辨率越高,转换时间越长。例如,12位分辨率的ADC通常需要比8位分辨率的ADC更长的转换时间。
  • 时钟频率:ADC的时钟频率决定了每个转换步骤所需的时间。

通过调整这些参数,可以在精度和速度之间找到平衡。

转换的步骤与转换时间的计算如下图(采样保持:确保在量化编码时电压不变。)(STM中为12位ADC,量化编码的时间为12个ADC周期)

10. 校准

为了提高转换的精度,STM32的ADC通常具有校准功能。通过内部的校准机制,STM32可以自动对ADC进行调整,减少误差。通常在启动ADC时会进行一次内部校准,确保转换结果的准确性。

11. 硬件电路

(课中电路图如下,了解即可)

12.代码部分

依旧附上老师写的代码(注释什么都很完善,太强啦ovo),便于复习初始化操作.

(单通道、非扫描、单次转换ADC通道初始化)

#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转换的结果
}

感谢阅读,要跟着光哦( •̀ ω •́ )✧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值