第二十三章 ADC实验
[mw_shl_code=c,true]
1.硬件平台:正点原子探索者STM32F407开发板
2.软件平台:MDK5.1
3.固件库版本:V1.4.0
[/mw_shl_code]
本章我们将向大家介绍
STM32F4的
ADC功能。在本章中,我们将使用
STM32F4的
ADC1通道
5来采样外部电压值,并在
TFTLCD模块上显示出来。本章将分为如下几个部分:
23.1 STM32F4 ADC简介
23.2 硬件设计
23.3 软件设计
23.4 下载验证
23.1
STM32F4 ADC简介
STM32F4xx系列一般都有
3个
ADC,这些
ADC可以独立使用,也可以使用双重
/三重模式(提高采样率)。
STM32F4的
ADC是
12位逐次逼近型的模拟数字转换器。它有
19个通道,可测量
16个外部源、
2个内部源和
Vbat通道的信号。这些通道的
A/D转换可以单次、连续、扫描或间断模式执行。
ADC的结果可以左对齐或右对齐方式存储在
16位数据寄存器中。
模拟看门狗特性允许应用程序检测输入电压是否超出用户定义的高
/低阀值。
STM32F407ZGT6包含有
3个
ADC。
STM32F4的
ADC最大的转换速率为
2.4Mhz,也就是转换时间为
1us(在
ADCCLK=36M,采样周期为
3个
ADC时钟下得到),不要让
ADC的时钟超过
36M,否则将导致结果准确度下降。
STM32F4将
ADC的转换分为
2个通道组:规则通道组和注入通道组。规则通道相当于你正常运行的程序,而注入通道呢,就相当于中断。在你程序正常执行的时候,中断是可以打断你的执行的。同这个类似,注入通道的转换可以打断规则通道的转换,
在注入通道被转换完成之后,规则通道才得以继续转换。
通过一个形象的例子可以说明:假如你在家里的院子内放了
5个温度探头,室内放了
3个温度探头;你需要时刻监视室外温度即可,但偶尔你想看看室内的温度;因此你可以使用规则通道组循环扫描室外的
5个探头并显示
AD转换结果,当你想看室内温度时,通过一个按钮启动注入转换组
(3个室内探头
)并暂时显示室内温度,当你放开这个按钮后,系统又会回到规则通道组继续检测室外温度。从系统设计上,测量并显示室内温度的过程中断了测量并显示室外温度的过程,但程序设计上可以在初始化阶段分别设置好不同的转换组,系统运行中不必再变更循环转换的配置,从而达到两个任务互不干扰和快速切换的结果。可以设想一下,如果没有规则组和注入组的划分,当你按下按钮后,需要从新配置
AD循环扫描的通道,然后在释放按钮后需再次配置
AD循环扫描的通道。
上面的例子因为速度较慢,不能完全体现这样区分
(规则通道组和注入通道组
)的好处,但在工业应用领域中有很多检测和监视探头需要较快地处理,这样对
AD转换的分组将简化事件处理的程序并提高事件处理的速度。
STM32F4其
ADC的规则通道组最多包含
16个转换,而注入通道组最多包含
4个通道。关于这两个通道组的详细介绍,请参考《
STM32F4xx中文参考手册》第
250页,第
11.3.3节。
STM32F4的
ADC可以进行很多种不同的转换模式,这些模式在《
STM32F4xx中文参考手册》的第
11章也都有详细介绍,我们这里就不在一一列举了。我们本章仅介绍如何使用规则通道的单次转换模式。
STM32F4的
ADC在单次转换模式下,只执行一次转换,该模式可以通过
ADC_CR2寄存器的
ADON位(只适用于规则通道)启动,也可以通过外部触发启动(适用于规则通道和注入通道),这时
CONT位为
0。
以规则通道为例,一旦所选择的通道转换完成,转换结果将被存在
ADC_DR寄存器中,
EOC(转换结束)标志将被置位,如果设置了
EOCIE,则会产生中断。然后
ADC将停止,直到下次启动。
接下来,我们介绍一下我们执行规则通道的单次转换,需要用到的
ADC寄存器。第一个要介绍的是
ADC控制寄存器(
ADC_CR1和
ADC_CR2)。
ADC_CR1的各位描述如图
23.1.1所示:
图
23.1.1 ADC_CR1寄存器各位描述
这里我们不再详细介绍每个位,而是抽出几个我们本章要用到的位进行针对性的介绍,详细的说明及介绍,请参考《
STM32F4xx中文参考手册》第
11.13.2节。
ADC_CR1的
SCAN位,该位用于设置扫描模式,由软件设置和清除,如果设置为
1,则使用扫描模式,如果为
0,则关闭扫描模式。在扫描模式下,由
ADC_SQRx或
ADC_JSQRx寄存器选中的通道被转换。如果设置了
EOCIE或
JEOCIE,只在最后一个通道转换完毕后才会产生
EOC或
JEOC中断。
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位必须为
0。
ALIGN用于设置数据对齐,我们使用右对齐,该位设置为
0。
EXTEN[1:0]用于规则通道的外部触发使能设置,详细的设置关系如图
23.1.4所示:
图
23.1.4 ADC规则通道外部触发使能设置
我们这里使用的是软件触发,即不使用外部触发,所以设置这
2个位为
0即可。
ADC_CR2的
SWSTART位用于开始规则通道的转换,我们每次转换(单次转换模式下)都需要向该位写
1。
第二个要介绍的是
ADC通用控制寄存器(
ADC_CCR),该寄存器各位描述如图
23.1.5所示:
图
23.1.5 ADC_CCR寄存器各位描述
该寄存器我们也只针对性的介绍一些位:
TSVREFE位是内部温度传感器和
Vrefint通道使能位,内部温度传感器我们将在下一章介绍,这里我们直接设置为
0。
ADCPRE[1:0]用于设置
ADC输入时钟分频,
00~11分别对应
2/4/6/8分频,
STM32F4的
ADC最大工作频率是
36Mhz,而
ADC时钟(
ADCCLK)来自
APB2,
APB2频率一般是
84Mhz,所以我们一般设置
ADCPRE=01,即
4分频,这样得到
ADCCLK频率为
21Mhz。
MULTI[4:0]用于多重
ADC模式选择,详细的设置关系如图
23.1.6所示:
图
23.1.6 多重
ADC模式选择设置
本章我们仅用了
ADC1(独立模式),并没用到多重
ADC模式,所以设置这
5个位为
0即可。
第三个要介绍的是
ADC采样时间寄存器(
ADC_SMPR1和
ADC_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[3:
0]用于存储规则序列的长度,我们这里只用了
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_CR2的
ALIGN位设置左对齐还是右对齐。在读取数据的时候要注意。
最后一个要介绍的
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为模拟输入。
STM32F407ZGT6的
ADC1通道
5在
PA5上,所以,我们先要使能
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
PF5
表
23.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_DMAAccessMode是
DMA模式禁止或者使能相应
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_6b,
ADC_Resolution_8b,
ADC_Resolution_10b和
ADC_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。
通过以上几个步骤的设置,我们就能正常的使用
STM32F4的
ADC1来执行
AD转换操作了。
23.2 硬件设计
本实验用到的硬件资源有:
1) 指示灯
DS0
2) TFTLCD模块
3) ADC
4) 杜邦线
前面
2个均已介绍过,而
ADC属于
STM32F4内部资源,实际上我们只需要软件设置就可以正常工作,不过我们需要在外部连接其端口到被测电压上面。本章,我们通过
ADC1的通道
5(
PA5)来读取外部电压值,探索者
STM32F4开发板没有设计参考电压源在上面,但是板上有几个可以提供测试的地方:
1,
3.3V电源。
2,
GND。
3,后备电池。注意:这里不能接到板上
5V电源上去测试,这可能会烧坏
ADC!。
因为要连接到其他地方测试电压,所以我们需要
1跟杜邦线,或者自备的连接线也可以,一头插在多功能端口
P12的
ADC插针上(与
PA5连接),另外一头就接你要测试的电压点(确保该电压不大于
3.3V即可)。
23.3 软件设计
打开实验工程可以发现,我们在
FWLIB分组下面新增了
stm32f4xx_adc.c源文件,同时会引入对应的头文件
stm32f4xx_adc.h。
ADC相关的库函数和宏定义都分布在这两个文件中。同时,我们在
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;
//①开启
ADC和
GPIO相关时钟和初始化
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:获取次数
//返回值
:通道
ch的
times次转换结果平均值
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_Adc(
ADC_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变量,因为
adcx为
u16整型
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实验测试图
上图中,我们是将
ADC和
TPAD连接在一起,可以看到
TPAD信号电平为
3V左右,这是因为存在上拉电阻
R64的缘故。
同时伴随
DS0的不停闪烁,提示程序在运行。大家可以试试把杜邦线接到其他地方,看看电压值是否准确?但是一定别接到
5V上面去,否则可能烧坏
ADC!
特别注意:STM32F4的
ADC精度貌似不怎么好,
ADC引脚直接接
GND,都可以读到十几的数值,相比
STM32F103来说,要差了一些,在使用的时候,请大家注意下这个问题。
通过这一章的学习,我们了解了
STM32F4 ADC的使用,但这仅仅是
STM32F4强大的
ADC功能的一小点应用。
STM32F4的
ADC在很多地方都可以用到,其
ADC的
DMA功能是很不错的,建议有兴趣的大家深入研究下
STM32F4的
ADC,相信会给你以后的开发带来方便。
实验详细手册和源码下载地址:http://www.openedv.com/posts/list/41586.htm
正点原子探索者STM32F407开发板购买地址:http://item.taobao.com/item.htm?id=41855882779
一周热门 更多>