【正点原子探索者STM32F407开发板例程连载+教学】第23章 ADC模数转换实验

2019-07-20 14:39发布

第二十三章 ADC实验

       [mw_shl_code=c,true] 1.硬件平台:正点原子探索者STM32F407开发板 2.软件平台:MDK5.1 3.固件库版本:V1.4.0 [/mw_shl_code]
本章我们将向大家介绍STM32F4ADC功能。在本章中,我们将使用STM32F4ADC1通道5来采样外部电压值,并在TFTLCD模块上显示出来。本章将分为如下几个部分: 23.1 STM32F4 ADC简介 23.2 硬件设计 23.3 软件设计 23.4 下载验证  

23.1 STM32F4 ADC简介

STM32F4xx系列一般都有3ADC,这些ADC可以独立使用,也可以使用双重/三重模式(提高采样率)。STM32F4ADC12位逐次逼近型的模拟数字转换器。它有19个通道,可测量16个外部源、2个内部源和Vbat通道的信号。这些通道的A/D转换可以单次、连续、扫描或间断模式执行。ADC的结果可以左对齐或右对齐方式存储在16位数据寄存器中。 模拟看门狗特性允许应用程序检测输入电压是否超出用户定义的高/低阀值。 STM32F407ZGT6包含有3ADCSTM32F4ADC最大的转换速率为2.4Mhz,也就是转换时间为1us(在ADCCLK=36M,采样周期为3ADC时钟下得到),不要让ADC的时钟超过36M,否则将导致结果准确度下降。 STM32F4ADC的转换分为2个通道组:规则通道组和注入通道组。规则通道相当于你正常运行的程序,而注入通道呢,就相当于中断。在你程序正常执行的时候,中断是可以打断你的执行的。同这个类似,注入通道的转换可以打断规则通道的转换, 在注入通道被转换完成之后,规则通道才得以继续转换。 通过一个形象的例子可以说明:假如你在家里的院子内放了5个温度探头,室内放了3个温度探头;你需要时刻监视室外温度即可,但偶尔你想看看室内的温度;因此你可以使用规则通道组循环扫描室外的5个探头并显示AD转换结果,当你想看室内温度时,通过一个按钮启动注入转换组(3个室内探头)并暂时显示室内温度,当你放开这个按钮后,系统又会回到规则通道组继续检测室外温度。从系统设计上,测量并显示室内温度的过程中断了测量并显示室外温度的过程,但程序设计上可以在初始化阶段分别设置好不同的转换组,系统运行中不必再变更循环转换的配置,从而达到两个任务互不干扰和快速切换的结果。可以设想一下,如果没有规则组和注入组的划分,当你按下按钮后,需要从新配置AD循环扫描的通道,然后在释放按钮后需再次配置AD循环扫描的通道。 上面的例子因为速度较慢,不能完全体现这样区分(规则通道组和注入通道组)的好处,但在工业应用领域中有很多检测和监视探头需要较快地处理,这样对AD转换的分组将简化事件处理的程序并提高事件处理的速度。 STM32F4ADC的规则通道组最多包含16个转换,而注入通道组最多包含4个通道。关于这两个通道组的详细介绍,请参考《STM32F4xx中文参考手册》第250页,第11.3.3节。 STM32F4ADC可以进行很多种不同的转换模式,这些模式在《STM32F4xx中文参考手册》的第11章也都有详细介绍,我们这里就不在一一列举了。我们本章仅介绍如何使用规则通道的单次转换模式。 STM32F4ADC在单次转换模式下,只执行一次转换,该模式可以通过ADC_CR2寄存器的ADON位(只适用于规则通道)启动,也可以通过外部触发启动(适用于规则通道和注入通道),这时CONT位为0 以规则通道为例,一旦所选择的通道转换完成,转换结果将被存在ADC_DR寄存器中,EOC(转换结束)标志将被置位,如果设置了EOCIE,则会产生中断。然后ADC将停止,直到下次启动。 接下来,我们介绍一下我们执行规则通道的单次转换,需要用到的ADC寄存器。第一个要介绍的是ADC控制寄存器(ADC_CR1ADC_CR2)。ADC_CR1的各位描述如图23.1.1所示:
 23.1.1 ADC_CR1寄存器各位描述 这里我们不再详细介绍每个位,而是抽出几个我们本章要用到的位进行针对性的介绍,详细的说明及介绍,请参考《STM32F4xx中文参考手册》第11.13.2节。 ADC_CR1SCAN位,该位用于设置扫描模式,由软件设置和清除,如果设置为1,则使用扫描模式,如果为0,则关闭扫描模式。在扫描模式下,由ADC_SQRxADC_JSQRx寄存器选中的通道被转换。如果设置了EOCIEJEOCIE,只在最后一个通道转换完毕后才会产生EOCJEOC中断。 ADC_CR1[25:24]用于设置ADC的分辨率,详细的对应关系如图23.1.2所示:  23.1.2 ADC分辨率选择 本章我们使用12位分辨率,所以设置这两个位为0就可以了。接着我们介绍ADC_CR2,该寄存器的各位描述如图23.1.3所示:  23.1.3 ADC_CR2寄存器各位描述 该寄存器我们也只针对性的介绍一些位:ADON位用于开关AD转换器。而CONT位用于设置是否进行连续转换,我们使用单次转换,所以CONT位必须为0ALIGN用于设置数据对齐,我们使用右对齐,该位设置为0 EXTEN[1:0]用于规则通道的外部触发使能设置,详细的设置关系如图23.1.4所示:  23.1.4 ADC规则通道外部触发使能设置 我们这里使用的是软件触发,即不使用外部触发,所以设置这2个位为0即可。ADC_CR2SWSTART位用于开始规则通道的转换,我们每次转换(单次转换模式下)都需要向该位写1 第二个要介绍的是ADC通用控制寄存器(ADC_CCR),该寄存器各位描述如图23.1.5所示:  23.1.5 ADC_CCR寄存器各位描述 该寄存器我们也只针对性的介绍一些位:TSVREFE位是内部温度传感器和Vrefint通道使能位,内部温度传感器我们将在下一章介绍,这里我们直接设置为0ADCPRE[1:0]用于设置ADC输入时钟分频,00~11分别对应2/4/6/8分频,STM32F4ADC最大工作频率是36Mhz,而ADC时钟(ADCCLK)来自APB2APB2频率一般是84Mhz,所以我们一般设置ADCPRE=01,即4分频,这样得到ADCCLK频率为21MhzMULTI[4:0]用于多重ADC模式选择,详细的设置关系如图23.1.6所示:  23.1.6 多重ADC模式选择设置        本章我们仅用了ADC1(独立模式),并没用到多重ADC模式,所以设置这5个位为0即可。 第三个要介绍的是ADC采样时间寄存器(ADC_SMPR1ADC_SMPR2),这两个寄存器用于设置通道0~18的采样时间,每个通道占用3个位。ADC_SMPR1的各位描述如图23.1.7所示:                               23.1.7 ADC_SMPR1寄存器各位描述 ADC_SMPR2的各位描述如下图23.1.8所示:  23.1.8 ADC_SMPR2寄存器各位描述 对于每个要转换的通道,采样时间建议尽量长一点,以获得较高的准确度,但是这样会降低ADC的转换速率。ADC的转换时间可以由以下公式计算:                                 Tcovn=采样时间+12个周期 其中:Tcovn为总转换时间,采样时间是根据每个通道的SMP位的设置来决定的。例如,当ADCCLK=21Mhz的时候,并设置3个周期的采样时间,则得到:Tcovn=3+12=15个周期=0.71us 第四个要介绍的是ADC规则序列寄存器(ADC_SQR1~3,该寄存器总共有3个,这几个寄存器的功能都差不多,这里我们仅介绍一下ADC_SQR1,该寄存器的各位描述如图23.1.9所示:  23.1.9  ADC_ SQR1寄存器各位描述 L[30]用于存储规则序列的长度,我们这里只用了1个,所以设置这几个位的值为0。其他的SQ13~16则存储了规则序列中第13~16个通道的编号(0~18)。另外两个规则序列寄存器同ADC_SQR1大同小异,我们这里就不再介绍了,要说明一点的是:我们选择的是单次转换,所以只有一个通道在规则序列里面,这个序列就是SQ1,至于SQ1里面哪个通道,完全由用户自己设置,通过ADC_SQR3的最低5位(也就是SQ1)设置。 第五个要介绍的是ADC规则数据寄存器(ADC_DR)。规则序列中的AD转化结果都将被存在这个寄存器里面,而注入通道的转换结果被保存在ADC_JDRx里面。ADC_DR的各位描述如图23.1.10  23.1.10  ADC_ JDRx寄存器各位描述 这里要提醒一点的是,该寄存器的数据可以通过ADC_CR2ALIGN位设置左对齐还是右对齐。在读取数据的时候要注意。 最后一个要介绍的ADC寄存器为ADC状态寄存器(ADC_SR),该寄存器保存了ADC转换时的各种状态。该寄存器的各位描述如图23.1.11所示:                                     23.1.11  ADC_ SR寄存器各位描述 这里我们仅介绍将要用到的是EOC位,我们通过判断该位来决定是否此次规则通道的AD转换已经完成,如果该位位1,则表示转换完成了,就可以从ADC_DR中读取转换结果,否则等待转换完成。 至此,本章要用到的ADC相关寄存器全部介绍完毕了,对于未介绍的部分,请大家参考《STM32F4xx中文参考手册》第11章相关章节。通过以上介绍,我们了解了STM32F4的单次转换模式下的相关设置,接下来我们介绍使用库函数来设置ADC1的通道5来进行AD转换的步骤,这里需要说明一下,使用到的库函数分布在stm32f4xx_adc.c文件和stm32f4xx_adc.h文件中。下面讲解其详细设置步骤: 1)开启PA口时钟和ADC1时钟,设置PA5为模拟输入。 STM32F407ZGT6ADC1通道5PA5上,所以,我们先要使能GPIOA的时钟,然后设置PA5为模拟输入。同时我们要把PA5复用为ADC,所以我们要使能ADC1时钟。 这里特别要提醒,对于IO口复用为ADC我们要设置模式为模拟输入,而不是复用功能,也不需要调用GPIO_PinAFConfig函数来设置引脚映射关系。 使能GPIOA时钟和ADC1时钟都很简单,具体方法为:   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟   RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //使能ADC1时钟 初始化GPIOA5为模拟输入,方法也多次讲解,关键代码为:   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入     这里需要说明一下,ADC的通道与引脚的对应关系在STM32F4的数据手册可以查到,我们这里使用ADC1的通道5,在数据手册中的表格为:  23.1.12 ADC1通道5对应引脚查看表 这里我们把ADC1~ADC3的引脚与通道对应关系列出来, 16个外部源的对应关系如下表: 通道号 ADC1 ADC2 ADC3 通道0 PA0 PA0 PA0 通道1 PA1 PA1 PA1 通道2 PA2 PA2 PA2 通道3 PA3 PA3 PA3 通道4 PA4 PA4 PF6 通道5 PA5 PA5 PF7 通道6 PA6 PA6 PF8 通道7 PA7 PA7 PF9 通道8 PB0 PB0 PF10 通道9 PB1 PB1 PF3 通道10 PC0 PC0 PC0 通道11 PC1 PC1 PC1 通道12 PC2 PC2 PC2 通道13 PC13 PC13 PC13 通道14 PC4 PC4 PF4 通道15 PC5 PC5 PF523.1.13 ADC1~ADC3引脚对应关系表   2)设置ADC的通用控制寄存器CCR,配置ADC输入时钟分频,模式为独立模式等。 在库函数中,初始化CCR寄存器是通过调用ADC_CommonInit来实现的: void ADC_CommonInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct) 这里我们不再李处初始化结构体成员变量,而是直接看实例。初始化实例为: ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式 ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4; ADC_CommonInit(&ADC_CommonInitStructure);//初始化 第一个参数ADC_Mode用来设置是独立模式还是多重模式,这里我们选择独立模式。 第二个参数ADC_TwoSamplingDelay用来设置两个采样阶段之间的延迟周期数。这个比较好理解。取值范围为:ADC_TwoSamplingDelay_5Cycles~ ADC_TwoSamplingDelay_20Cycles 第三个参数ADC_DMAAccessModeDMA模式禁止或者使能相应DMA模式。 第四个参数ADC_Prescaler用来设置ADC预分频器。这个参数非常重要,这里我们设置分 频系数为4分频ADC_Prescaler_Div4,保证ADC1的时钟频率不超过36MHz 3)初始化ADC1参数,设置ADC1的转换分辨率,转换方式,对齐方式,以及规则序列等相关信息。 在设置完分通用控制参数之后,我们就可以开始ADC1的相关参数配置了,设置单次转换模式、触发方式选择、数据对齐方式等都在这一步实现。具体的使用函数为: void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct) 初始化实例为:  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位模式  ADC_InitStructure.ADC_ScanConvMode = DISABLE;//非扫描模式      ADC_InitStructure.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_Resolution用来设置ADC转换分辨率。取值范围为:ADC_Resolution_6bADC_Resolution_8bADC_Resolution_10bADC_Resolution_12b 第二个参数ADC_ScanConvMode用来设置是否打开扫描模式。这里我们设置单次转换所以不打开扫描模式,值为DISABLE 第三个参数ADC_ContinuousConvMode用来设置是单次转换模式还是连续转换模式,这里我们是单次,所以关闭连续转换模式,值为DISABLE 第三个参数ADC_ExternalTrigConvEdge用来设置外部通道的触发使能和检测方式。这里我们直接禁止触发检测,使用软件触发。还可以设置为上升沿触发检测,下降沿触发检测以及上升沿和下降沿都触发检测。 第四个参数ADC_DataAlign用来设置数据对齐方式。取值范围为右对齐ADC_DataAlign_Right和左对齐ADC_DataAlign_Left 第五个参数ADC_NbrOfConversion用来设置规则序列的长度,这里我们是单次转换,所以值为1即可。   实际上还有个参数ADC_ExternalTrigConv是用来为规则组选择外部事件。因为我们前面配置的是软件触发,所以这里我们可以不用配置。如果选择其他触发方式方式,这里需要配置。 4)开启AD转换器。 在设置完了以上信息后,我们就开启AD转换器了(通过ADC_CR2寄存器控制)。 ADC_Cmd(ADC1, ENABLE);//开启AD转换器       5)读取ADC值。 在上面的步骤完成后,ADC就算准备好了。接下来我们要做的就是设置规则序列1里面的通道,然后启动ADC转换。在转换结束后,读取转换结果值值就是了。 这里设置规则序列通道以及采样周期的函数是: void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel,                                   uint8_t Rank, uint8_t ADC_SampleTime) 我们这里是规则序列中的第1个转换,同时采样周期为480,所以设置为: ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_480Cycles ); 软件开启ADC转换的方法是: ADC_SoftwareStartConvCmd(ADC1);//使能指定的ADC1的软件转换启动功能  开启转换之后,就可以获取转换ADC转换结果数据,方法是: ADC_GetConversionValue(ADC1); 同时在AD转换中,我们还要根据状态寄存器的标志位来获取AD转换的各个状态信息。库函数获取AD转换的状态信息的函数是:
FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG)
比如我们要判断ADC1的转换是否结束,方法是: while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束 这里还需要说明一下ADC的参考电压,探索者STM32F4开发板使用的是STM32F407ZGT6,该芯片只有Vref+参考电压引脚,Vref+的输入范围为:1.8~VDDA。探索者STM32F4开发板通过P7端口,来设置Vref+的参考电压,默认的我们是通过跳线帽将ref+接到VDDA,参考电压就是3.3V。如果大家想自己设置其他参考电压,将你的参考电压接在Vref+上就OK了(注意要共地)。另外,对于还有Vref-引脚的STM32F4芯片,直接就近将Vref-VSSA就可以了。本章我们的参考电压设置的是3.3V 通过以上几个步骤的设置,我们就能正常的使用STM32F4ADC1来执行AD转换操作了。

23.2 硬件设计

本实验用到的硬件资源有: 1)  指示灯DS0 2)  TFTLCD模块 3)  ADC 4)  杜邦线  前面2个均已介绍过,而ADC属于STM32F4内部资源,实际上我们只需要软件设置就可以正常工作,不过我们需要在外部连接其端口到被测电压上面。本章,我们通过ADC1的通道5PA5)来读取外部电压值,探索者STM32F4开发板没有设计参考电压源在上面,但是板上有几个可以提供测试的地方:13.3V电源。2GND3,后备电池。注意:这里不能接到板上5V电源上去测试,这可能会烧坏ADC! 因为要连接到其他地方测试电压,所以我们需要1跟杜邦线,或者自备的连接线也可以,一头插在多功能端口P12ADC插针上(与PA5连接),另外一头就接你要测试的电压点(确保该电压不大于3.3V即可)。

