STM32资料上说:ADC的输入时钟不得超过14MHz,可是我看好多程序都是超过14M的,不知道是哪里错了
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32资料上说:ADC的输入时钟不得超过14MHz,可是我看好多程序都是超过14M的,不知道是哪里错了相关的知识,希望对你有一定的参考价值。
STM32资料上说:ADC的输入时钟不得超过14MHz,可是我看好多程序都是超过14M的,不知道是哪里错了,希望高手指点一下!!
资料上的都是推荐,事实上很多芯片的设计都是有超额余量的,很多人都会超额的利用这些资源,并且很好的工作。若所看的程序频率是超过14M,也没有错,可能作者的目的在于快速而宁愿损失一些精度,ADC的分辨率是12位,若是超过这个频率也是工作的,只不过采样到的精度可能仅到10位,若这个已到 作者的要求,也无错误之说了。 参考技术A 你检查一下有没有用到RCC_ADCCLKConfig()函数,这个是限制ADC工作频率的。追问
我知道要看这个函数,可是我就是查了半天没有查到啊,郁闷!
追答在stm32f10x_rcc中,你在ADC初始化之前加这个函数限制ADC工作频率就可以了。
追问您好,情况是这样的:STM32F107,电路板是25M晶振,我自己设置成72M的SysClk了,其中ADC时钟为72M系统时钟6分频,ADC的转换结果为1.08V,我使用的是神舟四号板子,我用它提供的例程跑了一下(例程也是设置为72M的SysClk),结果ADC转换结果为1.05V,于是我就将ADC时钟设置为72M的8分频,实验结果还是和例程不一样,由于STM32资料上说:ADC的输入时钟不得超过14MHz,所以也没有进行2分频,4分频的实验。不知道我哪里错了!!??
追答实验没错,不过F107的时钟系统和F103的有些差别,写程序时多加注意了。
本回答被提问者采纳STM32F429第二十八篇之ADC
文章目录
前言
STM32F429有3个独立的ADC。每个ADC为12位逐次逼近的模数转换器。该ADC具有19个复用通道,其中16个通道用于外部测量,两个内部源和VBAT通道。AD转换的结果存在一个16位的数据寄存器中,可以选择为左对齐或者右对齐。
本文主要参考资料:
- ST.RM0090
- ST.STM32F427xx STM32F429xx数据手册
- 刘火良,杨森.STM32库开发实战指南——基于STM32F4.机械工业出版社.
框图
上图为ADC的框图,是对ADC功能的总体描述,我将其分成7个部分,下面分别陈述:
1.对外引脚
引脚描述
ADC的供电引脚为
V
D
D
A
V_DDA
VDDA 和
V
S
S
A
V_SSA
VSSA。
ADC的参考电压为
V
R
E
F
+
V_REF+
VREF+ 和
V
R
E
F
−
V_REF-
VREF−。
每个ADC有16个输入通道,输入电压范围为:
V
R
E
F
−
≤
V
I
n
≤
V
R
E
F
−
V_REF- \\leq V_In \\leq V_REF-
VREF−≤VIn≤VREF−。在实际设计中,将
V
R
E
F
−
V_REF-
VREF−连接到
V
S
S
A
V_SSA
VSSA。将
V
R
E
F
+
V_REF+
VREF+ 连接到
V
D
D
A
V_DDA
VDDA,且为3.3V。
输入电压与AD值关系
若ADC的输入电压范围0~3.3V,且ADC为12位的话,那么,实际电压
V
V
V 与ADC读取
N
N
N的关系为:
V
=
N
2
12
×
3.3
V=\\fracN2^12 \\times 3.3
V=212N×3.3
2.输入通道
通道与GPIO
在F429中,每个ADC包含19个输入通道,其中有16个为外部输入通道,也就是ADCx_IN[15:0]。ADC输入通道与GPIO之间的关系如下表所示:
通道 | 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 | PC3 | PC3 | PC3 |
14 | PC4 | PC4 | PF4 |
15 | PC5 | PC5 | PF5 |
16 | VSS | VSS | VSS |
17 | V R E F I N T V_REFINT VREFINT | VSS | VSS |
18 | 内部温度传感器/ V B A T V_BAT VBAT | VSS | VSS |
规则转换与注入转换
如上表所示,每个ADC都有16个外部复用通道。可以将16个外部通道分成两组:规则转换和注入转换。
- 规则转换最多由16路通道构成。一般我们使用的就是规则转换。
- 注入转换最多由4路通道构成。注入转换就是在规则转换中强行插入的一种转换。如果在规则转换过程中,有注入转换插队,则需要等注入通道完成后,在回归到规则转换。有点类似于中断程序。
转换顺序
规则转换
与规则转换顺序相关的寄存器共有3个,分别为SQR3,SQR2,SQR1。通过这三个寄存器,可以设置规则转换的数量和转换的先后顺序。
SQR3
SQR2
SQR1
通过上图可以发现,三个寄存器大致可以分成两个部分:
- SQ1~SQ16:设置第1到第16个转换的通道。若想ADCx_IN16在规则转化中第一个转换,只需要将SQ1设置为16即可。
- L:用于表示该规则转化的总转换的个数。
注入转换
3. 触发源
控制开关
STM32的ADC有两个控制开关,两者都在ADC_CR2寄存器中。
- ADON控制ADC的上电与掉电。
- SWSTART和JSWSTART用于启动AD转换——软件触发。
外部触发源
除了使用SWSTART和JSWSTART软件触发外,在F429中还可以使用事件触发。
配置触发极性
如图所示,当寄存器值不是00时,则可以通过事件的极性触发外部转换。
触发事件选择
4. 时钟与时间
时钟
ADC同时使用两种时钟:
-
用于模拟电路的时钟:ADCCLK
该时钟来自于APB2时钟,通过预分频器进行2分频,4分频,6分频或者8分频。
根据数据手册可以知道:
在STM32F429中,ADCCLK最大频率为36M,而APB2的一般配置为90M,所以,在F429中,AD采样的频率一般设置为:90/4=22.5M。 -
用于数字接口的时钟——用于寄存器的读/写访问。
ADC的寄存器读写时钟为APB2。
转化时间
在ADC转化中,所花费的时间功分成两个部分:
- 采样时间
- 转化时间
其中采样时间可以通过ADC_SMPR1和ADC_SMPR2来设置。其中可以选择的采样时间分别为:
- 3个周期
- 15个周期
- 28个周期
- 56个周期
- 84个周期
- 112个周期
- 144个周期
- 480个周期
若为了提高整个转换过程的速度,可以减小采样时间,也就是选择3个周期的采样时间。
而转化时间与AD的位数成正比,每位需要一个采样周期。这样,就可以知道,一般的,选择3个周期采样时间的12位AD,完成一次转换需要花费的时钟周期为:
3 + 12 = 15 3+12=15 3+12=15
一般的,在F429中,ADC时钟为22.5MHz,所以,总转化时间为:
t
C
O
N
V
=
15
22.5
×
1
0
6
=
0.6667
×
1
0
−
6
s
=
0.6667
μ
s
t_CONV= \\frac1522.5\\times 10^6=0.6667\\times 10^-6s=0.6667\\mu s
tCONV=22.5×10615=0.6667×10−6s=0.6667μs
这是数据手册中提供的典型数据,同样可以通过相同的方法算出。
5.转换模式
5.1单次转换模式
在单次转换模式下,ADC 执行一次转换。CONT 位为 0 时,可通过以下方式启动此模式:
- 将 ADC_CR2 寄存器中的 SWSTART 位置 1(仅适用于规则通道)
- 将 JSWSTART 位置 1(适用于注入通道)
- 外部触发(适用于规则通道或注入通道)
完成所选通道的转换之后:
- 如果转换了规则通道:
- 转换数据存储在 16 位 ADC_DR 寄存器中
- EOC(转换结束)标志置 1
- EOCIE 位置 1 时将产生中断
- 如果转换了注入通道:
- 转换数据存储在 16 位 ADC_JDR1 寄存器中
- JEOC(注入转换结束)标志置 1
- JEOCIE 位置 1 时将产生中断
然后,ADC 停止。
5.2 连续转换模式
在连续转换模式下,ADC 结束一个转换后立即启动一个新的转换。CONT 位为 1 时,可通过外部触发或将 ADC_CR2 寄存器中的 SWSTRT 位置 1 来启动此模式(仅适用于规则通道)。
每次转换之后:
- 如果转换了规则通道组:
- 上次转换的数据存储在 16 位 ADC_DR 寄存器中
- EOC(转换结束)标志置 1
- EOCIE 位置 1 时将产生中断
5.3 扫描模式
此模式用于扫描一组模拟通道。
通过将 ADC_CR1 寄存器中的 SCAN 位置 1 来选择扫描模式。将此位置 1 后,ADC 会扫描 在 ADC_SQRx 寄存器(对于规则通道)或 ADC_JSQR 寄存器(对于注入通道)中选择的 所有通道。为组中的每个通道都执行一次转换。每次转换结束后,会自动转换该组中的下一个通道。如果将 CONT 位置 1,规则通道转换不会在组中最后一个所选通道处停止,而是再 次从第一个所选通道继续转换。
如果将 DMA 位置 1,则在每次规则通道转换之后,均使用直接存储器访问 (DMA) 控制器将 转换自规则通道组的数据(存储在 ADC_DR 寄存器中)传输到 SRAM。
在以下情况下,ADC_SR 寄存器中的 EOC 位置 1:
- 如果 EOCS 位清零,在每个规则组序列转换结束时
- 如果 EOCS 位置 1,在每个规则通道转换结束时
从注入通道转换的数据始终存储在 ADC_JDRx 寄存器中。
5.4 非连续模式
规则组
可将 ADC_CR1 寄存器中的 DISCEN 位置 1 来使能此模式。该模式可用于转换含有 n (n ≤ 8) 个转换的短序列,该短序列是在 ADC_SQRx 寄存器中选择的转换序列的一部分。可通过写 入 ADC_CR1 寄存器中的 DISCNUM[2:0] 位来指定 n 的值。
出现外部触发时,将启动在 ADC_SQRx 寄存器中选择的接下来 n 个转换,直到序列中的所 有转换均完成为止。通过 ADC_SQR1 寄存器中的 L[3:0] 位定义总序列长度。
示例:
n = 3,要转换的通道 = 0、1、2、3、6、7、9、10
第 1 次触发:转换序列 0、1、2
第 2 次触发:转换序列 3、6、7
第 3 次触发:转换序列 9、10 并生成 EOC 事件
第 4 次触发:转换序列 0、1、2
注意:
- 在不连续采样模式下转换规则组时,不会出现翻转。
- 转换完所有子组后,下一个触发信号将启动第一个子组的转换。在上述示例中,第 4 次触发 重新转换了第 1 个子组中的通道 0、1 和 2。
注入组
可将 ADC_CR1 寄存器中的 JDISCEN 位置 1 来使能此模式。在出现外部触发事件之后,可 使用该模式逐通道转换在 ADC_JSQR 寄存器中选择的序列。
出现外部触发时,将启动在 ADC_JSQR 寄存器中选择的下一个通道转换,直到序列中的所 有转换均完成为止。通过 ADC_JSQR 寄存器中的 JL[1:0] 位定义总序列长度。
示例:
n = 1,要转换的通道 = 1、2、3
第 1 次触发:转换通道 1
第 2 次触发:转换通道 2
第 3 次触发:转换通道 3 并生成 EOC 和 JEOC 事件
第 4 次触发:通道 1
注意:
- 转换完所有注入通道后,下一个触发信号将启动第一个注入通道的转换。在上述示例中,第 4 次触发重新转换了第 1 个注入通道。
- 不能同时使用自动注入和不连续采样模式。
- 不得同时为规则组和注入组设置不连续采样模式。只能针对一个组使能不连续采样模式。
6.数据处理
数据对齐
因为ADC转换的数据通常不是一个完整的字节或者字节的倍数,所以,获取的数据就需要进行对齐。在F429中,通过ADC_CR2
寄存器中的 ALIGN 位用于选择转换后存储的数据的对齐方式。可以选择左对齐有右对齐两种。
注入通道组的转换数据将减去 ADC_JOFRx 寄存器中写入的用户自定义偏移量,因此结果可 以是一个负值。SEXT 位表示扩展
的符号值。
对于规则组中的通道,不会减去任何偏移量,因此只有十二个位有效。
特例:采用左对齐时,数据基于半字进行对齐,除了分辨率设置为 6 位时。分辨率设置为 6 位 时,数据基于字节进行对齐,如图 40 所示。
DMA
不使用DMA
如果转换过程足够慢,则可使用软件来处理转换序列。在这种情况下,必须将 ADC_CR2 寄 存器中的 EOCS 位置 1,才能使EOC 状态位在每次转换结束时置 1,而不仅是在序列结束 时置 1。当 EOCS = 1 时,会自动使能溢出检测。因此,每当转换结束时,EOC 都会置 1,并且可以读取 ADC_DR 寄存器。溢出管理与使用 DMA 时的管理相同。
要在 EOCS 位置 1 时将 ADC 从 OVR 状态中恢复,请按以下步骤操作:
- 将 ADC_SR 寄存器中的 ADC OVR 位清零
- 触发 ADC 以开始转换。
使用DMA
由于规则通道组只有一个数据寄存器,因此,对于多个规则通道的转换,使用 DMA 非常有帮助。这样可以避免丢失在下一次写入之前还未被读出的 ADC_DR 寄存器中的数据。在使能 DMA 模式的情况下(ADC_CR2 寄存器中的 DMA 位置 1),每完成规则通道组中的 一个通道转换后,都会生成一个DMA 请求。这样便可将转换的数据从 ADC_DR 寄存器传输 到用软件选择的目标位置。
尽管如此,如果数据丢失(溢出),则会将 ADC_SR 寄存器中的 OVR 位置 1 并生成一个中 断(如果 OVRIE 使能位已置 1)。随后会禁止 DMA 传输并且不再接受 DMA 请求。在这种 情况下,如果生成 DMA 请求,则会中止正在进行的规则转换并忽略之后的规则触发。随后需要将所使用的 DMA 流中的 OVR 标志和 DMAEN 位清零,并重新初始化 DMA 和 ADC, 以将需要的转换通道数据传输到正确的存储器单元。注入通道转换不会受到溢出错误的影响。 在 DMA 模式下,当 OVR = 1 时,传送完最后一个有效数据后会阻止 DMA 请求,这意味着 传输到 RAM 的所有数据均被视为有效。
在最后一次 DMA 传输(DMA 控制器的 DMA_SxRTR 寄存器中配置的传输次数)结束时:
- 如果将 ADC_CR2 寄存器中的 DDS 位清零,则不会向 DMA 控制器发出新的 DMA 请求(这可避免产生溢出错误)。不过,硬件不会将 DMA 位清零。必须将该位写入 0 然后写入 1 才能启动新的传输。
- 如果将 DDS 位置 1,则可继续生成请求。从而允许在双缓冲区循环模式下配置 DMA。
要在使用 DMA 时将 ADC 从 OVR 状态中恢复,请按以下步骤操作:
- 重新初始化 DMA(调整目标地址和 NDTR 计数器)
- 将 ADC_SR 寄存器中的 ADC OVR 位清零
- 触发 ADC 以开始转换。
7.中断
以上是关于STM32资料上说:ADC的输入时钟不得超过14MHz,可是我看好多程序都是超过14M的,不知道是哪里错了的主要内容,如果未能解决你的问题,请参考以下文章