一、ADC简介
STM 32有3个ADC,精度为12位,每个ADC最多有16个外部通道。其中ADC1和ADC2都是有16个通道,而ADC3只有8个外部通道。
AD
转换模式
可以是单次、连续、扫描或间断执行。
结果可以
左对齐、右对齐储存在16位的寄存器中。
AD的输入时钟不得超过14MHZ,其
时钟频率由PCLK2分频产生。
输入电压范围0-3.3V
在ADC
转化时
,又分为规则通道和注入通道。
转化顺序。
触发源
转化时间:输入时钟、采样周期、转化时间 分频因子 2/4/6/8
掌握AD需要知道的概念:
1. 单次、连续、扫描或间断执行
单次:规则组中的第一个通道在有效的规则触发后转换一次。然后 ADC 进入空闲状态,直到
下一次有效规则触发带来的下一次转换。
连续:在有效的规则触发后,规则组第一个通道将不断转换,除非,断电/复位或者更改 ADC
工作模式。
扫描:完成有效的规则通道转换后,ADC
将 运行至空闲状态,直至下一次触发到来。
间断:产生一次注入触发只会转换注入组序列的一个通道,下一次再发生注入触发
2. 转化序列:规则组和注入组
3.触发方式
4.注入组和规则组通道长度:也就是有几个注入组,几个规则组通道
时钟、采样选择、采样率、分辨率
比如说我使用过的AC78013的AD,他的AD模式也是单次、扫描、间断、连续的,但是实际工程中用的最多的也就是扫描模式了。
然后他的触发方式有软件触发和硬件触发。软件触发就是他的内部有个定时器,也就是你配置AD时候的采样点,到时间了,就会内部自动触发。还有就是外部中断触发了,比如说是定时器、PWM、IO等,定时器触发的意思是每产生一个定时器中断,ADC模块就会进行一次模数转换。
中断源有:EOC、IEOC、AD、DMA中断,EOC就是完成一个注入组采集后产生一个中断,IEOC是完成一个规则组采集后产生的中断,AD中断就是字面意思,DMA中断就是DMA转化时产生。
规则通道和注入通道就如网上所说的,可以把注入通道看做一个中断,他的优先级要比规则通道高而已,一般我们就使用规则通道。
二、代码解释
//初始化ADC
//这里我们仅以规则通道为例
//我们默认将开启通道0~3
void Adc_Init(void)
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1 , ENABLE ); //使能ADC1通道时钟
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M
//PA1 作为模拟通道输入引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚
GPIO_Init(GPIOA, &GPIO_InitStructure);
ADC_DeInit(ADC1); //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式
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_InitStruct中指定的参数初始化外设ADCx的寄存器
ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1
ADC_ResetCalibration(ADC1); //使能复位校准
while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束
ADC_StartCalibration(ADC1); //开启AD校准
while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束
// ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
}
定义两个用于初始化的结构体:
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
使能时钟,GPIOA的时钟,ADC1的时钟:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1, ENABLE );//使能ADC1通道时钟
设置ADC的输入时钟频率,预分频因子2/4/6/8,总线时钟72MHZ:
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M
配置GPIOA模式:
//PA1 作为模拟通道输入引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚
GPIO_Init(GPIOA, &GPIO_InitStructure);
复位ADC:
ADC_DeInit(ADC1); //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值
ADC模式配置:
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式
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_InitStruct中指定的参数初始化外设ADCx的寄存器
工作模式:双模式、独立模式。双模式是指,两个ADC采集一组数据,提高采样率
转化模式:连续转换、单次转换、扫描、间断执行
触发方式:软件触发、定时器触发、中断线触发
数据对齐模式:左对齐、右对齐
通道数目:1-16
所有的操作无非都是最终对寄存器的操作。
12位ADC
是一种逐次逼近型模拟数字转换器。它有多达18
个通道,可测量
16
个外部和
2
个内部信号源。各通道的A/D
转换可以单次、连续、扫描或间断模式执行。
ADC
的结果可以左对齐或右
对齐方式存储在
16
位数据寄存器中。
ADC
的输入时钟不得超过
14MHz
,它是由
PCLK2
经分频产生。
规则通道组和注入通道组。规则通道相当于你正 常运行的程序,而注入通道呢,就相当于中断。
单个ADC的扫描模式
单次转换模式:只转换一次
连续转换模式:在连续转换模式中,当前面ADC转换一结束马上就启动另一次转换。
扫描 模式:此模式用来扫描一组模拟通道。
间断 模式:
ADC操作模式:
独立模式:
注入同步模式:
规则同步模式:
双ADC的工作模式
相关寄存器:
ADC
控制寄存器(
ADC_CR1
和
ADC_CR2
)
![](https://i-blog.csdnimg.cn/blog_migrate/53ca1cf7e07c0f343d1ef6e5e816f356.png)
本章我们要使用的是独立模式,所以设置这几位为
0
就可以了。
ADC
采样事件寄存器(
ADC_SMPR1
和
ADC_SMPR2
)
![](https://i-blog.csdnimg.cn/blog_migrate/4cefda8b51102182b333176ccbce485d.png)
ADC
规则序列寄存器(
ADC_SQR1~3)
ADC 状态寄存器(ADC_SR)