12.2.2 ADC结构与功能
1.电源引脚
ADC电源引脚功能如图所示:
2.输入引脚
3.时序图
从上面看到:ADC在开始精确转换前需要一个稳定时间tSTAB。在开始ADC转换和14个时钟周期后, EOC标志被设置, 16位ADC数据寄存器包含转换的结果。
4. 数据对齐
ADC_CR2寄存器中的ALIGN位选择转换后数据储存的对齐方式。数据可以左对齐或右对齐。注入组通道转换的数据值已经减去了在ADC_JOFRx寄存器中定义的偏移量,因此结果可以是一个负值。SEXT位是扩展的符号值。对于规则组通道,不需减去偏移值,因此只有12个位有效。
5.校准
ADC有一个内置自校准模式。校准可大幅减小因内部电容器组的变化而造成的准精度误差。在校准期间,在每个电容器上都会计算出一个误差修正码(数字值),这个码用于消除在随后的转换中每个电容器上产生的误差。
通过设置ADC_CR2寄存器的CAL位启动校准。一旦校准结束, CAL位被硬件复位,可以开始正常转换。建议在上电时执行一次ADC校准。校准阶段结束后,校准码储存在ADC_DR中。
6. ADC转换时钟源
STM32F4系列微控制器的ADC是逐次比较逼近型,因此必须使用驱动时钟。所有ADC共用时钟ADCCLK,它来自经可编程预分频器分频的APB2时钟,该预分频器允许ADC在fPCLK2/2、fPCLK2/4、fPCLK2/6或fPCLK2/8等频率下工作。
ADCCLK最大频率为36MHz。
7. ADC转换通道
1-规则通道组:相当正常运行的程序。最多16个通道。规则通道和它的转换顺序在ADC_SQRx寄存器中选择,规则 组转换的总数 写入ADC_SQR1寄存器的L[3:0]中规则通道组共用一个转换数据寄存器!
2-注入通道组:相当于“中断”。最多4个通道。注入组和它的转换顺序在ADC_JSQR寄存器中选择。注入组里转换的总数应写入ADC_JSQR寄存器的JL[1:0]中每个注入通道都有一个独立的转换数据寄存器。
STM32F4的ADC的各通道可以①单次,②连续,③扫描或者④间断模式执行。
8. ADC转换触发源
总的来说有以下两种方式:
1)、软件触发:ADC 使能 可以由 ADC 控制寄存器 2: ADC_CR2 的 ADON 这个位来控制,写 1 的时候开始转换,写 0 的时候 停止转换,这个是最简单也是最好理解的开启 ADC 转换的控制方式。
另:(1)位SWSTART:启动规则组。(2)位JSWSTART:启动注入组
2)、外部事件触发转换:触发源有很多,具体选择哪一种触发源,由 ADC 控制寄存器2:ADC_CR2 的 EXTSEL[2:0]和JEXTSEL[2:0]位来控制。
(1)EXTSEL[2:0]用于选择规则通道的触发源;
(2)JEXTSEL[2:0]用于选择注入通道的触发源。
9. 中断
当模拟看门狗状态位和溢出状态位分别置 1 时,规则组和注入组在转换结束时可能会产生中 断。可以使用单独的中断使能位以实现灵活性
。
10.模拟看门狗
使用看门狗功能,可以限制ADC转换模拟电压的范围(低于阈值下限或高于阈值上限,定义在ADC_HTR和ADC_LTR这两个寄存器中),当转换的结果超过这一范围时,会将ADC_SR中的模拟看门狗状态位置1,如果使能了相应中断,会触发中断服务程序,以及时进行对应的处理。
11. 时钟配置
12. DMA控制
由于规则组通道只有一个ADC_DR,因此,对于多个规则组通道的转换,使用 DMA非常有帮助。
比如:
ADC1规则组转换4个输入通道信号时,需要用到DMA2的数据流0的通道0,在扫描模式下,在每个输入通道被转化结束后,都会触发DMA控制器将转换结果从规则组ADC_DR中的数据传输到定义的存储器中。
12.3 ADC典型应用步骤及常用库函数
12.3.1 ADC典型应用步骤 ◆
//ADC1为例子1-开启PA口时钟和ADC1时钟,设置PA1为模拟输入。 RCC_AHB1PeriphClockCmd (RCC_AHB1Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); GPIO_Init(); 2-初始化模拟信号输入的GPIO引脚为模拟方式: GPIO_Init();3-复位ADC1。 ADC_DeInit(ADC1);4-初始化ADC_CCR寄存器。ADC通用控制寄存器。 ADC_CommonInit();5-初始化ADC1参数,设置ADC1的工作模式以及规则序列的相关信息。void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);6-配置规则通道参数: ADC_RegularChannelConfig();7-如果要用中断,使能ADC中断,配置ADC的NVIC 。 使能ADC1的转换结束中断: ADC_ITConfig(ADC1,ADC_IT_EOC,ENABLE); 配置ADC的NVIC: NVIC_Init(); 8-使能ADC ADC_Cmd(ADC1, ENABLE); 9-开启软件转换:ADC_SoftwareStartConvCmd(ADC1); 10-等待转换完成,读取ADC值 ADC_GetConversionValue(ADC1);11-中断服务程序 void ADC_IRQHandler(void);
12.3.2 常用库函数 ◆
1、ADC通用初始化函数void ADC_CommonInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct);//这些参数用来配置ADC_CCR寄存器的相关参数 typedef struct { uint32_t ADC_Mode; //多重ADC模式选择 uint32_t ADC_Prescaler; //ADC预分频 uint32_t ADC_DMAAccessMode; //DMA访问模式 uint32_t ADC_TwoSamplingDelay; //2个采样阶段之间的延迟 }ADC_CommonInitTypeDef; 2、ADC初始化函数ADC_Initvoid ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);ADCx,可以是ADC1、ADC2等typedef struct{ uint32_t ADC_Resolution; //ADC分辨率 FunctionalState ADC_ScanConvMode; //是否使用扫描模式。ADC_CR1位8:SCAN位 FunctionalState ADC_ContinuousConvMode; //单次转换OR连续转换:ADC_CR2的位1:CONT uint32_t ADC_ExternalTrigConvEdge; //外部触发使能方式:ADC_CR2的位29:28,EXTEN uint32_t ADC_ExternalTrigConv; //触发方式:ADC_CR2的位[19:17] :EXTSEL[2:0] uint32_t ADC_DataAlign; //对齐方式:左对齐还是右对齐:ADC_CR2的位11:ALIGN uint8_t ADC_NbrOfChannel; //规则通道序列长度:ADC_SQR1的位[23:20]:L[3:0] }ADC_InitTypeDef;
例如:
3、ADC使能函数
void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);
4、 ADC使能软件转换函数
void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState)///////////////////////////////ADC_SoftwareStartConvCmd(ADC1, ENABLE);//使能ADC1的软件转换启动
5、ADC 规则通道配置函数
void ADC_RegularChannelConfig(ADC_TypeDef* ADCx,uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime); ///////////////////////////////ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_480Cycles);//把规则通道中的通道5,设置为第一个转换
6、ADC 获取转换结果函数ADC_GetConversionValue
uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);ADC_GetConversionValue(ADC1);//获取ADC1转换结果
12.4 应用实例●
请参考野火,正点原子的以及ST官方或者其他优秀的代码例程。