23.3 软件设计

打开实验工程可以发现,我们在FWLIB分组下面新增了stm32f4xx_adc.c源文件,同时会引入对应的头文件stm32f4xx_adc.hADC相关的库函数和宏定义都分布在这两个文件中。同时,我们在HARDWARE分组下面新建了adc.c,也引入了对应的头文件adc.h。这两个文件是我们编写的adc相关的初始化函数和操作函数。 打开adc.c,代码如下: //初始化ADC //这里我们仅以规则通道为例 void  Adc_Init(void) {       GPIO_InitTypeDef  GPIO_InitStructure; ADC_CommonInitTypeDef ADC_CommonInitStructure; ADC_InitTypeDef       ADC_InitStructure;     //①开启ADCGPIO相关时钟和初始化GPIO   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟   RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //使能ADC1时钟     //先初始化ADC1通道5 IO   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//PA5 通道5   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//不带上下拉   GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化    RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE);        //ADC1复位 RCC_APB2PeriphResetCmd(RCC_APB2Periph_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_Prescaler_Div4;//预分频4分频。 //ADCCLK=PCLK2/4=84/4=21Mhz,ADC时钟最好不要超过36Mhz   ADC_CommonInit(&ADC_CommonInitStructure);//初始化     //③初始化ADC1相关参数   ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位模式   ADC_InitStructure.ADC_ScanConvMode = DISABLE;//非扫描模式     ADC_InitStructure.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_Cmd(ADC1, ENABLE);//开启AD转换器    }                            //获得ADC //ch:通道值 0~16: ch: @ref ADC_channels //返回值:转换结果 u16 Get_Adc(u8 ch)   {        //设置指定ADC的规则组通道,一个序列,采样时间 ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_480Cycles );                ADC_SoftwareStartConv(ADC1);         //使能指定的ADC1的软件转换启动功能  while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束 return ADC_GetConversionValue(ADC1);     //返回最近一次ADC1规则组的转换结果 } //获取通道ch的转换值,取times,然后平均 //ch:通道编号  times:获取次数 //返回值:通道chtimes次转换结果平均值 u16 Get_Adc_Average(u8 ch,u8 times) {        u32 temp_val=0; u8 t;        for(t=0;t<times;t++)        {               temp_val+=Get_Adc(ch);   delay_ms(5);        }        return temp_val/times; } 此部分代码就3个函数,Adc_Init函数用于初始化ADC1。这里基本上是按我们上面的步骤来初始化的,我们用标号①~④标示出来步骤。这里我们仅开通了1个通道,即通道5。第二个函数Get_Adc,用于读取某个通道的ADC值,例如我们读取通道5上的ADC值,就可以通过Get_AdcADC_Channel_5)得到。最后一个函数Get_Adc_Average,用于多次获取ADC值,取平均,用来提高准确度。 头文件adc.h代码比较简单,主要是三个函数申明。接下来我们看看main函数内容: int main(void) {   u16 adcx;  float temp;        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2        delay_init(168);    //初始化延时函数        uart_init(115200);  //初始化串口波特率为115200        LED_Init();                                //初始化LED       LCD_Init();         //初始化LCD接口        Adc_Init();         //初始化ADC        POINT_COLOR=RED;        LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");              LCD_ShowString(30,70,200,16,16,"ADC TEST");            LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");        LCD_ShowString(30,110,200,16,16,"2014/5/6");                POINT_COLOR=BLUE;//设置字体为蓝 {MOD}        LCD_ShowString(30,130,200,16,16,"ADC1_CH5_VAL:");                    LCD_ShowString(30,150,200,16,16,"ADC1_CH5_VOL:0.000V");   //这里显示了小数点             while(1)        {               adcx=Get_Adc_Average(ADC_Channel_5,20);//获取通道5的转换值,20次取平均               LCD_ShowxNum(134,130,adcx,4,16,0);    //显示ADCC采样后的原始值               temp=(float)adcx*(3.3/4096);    //获取计算后的带小数的实际电压值,比如3.1111               adcx=temp;              //赋值整数部分给adcx变量,因为adcxu16整型 LCD_ShowxNum(134,150,adcx,1,16,0);  //显示电压值的整数部分               temp-=adcx; //把已经显示的整数部分去掉,留下小数部分,比如3.1111-3=0.1111               temp*=1000;//小数部分乘以1000,例如:0.1111就转换为111.1,保留三位小数。               LCD_ShowxNum(150,150,temp,3,16,0X80); //显示小数部分               LED0=!LED0; delay_ms(250);            } } 此部分代码,我们在TFTLCD模块上显示一些提示信息后,将每隔250ms读取一次ADC通道5的值,并显示读到的ADC值(数字量),以及其转换成模拟量后的电压值。同时控制LED0闪烁,以提示程序正在运行。这里关于最后的ADC值的显示我们说明一下,首先我们在液晶固定位置显示了小数点,然后后面计算步骤中,先计算出整数部分在小数点前面显示,然后计算出小数部分,在小数点后面显示。这样就在液晶上面显示转换结果的整数和小数部分。

23.4 下载验证

在代码编译成功之后,我们通过下载代码到ALIENTEK探索者STM32F4开发板上,可以看到LCD显示如图23.4.1所示:  23.4.1 ADC实验测试图 上图中,我们是将ADCTPAD连接在一起,可以看到TPAD信号电平为3V左右,这是因为存在上拉电阻R64的缘故。 同时伴随DS0的不停闪烁,提示程序在运行。大家可以试试把杜邦线接到其他地方,看看电压值是否准确?但是一定别接到5V上面去,否则可能烧坏ADC 特别注意:STM32F4ADC精度貌似不怎么好,ADC引脚直接接GND,都可以读到十几的数值,相比STM32F103来说,要差了一些,在使用的时候,请大家注意下这个问题。 通过这一章的学习,我们了解了STM32F4 ADC的使用,但这仅仅是STM32F4强大的ADC功能的一小点应用。STM32F4ADC在很多地方都可以用到,其ADCDMA功能是很不错的,建议有兴趣的大家深入研究下STM32F4ADC,相信会给你以后的开发带来方便。    实验详细手册和源码下载地址:http://www.openedv.com/posts/list/41586.htm  正点原子探索者STM32F407开发板购买地址http://item.taobao.com/item.htm?id=41855882779
  

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。