f401和f407,f401和f407的区别

首页 > 汽车 > 汽车资讯 > 正文

f401和f407,f401和f407的区别

1)实验平台:alientek 阿波罗 STM32F767 开发板

2)摘自《STM32F7 开发指南(HAL 库版)》关注官方微信号公众号,获取更多资料:正点原子

f401和f407,f401和f407的区别

第二十三章 ADC 实验

本章我们将向大家介绍 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,也就是

转换时间为 0.41us(在 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 时钟都很简单,具体方法为:

这里需要说明一下,ADC 的通道与引脚的对应关系在 STM32F4 的数据手册可以查到,我

们这里使用 ADC1 的通道 5,在数据手册中的表格为:

表 23.1.12 ADC1 通道 5 对应引脚查看表

这里我们把 ADC1~ADC3 的引脚与通道对应关系列出来, 16 个外部源的对应关系如下表:

表 23.1.13 ADC1~ADC3 引脚对应关系表

2)初始化 ADC,设置 ADC 时钟分频系数,分辨率,模式,扫描方式,对齐方式等信息。

在 HAL 库中,初始化 ADC 是通过函数 HAL_ADC_Init 来实现的,该函数声明为:

该结构体定义和其他外设比较类似,我们着重看第二个成员变量 Init 含义,它是结构体

ADC_InitTypeDef 类型,结构体 ADC_InitTypeDef 定义为:

我们直接把每个成员变量含义注释在结构体定义的后面,请大家仔细阅读上面注释。

这里我们需要说明一下,和其他外设一样,HAL 库同样提供了 ADC 的 MSP 初始化函数,

一般情况下,时钟使能和 GPIO 初始化都会放在 MSP 初始化函数中。函数声明为:

4)开启 AD 转换器。

在设置完了以上信息后,我们就开启 AD 转换器了(通过 ADC_CR2 寄存器控制)。

HAL_ADC_Start(&ADC1_Handler); //开启 ADC

5)配置通道,读取通道 ADC 值。

在上面的步骤完成后,ADC 就算准备好了。接下来我们要做的就是设置规则序列 1 里面的

通道,然后启动 ADC 转换。在转换结束后,读取转换结果值值就是了。

设置规则序列通道以及采样周期的函数是:

该函数有两个入口参数,第一个就不用多说了,接下来我们看第二个入口参数 sConfig,它

是 ADC_ChannelConfTypeDef 结构体指针类型,结构体定义如下:

该结构体有四个成员变量,对于 STM32F4 只用到前面三个。Channel 用来设置 ADC 通道,

Rank 用来设置要配置的通道是规则序列中的第几个转换,SamplingTime 用来设置采样时间。

使用实例为:

配置好通道并且使能 ADC 后,接下来就是读取 ADC 值。这里我们采取的是查询方式读取,

所以我们还要等待上一次转换结束。此过程 HAL 库 提 供 了 专 用 函 数

等待上一次转换结束之后,接下来就是读取 ADC 值,函数为:

这两个函数的使用方法都比较简单,这里我们就不累赘了。

这里还需要说明一下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_hal_adc.c 源文件,同

时会引入对应的头文件 stm32f4xx_hal_adc.h。ADC 相关的库函数和宏定义都分布在这两个文件

中。同时,我们在 HARDWARE 分组下面新建了 adc.c,也引入了对应的头文件 adc.h。这两个

文件是我们编写的 adc 相关的初始化函数和操作函数。

打开 adc.c,代码如下:

此部分代码就 3 个函数,Adc_Init 函数用于初始化 ADC1。这里基本上是按我们上面的步

骤来初始化的,我们用标号①~④标示出来步骤。这里我们仅开通了 1 个通道,即通道 5。第二

个函数 Get_Adc,用于读取某个通道的 ADC 值,例如我们读取通道 5 上的 ADC 值,就可以通

过 Get_Adc(ADC_Channel_5)得到。最后一个函数 Get_Adc_Average,用于多次获取 ADC 值,

取平均,用来提高准确度。

头文件 adc.h 代码比较简单,主要是三个函数申明。接下来我们看看 main 函数内容:

此部分代码,我们在 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,相信会给你以后的开发带来方便。

备案号:赣ICP备2022005379号
华网(http://www.hbsztv.com) 版权所有未经同意不得复制或镜像

QQ:51985809邮箱:51985809@qq.com