ADC(Analog-Digital Converter)模拟-数字转换器
将外部的模拟信号转换为数字信号 ( ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量,建立模拟电路到数字电路的桥梁 )
- 12位逐次逼近型ADC,1us转换时间(其他类型:积分型、逐次逼近型、并行比较型/串并行型、sigma_delta调制型、电容阵列逐次比较型及压频变换型。)
- 输入电压范围:0~3.3V,转换结果范围:0~4095
- 18个输入通道,可测量16个外部和2个内部信号源
- 规则组和注入组两个转换单元 模拟看门狗自动监测输入电压范围
- STM32F103C8T6 ADC资源:ADC1、ADC2,10个外部输入通道
输入时钟
ADC功能描述
转换时间
由于ADC在STM32中是挂载在APB2总线上的,所以ADC的时钟是由PCLK2(72MHz)经过分频得到的,可以是 2/4/6/8 分频,一般配置分频因子为6或者8,6分频得到ADC的输入时钟频率为12MHz ,8分频得到ADC的输入时钟频率为9MHz。
AD转换的步骤:采样,保持,量化,编码
STM32 ADC的总转换时间为:
- TCONV = 采样时间 + 12.5个ADC周期
- 例如:当ADCCLK=14MHz,采样时间为1.5个ADC周期
- TCONV = 1.5 + 12.5 = 14个ADC周期 = 1μs
规则通道与注入通道
我们上面说了ADC模块有16个外部通道,若是一个通道有输入信号那么我们可以不用管那么多直接进行转换,但是当我们有多个通道有输入信号需要进行转换怎么办?转换的顺序是什么?
在STM32中把这16个外部通道分为规则通道和注入通道,在规则通道里进行规则转换,在注入通道里进行注入转换。
规则通道
按照给定的转换顺序进行转换。一个规则转换组最多由 16 个转换构成。理解相当于菜单,可以点一堆菜,菜单报道到规则通道数据寄存器后得一个菜一个菜做,通过DMA转运,依次做菜。
注入通道
由多达4个转换组成。注入通道和它们的转换顺序在ADC_JSQR寄存器中选择。注入组里的转换总数目应写入ADC_JSQR寄存器的中。理解相当这是VIP,虽然通道少,但是注入通道数据寄存器多。这意味这每个字节数据传进无需等待,无需像规则组那样等待DMA转运。
触发模式
ADC 的触发转换有两种方法:分别是通过 软件 或 外部事件 触发转换。
- 软件触发事件可以通过对寄存器ADC_CR2的SWSTART或JSWSTART位置’1’产生。写 1 就开始转换,写 0 就停止转换。
- 外部事件触发如果设置了EXTTRIG控制位,则外部事件就能够触发转换。
数据对齐
SEXT位是扩展的符号值
校准
ADC有一个内置自校准模式。
- 校准可大幅减小因内部电容器组的变化而造成的准精度误差。
- 校准期间,在每个电容器上都会计算出一个误差修正码(数字值),这个码用于消除在随后的转换中
- 每个电容器上产生的误差 建议在每次上电后执行一次校准
- 启动校准前, ADC必须处于关电状态超过至少两个ADC时钟周期
转换模式
单次转换模式
- 转换数据被储存在16位ADC_DR寄存器中
- EOC(转换结束)标志被设置
- 如果设置了EOCIE,则产生中断。
连续转换模式
- 转换数据被储存在16位的ADC_DR寄存器中
- EOC(转换结束)标志被设置
- 如果设置了EOCIE,则产生中断。
扫描模式
基本结构
初始化代码
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);
}
推荐博文:详细配置标准库
配置 Hal库
本站资源均来自互联网,仅供研究学习,禁止违法使用和商用,产生法律纠纷本站概不负责!如果侵犯了您的权益请与我们联系!
转载请注明出处: 免费源码网-免费的源码资源网站 » STM32中ADC笔记
发表评论 取消回复