arm - 试图了解STM32L4的ADC

标签 arm stm32 firmware adc

我很难理解 STM32 ADC 的工作原理。 我想做一些简单的事情,即。在 2 个 GPIO 上定期采样和转换 (@ 250Hz)。 现在我以一种“虚拟”的方式做到了:在基本单模式下设置 ADC,然后在 250Hz 启动定时器,并在每次定时器中断时启动 ADC 以在每个 channel 上仅转换一个样本。但我认为这不是正确的做法,我担心样本之间的时间安排不够精确。 你能解释一下我应该如何配置 ADC 在给定数量的样本期间以给定频率连续采样/转换吗?我没有在网上找到太多有用的资源,引用手册也很复杂。 谢谢

最佳答案

常规或注入(inject)的转换序列

每个 ADC 可以处理两个要转换的 channel 列表,一个具有 16 个 channel 的常规序列 (SQR1-SQR4),以及一个具有 4 个 channel 的注入(inject)序列 (JSQR).

主要区别之一是常规转换将所有结果存储在单个共享数据寄存器 (DR) 中,必须在下一个转换步骤完成之前读出并存储该寄存器。当有多个 channel 按一定顺序排列时,最好使用DMA 来存储转换结果。因为你想要一些简单的东西,我现在不会进入 DMA。

注入(inject)的转换序列将每个结果存储在自己的寄存器中(JDR1-JDR4JDR[4]),然后软件可以序列完成后读取结果,这可以通过轮询 ISR 寄存器中的 JEOS 位或通过使用 JEOSIE 启用中断来检测> IER 中的位。

可以在常规序列完成时自动启动注入(inject)序列(CFGR 中的JAUTO 位),这样就可以连续启动 5 次转换在每个 ADC 单元上,并将结果放在最后的不同寄存器中。

定期开始转换

您可以设置一个定时器来直接启动 ADC 转换序列,而不是每次都通过软件启动转换。

首先,请参阅引用手册中标题为外部触发和触发极性转换(EXTSEL、EXTEN、JEXTSEL、JEXTEN)的章节。有常规和注入(inject)序列的可能触发事件列表。从表中选择一个 TRGO 事件,相应地设置 EXTSELEXTEN,或 JEXTSELJEXTEN

您现在可能希望启用序列结束中断(IER 中的EOSIEJEOSIE),以便在序列结束时通知软件.

通过在 CR1 中设置 ADENADSTARTJADSTART 来启动 ADC,一旦来自定时器的触发器到达。

将您从上表中选择的定时器编程为所需的频率,并将 CR2 中的 MMS 位设置为 010(更新).定时器的每次溢出(更新)都会产生一个触发事件,启动下一个 ADC 转换序列。没有必要启用定时器中断。

使用更多 ADC 单元

如果您的 Controller 中有多个 ADC 单元,您可以在每个单元上使用相同的触发器同时启动它们。通过这种方式,您可以同时进行 2 或 3 次转换,或者最多启动 15 次转换并立即获得结果,而无需使用 DMA。

关于arm - 试图了解STM32L4的ADC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49999626/

相关文章:

linux - 按名称杀死正在运行的进程

gcc - arm-none-eabi-gdb 和 openocd : Malformed response to offset query, qOffsets?

c - STM32接收来自盖革计数器的输入

raspberry-pi - 远程更新树莓派软件 'over the air'

linux-device-driver - 查找设备基地址以通过 in() 和 out() 进行通信

driver - 我是否认为现代消费类显卡使用完全相同的 GPU 结构来进行实际图形渲染和裸计算?

assembly - ARM当前程序状态寄存器(SPSR)读-修改-写策略实践

ubuntu - 使用 Arm Trusted Firmware-v2.2 构建 Avenger96 板的错误

c - stm32g483 基于 SysTick 的计时器的奇怪行为

arm - STM32 F446RE简单DAC输出;我缺少什么?