STM32笔记-AD模数转换

目录

一、ADC介绍

二、ADC主要特征

三、ADC框图

[1. ​​​​ 外部触发转换 ​](#1. 外部触发转换)

[2. 转换模式](#2. 转换模式)

[3. 输入通道](#3. 输入通道)

[4. 逻辑框图](#4. 逻辑框图)

四、校准

五、数据对齐

六、AD转换步骤

七、AD_Init(单通道AD转换)初始化函数配置

一、ADC介绍

  1. 12位ADC是一种逐次逼近型模拟数字转换器。它有多达18个通道,可测量16个外部和2个内部信号源。

2. ADC的输入时钟不得超过14MHz,它是由PCLK2经分频产生的。

cpp 复制代码
void RCC_ADCCLKConfig(uint32_t RCC_PCLK2)
/*RCC_PCLK2: defines the ADC clock divider. This clock is derived from the APB2 clock (PCLK2).*/
//eg:
RCC_ADCCLKConfig(RCC_PCLK2_Div6);//选择时钟6分频,ADCCLK = 72MHz / 6 = 12MHz

但是需要注意的是,如下图,ADCCLK最大14MHz。

二、ADC主要特征

  1. ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量,建立模拟电路到数字电路的桥梁

  2. 12位逐次逼近型ADC,1us转换时间

3. 输入电压范围:0~3.3V,转换结果范围:0~4095

  1. 18个输入通道,可测量16个外部和2个内部信号源

  2. 规则组和注入组两个转换单元

  3. 模拟看门狗自动监测输入电压范围

三、ADC框图

1. ​​​​ 外部触发转换 2. 转换模式

单次转换模式下,ADC只执行一次转换。该模式既可通过设置ADC_CR2寄存器的ADON位(只适用于规则通道)启动也可通过外部触发启动(适用于规则通道或注入通道),这时CONT位为0。 一旦选择通道的转换完成。

在连续转换模式中,当前面ADC转换一结束马上就启动另一次转换。此模式可通过外部触发启动或通过设置ADC_CR2寄存器上的ADON位启动,此时CONT位是1。

总的来说就是:单次模式、连续模式:ADC单通道要求进行一次ADC转换时配置为单次模式使能,这样ADC的这个通道转换一次后就停止转换。要求进行连续ADC转换时配置为连续模式使能,这样ADC的这个通道转换一次后接着进行下一次。 扫描模式:对应多个ADC通道的情况,每个通道依次进行转换。

3. 输入通道

|--------|----------|----------|----------|
| 通道 | ADC1 | ADC2 | ADC3 |
| 通道0 | PA0 | PA0 | PA0 |
| 通道1 | PA1 | PA1 | PA1 |
| 通道2 | PA2 | PA2 | PA2 |
| 通道3 | PA3 | PA3 | PA3 |
| 通道4 | PA4 | PA4 | PF6 |
| 通道5 | PA5 | PA5 | PF7 |
| 通道6 | PA6 | PA6 | PF8 |
| 通道7 | PA7 | PA7 | PF9 |
| 通道8 | PB0 | PB0 | PF10 |
| 通道9 | PB1 | PB1 | |
| 通道10 | PC0 | PC0 | PC0 |
| 通道11 | PC1 | PC1 | PC1 |
| 通道12 | PC2 | PC2 | PC2 |
| 通道13 | PC3 | PC3 | PC3 |
| 通道14 | PC4 | PC4 | |
| 通道15 | PC5 | PC5 | |
| 通道16 | 温度传感器 | | |
| 通道17 | 内部参考电压 | | |

4. 逻辑框图

规则组最多转换16通道,注入组最多转换4通道,但是规则通道为"一次可以点16个菜,但是一次只能上一个菜",因为规则通道的数据寄存器仅仅为16位,而注入通道为"一次可以点4个菜,但一次可以最多上4个菜"。

四、校准

ADC有一个内置自校准模式。校准可大幅减小因内部电容器组的变化而造成的准精度误差。在校准期间,在每个电容器上都会计算出一个误差修正码(数字值),这个码用于消除在随后的转换中每个电容器上产生的误差。特别需要注意:建议在每次上电后执行一次校准。简单说,这就是个固定流程,stm32要求这么处理:

示例代码如下:

cpp 复制代码
    ADC_ResetCalibration(ADC1);				//固定流程,内部有电路会自动执行校准
	while (ADC_GetResetCalibrationStatus(ADC1) == SET);
	ADC_StartCalibration(ADC1);
	while (ADC_GetCalibrationStatus(ADC1) == SET);

五、数据对齐

左对齐与右对齐

六、AD转换步骤

采样、保持、量化、编码

ADC总转换时间:TCONV = 采样时间+ 12.5个周期

例如: 当ADCCLK=14MHz,采样时间为1.5周期 TCONV = 1.5 + 12.5 = 14周期 = 1μs

为什么需要保持?

因为AD转换中量化、编码需要一定的转换时间,在这个时间内输入电压如果还在不断变化,那么就无法定位电压,所以往往在量化编码前引入采样开关,比如通过加入一个小的电容来存储电压。

七、AD_Init(单通道AD转换)初始化函数配置

1.使能外设时钟:开启ADC1的时钟、开启GPIO的时钟

2.设置ADC的时钟,选择时钟分频

cpp 复制代码
    /*开启时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);	//开启ADC1的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//开启GPIOA的时钟
	
	/*设置ADC时钟*/
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);	

3.规则组通道配置

cpp 复制代码
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);

4.GPIO初始化、ADC初始化配置:

cpp 复制代码
    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);
cpp 复制代码
/*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

5.ADC使能

6.ADC校准

cpp 复制代码
    /*ADC使能*/
	ADC_Cmd(ADC1, ENABLE);									//使能ADC1,ADC开始运行
	
	/*ADC校准*/
	//先将ADC1校准功能恢复到默认值,然后再初始化ADC1。
	ADC_ResetCalibration(ADC1);								//固定流程,内部有电路会自动执行校准
	while (ADC_GetResetCalibrationStatus(ADC1) == SET);
	ADC_StartCalibration(ADC1);
	while (ADC_GetCalibrationStatus(ADC1) == SET);

AD多通道转换只需修改通道配置即可:

EOC:转换结束位,该位由硬件在规则或者注入通道组转换结束时置1,由软件清除或者读取数据寄存器后自动清除,那么等待EOC标志位置1即等待AD转换完成。

cpp 复制代码
/**
  * 函    数:获取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转换的结果
}
相关推荐
weixin_4526006922 分钟前
【青牛科技】电流模式PWM控制器系列--D4870
科技·单片机·嵌入式硬件·音视频·智能电表·白色家电电源·机顶盒电源
嵌新程3 小时前
day06(单片机高级)PCB设计
单片机·嵌入式硬件·pcb
stm 学习ing4 小时前
FPGA 第十讲 避免latch的产生
c语言·开发语言·单片机·嵌入式硬件·fpga开发·fpga
LateBloomer7777 小时前
FreeRTOS——信号量
笔记·stm32·学习·freertos
wenchm8 小时前
细说STM32单片机DMA中断收发RTC实时时间并改善其鲁棒性的另一种方法
stm32·单片机·嵌入式硬件
编码追梦人9 小时前
如何实现单片机的安全启动和安全固件更新
单片机
电子工程师UP学堂9 小时前
电子应用设计方案-16:智能闹钟系统方案设计
单片机·嵌入式硬件
飞凌嵌入式9 小时前
飞凌嵌入式T113-i开发板RISC-V核的实时应用方案
人工智能·嵌入式硬件·嵌入式·risc-v·飞凌嵌入式
blessing。。11 小时前
I2C学习
linux·单片机·嵌入式硬件·嵌入式
嵌新程12 小时前
day03(单片机高级)RTOS
stm32·单片机·嵌入式硬件·freertos·rtos·u575