1、CC2530和STM32嵌入式接口技术开发5.4 STM32 ADC模数转换应用开发EducationSolutions目录ContentsInternet+ADC模数转换介绍STM32 ADC模数转换项目场景项目实践11:26/3ADC模数转换概念ADC是Analog-to-Digital Converter的缩写,指模/数转换器或者模数转换器。是指将连续变化的模拟信号转换为离散的数字信号的器件。3Bit电压转换原理(右图)11:27/4STM32的ADC模数转换介绍nSTM32F4xx系列一般都有3个ADC外设,这些ADC可以独立使用,也可以使用双重/三重模式(提高采样率)。STM32F4
2、的ADC是12位逐次逼近型的模拟数字转换器。n每个ADC有19个通道,可测量16个外部源、2个内部源和Vbat通道的信号。这些通道的A/D转换可以单次、连续、扫描或间断模式执行。ADC的结果可以左对齐或右对齐方式存储在16位数据寄存器中。11:27/5ADC模数转换基本原理1.参考电压输入范围2.模拟信号输入通道3.模拟信号转换顺序4.ADC启动转换触发源5.ADC转换时钟配置6.ADC数据存储器7.ADC相关中断源11:27/6ADC模数转换输入电压VREF-VREF+VDDAVSSAVINADC输入范围为:VREF-VINVREF+。由VREF-、VREF+、VDDA、VSSA这四个外部引
3、脚决定。在设计原理图的时候一般把VSSA和VREF-接地,把VREF+和VDDA接3V3,得到ADC的输入电压范围为:03.3V。11:27/7ADC输入通道通道号ADC1ADC2ADC3通道 0PA0PA0PA0通道 1PA1PA1PA1通道 2PA2PA2PA2通道 3PA3PA3PA3通道 4PA4PA4PF6通道 5PA5PA5PF7通道 6PA6PA6PF8通道 7PA7PA7PF9通道 8PB0PB0PF10通道 9PB1PB1PF3通道 10PC0PC0PC0通道 11PC1PC1PC1通道 12PC2PC2PC2通道 13PC3PC3PC3通道 14PC4PC4PF4通道 15
4、PC5PC5PF5STM32的ADC多达19个通道,外部通道16个ADCx_IN0.ADCx_IN5。这16个通道对应着不同的IO口,具体是哪一个IO口可以从手册查询到。11:27/8ADC转换顺序 SQR3控制着规则序列中的第一个到第六个转换,对应的位为:SQ14:0SQ64:0SQR3 SQR2控制着规则序列中的第7到第12个转换,对应的位为:SQ74:0SQ124:0SQR2 SQR1控制着规则序列中的第13到第16个转换,对应位为:SQ134:0SQ164:0SQR1在顺序转换的模式下ADC的转换可以按照设置顺序执行,若通道16想第一次转换,那么在SQ14:0写16即可。若通道1想第8
5、个转换,则SQ84:0写1即可。若通道6想第10个转换,则SQ104:0写6即可。11:27/9ADC转换触发条件 向ADC_CR2的ADON位,写1时开始转换,写0时停止转换。手动触发ADC转换 由触发源触发转换,触发源有很多,具体选择哪一种触发源,由ADC控制寄存器ADC_CR2的EXTSEL2:0和JEXTSEL2:0位来控制。外部条件触发ADC转换ADC的触发方式有两种,一种为手动触发,即向寄存器写入参数触发转换。另一种为外部条件触发,而事件触发又分为两种情况,一种是规则触发,即按顺序完成ADC转换,这种触发方式有EXTSEL控制;另一种是注入式触发,即触发时间随机,此时可能有其他AD
6、C在执行,注入式触发可以抢断执行,这种触发方式由JEXTSEL控制。11:27/10ADC转换时间 Tconv=采样时间+12个周期。ADC 的总转换时间跟 ADC的输入时钟和采样时间有关当 ADCCLK=30MHz,即 PCLK2 为 60MHz,ADC时钟为 2分频,采样时间设置为 3个周期,那么总的转换时为:Tconv=3+12=15 个周期=0.5us。11:27/11ADC转化流程 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);/使能GPIOA时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_A
7、DC1,ENABLE);/使能ADC1时钟 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AN;/模拟输入1.开启时钟和ADC时钟置,设置管脚为模拟输入 void ADC_CommonInit(ADC_CommonInitTypeDef*ADC_CommonInitStruct)2.设置ADC转换参数初始化 void ADC_Init(ADC_TypeDef*ADCx,ADC_InitTypeDef*ADC_InitStruct)3.设置ADC基本参数初始化 ADC_Cmd(ADC1,ENABLE);/开启AD转换器4.开启AD转换器 ADC_GetConver
8、sionValue(ADC1);5.读取ADC值11:27/12ADC基本参数初始化配置ADC_CommonInitStructure.ADC_Mode=ADC_Mode_Independent;/独立模式ADC_CommonInitStructure.ADC_TwoSamplingDelay=ADC_TwoSamplingDelay_5Cycles;/采样间隔ADC_CommonInitStructure.ADC_DMAAccessMode=ADC_DMAAccessMode_Disabled;/DMA禁止ADC_CommonInitStructure.ADC_Prescaler=ADC_P
9、rescaler_Div4;/ADC时钟频率4分频ADC_CommonInit(&ADC_CommonInitStructure);/初始化ADC的公共参数配置主要是四个方面,采用独立模式即使用单通道模式采集模拟信号,配置采样间隔是两次采样的时间间隔,ADC转换值的获取使用手动获取,转换频率是4分频。11:27/13ADC转换参数初始化配置ADC_InitStructure.ADC_Resolution=ADC_Resolution_12b;/12位精度模式ADC_InitStructure.ADC_ScanConvMode=DISABLE;/非扫描模式即单次转换ADC_InitStructu
10、re.ADC_ContinuousConvMode=DISABLE;/关闭连续转换/禁止触发检测,使用软件触发ADC_InitStructure.ADC_ExternalTrigConvEdge=ADC_ExternalTrigConvEdge_None;ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;/转换的数据右对齐ADC_InitStructure.ADC_NbrOfConversion=1;/1个转换在规则序列中ADC_Init(ADC1,&ADC_InitStructure);/ADC初始化ADC的转换参数初始化主要是对ADC的
11、转换精度、扫描机制、数据处理方式进行配置。11:27/14ADC读值配置流程void ADC_RegularChannelConfig(ADC_TypeDef*ADCx,uint8_t ADC_Channel,uint8_t Rank,uint8_t ADC_SampleTime);1.规则序列通道以及采样周期的设置ADC_RegularChannelConfig(ADC1,ADC_Channel_5,1,ADC_SampleTime_480Cycles);2.多路同时采用周期配置ADC_SoftwareStartConvCmd(ADC1);/使能指定的ADC1的软件转换启动功能3.软件开启A
12、DC转换ADC_GetConversionValue(ADC1);4.获取转换ADC转换结果数据ADC_GetConversionValue(ADC1);5.读取ADC值FlagStatus ADC_GetFlagStatus(ADC_TypeDef*ADCx,uint8_t ADC_FLAG);6.AD转换的状态信息设置11:27/15项目场景充电宝的电平电压为模拟量,嵌入式处理器要如何采集模拟信号呢?需要用到ADC模数转换的外设功能,电压指示器通过ADC模数转换外设将电压转化为数字化电压。本项目将围绕这个场景展开对嵌入式ADC模数转换外设的学习与开发。11:27/16任务目标使用STM32
13、处理器模拟电压检测,通过程序功能设计使用STM32处理器的ADC外设对处理器底板的电源电压进行检测,并将电压采集值转换为电压物理量。11:27/17项目分析项目中STM32F407采集的电压为电池电压,由于电池标准电压为12V远高于STM32F407的3.3V工作电压,因此电池电压需要通过相应的硬件电路进行处理,将电池电压等比例缩小到STM32F407可接受的工作电压。电池电压分压电路如图:11:27/18项目程序流程图程序设计思路是首先初始化LED和ADC相关配置。配置完成后程序进入主循环。主循环中首先通过ADC转换函数获取电源电压的转换值,再将转换值转换为电压值。延时一段时候后从新启动AD
14、C转换。11:27/19项目实现adc初始化void AdcInit(void)GPIO_InitTypeDef GPIO_InitStructure;ADC_CommonInitTypeDef ADC_CommonInitStructure;ADC_InitTypeDef ADC_InitStructure;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE);/使能GPIOC时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);/使能ADC1时钟 /先初始化ADC1通道0 IO口 GPI
15、O_InitStructure.GPIO_Pin=GPIO_Pin_0;/PC0 通道0 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AN;/模拟输入 GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;/不带上下拉 GPIO_Init(GPIOC,&GPIO_InitStructure);/初始化 11:27/20项目实现adc初始化 RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE);/ADC1复位 RCC_APB2PeriphResetCmd(RCC_APB2Per
16、iph_ADC1,DISABLE);/复位结束 ADC_CommonInitStructure.ADC_Mode=ADC_Mode_Independent;/独立模式 ADC_CommonInitStructure.ADC_TwoSamplingDelay=ADC_TwoSamplingDelay_5Cycles;/两个采样阶段之间的延迟5个时钟 ADC_CommonInitStructure.ADC_DMAAccessMode=ADC_DMAAccessMode_Disabled;/DMA失能 ADC_CommonInitStructure.ADC_Prescaler=ADC_Prescal
17、er_Div4;/预分频4分频。ADCCLK=PCLK2/4=84/4=21Mhz,ADC时钟最好不要超过36Mhz ADC_CommonInit(&ADC_CommonInitStructure);11:27/21项目实现adc初始化 ADC_InitStructure.ADC_Resolution=ADC_Resolution_12b;/12位模式 ADC_InitStructure.ADC_ScanConvMode=DISABLE;/非扫描模式 ADC_InitStructure.ADC_ContinuousConvMode=DISABLE;/关闭连续转换 ADC_InitStructu
18、re.ADC_ExternalTrigConvEdge=ADC_ExternalTrigConvEdge_None;/禁止触发检测,使用软件触发 ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;/右对齐 ADC_InitStructure.ADC_NbrOfConversion=1;/1个转换在规则序列中 也就是只转换规则序列1 ADC_Init(ADC1,&ADC_InitStructure);/ADC初始化 ADC_Cmd(ADC1,ENABLE);/开启AD转换器 11:27/22项目实现ADC转换函数u16 AdcGet(u8 c
19、h)if(ch=1)ch=ADC_Channel_10;else if(ch=2)ch=ADC_Channel_11;else if(ch=3)ch=ADC_Channel_14;else if(ch=4)ch=ADC_Channel_15;else return 0;/设置指定ADC的规则组通道,一个序列,采样时间 ADC_RegularChannelConfig(ADC1,ch,1,ADC_SampleTime_480Cycles);/ADC1,ADC通道,480个周期,提高采样时间可以提高精确度 ADC_SoftwareStartConv(ADC1);/使能指定的ADC1的软件转换启动功能 while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC);/等待转换结束 return ADC_GetConversionValue(ADC1);/返回最近一次ADC1规则组的转换结果11:27/23项目思考STM32F407有多少路ADC?生活中有哪些场景需要使用到ADC转换?