stm32 ADC 简介
stm32的ADC是 12位逐次逼近型 模拟数字转换器;它包括18个通道,可以用来测量16个外部通道和2个内部通道.ADC转换的结果存放在16位数据寄存器(ADC规则数据寄存器,ADC_DR 和 ADC注入数据寄存器,ADC_JDCx)中,这个数据寄存器可以设置对齐方式为左对齐或右对齐.
规则通道组和注入通道组
注入通道可打断规则通道的转换
所谓规则通道组和注入通道组其实应该就是通道的分组吧,按照OOP的思想来理解,通道组是一个基类,注入通道组和规则通道组派生自通道组这个基类,通道组这个基类中包含了一个保存各个通道的数组.
为什么要对通道进行分组呢,这个有待深究,以后再说.
ADC相关的寄存器
ADC_CR1
各个位描述如下图:
- scan位:
设置扫描模式,1为使用扫描模式,0则关闭.扫描模式下,有ADC_SQRx或ADC_JSQRx寄存器选中的通道被转换,此时如果设置了EOCIE或JEOCIE,则只有在最后一个通道转换完毕后才会产生EOC或JEOC中断 DUALMOD位:
设置ADC的操作模式,详细的看下面的来自<>截图
ADC_CR2
各个位描述如下图:
- ADON位:用于开关AD转换器
- CONT位:用于设置是否进行连续转换,使用单次转换CONT位必须设置为0.
EXTSEL[2:0]:用于选择启动规则转换组转换的外部事件
如果需要使用软件触发,就将这三个位设置为 111
ADC采样事件寄存器(ADC_SMPR1和ADC_SMPR2)
各个位描述如下图:
这两个寄存器用来设置通道0~17的采样时间,每个通道要占3位.
对于每个要转换的通道,采样时间尽量长一点,以获得较高的准确度,但是会降低ADC的转换速率.ADC的转换时间可以由以下公式计算:
Tconv = 采样时间 + 12.5周期
ADC规则序列寄存器(ADC_SQR1~3)
这几个寄存器功能都差不多,不一一详细说明了.
L[3:0]:用于存储规则序列的长度
ADC数据寄存器(ADC_DR)
这个没什么好说的,用来存放AD转换后的结果
要注意可以通过ADC_CR2的ALIGN位设置这个寄存器是左对齐还是右对齐
ADC状态寄存器(ADC_SR)
没啥好说的,保存了各种状态,看图吧.
通过库函数配置ADC1通道1进行AD转换
1.外设使能
STM32F103ZET6的ADC通道1在PA1上所以我们先要使能 PORTA的时钟 和 ADC1时钟,然后设置 PA1为模拟输入.
2.复位ADC1,同时设置ADC1的分频因子
开启了ADC1的时钟后,要复位ADC1,将ADC1的全部寄存器重设位缺省值,然后通过RCC_CFGR设置ADC1的分频因子,并且分频因子要确保ADC1的时钟不超过14MHz!
ADC复位函数:
ADC_DeInit();
设置分配因子的库函数
RCC_ADCCLKConfig(RCC_PCLK2_DIV6);
3.初始化ADC1参数,设置ADC1的工作模式以及规则序列的相关信息.
ADC初始化函数:
void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);
4.使能ADC并校准
void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);
//使能指定的ADC
void ADC_ResetCalibration(ADC_TypeDef* ADCx);
//复位校准
void ADC_StartCalibration(ADC_TypeDef* ADCx);
//执行ADC校准
while(ADC_GetResetCalibrationStatus(...));
//等待复位校准结束
while(ADC_GetCalibrationStatus(...));
//等待AD校准结束
5.设置规则序列1里面的通道,读取ADC的值
void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);
//设置规则序列通道以及采样周期
void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
//软件开启ADC转换
while(!ADC_GetFlagStatus(ADCx,ADC_FLAG_EOC));
//等待转换结束
uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);
//获取转换结果数据