STM32单片机之ADC学习经验总结 下载本文

内容发布更新时间 : 2024/5/20 7:13:27星期一 下面是文章的全部内容请认真阅读。

STM32 单片机之 ADC 学习经验总结

因为公司的产品上需要使用 AD 来检测电池电压,要求不是很高,突然 想用下 DMA+ADC+TIM,以前以为很简单,实际使用中让我觉得很惭愧, 遇到的问题让我一下子蒙了,不停的查资料,不停的测试,终于一个一个的 问题都解决了,同时对 STM32 的 ADC 有了新的认识,并且打算再闲暇时间 内将 STM32 的资源尽量的实践下。

我用的是 STM32F4

来调试 ADC3+DMA+TIM1(单通道),首先我先查看

了下 DMA 的资料,之后参考官方提供的 ADC3+DMA 很快可以正常读取数 据,之后我直接添加定时器触发 AD 转换,结果失败,我开始查资料看手 册,逐渐对这三者之间的关系有了一个认识

首先定时器产生触发信号,AD 检测到转换信号后开始转换,每转换一次 就通过 DMA 将数据放到指定的内存地址中,直到达到 DMA 设定的 DMA_BufferSize 设定值后 DMA 置位相应的标志位,从而完成一次 DMA 传 输。

由上面的关系的可以得知 ADC 转换是一次一次即单次非扫描模式(我测试 的是 AD 单通道),因为连续模式一旦触发就会不停的转换,这样的话定时器 触发转换就失去了意义,之后 DMA 设置成普通模式,即完成一次 DMA 传 输后,停止传输,之后的 DMA 请求不被响应,因为 DMA 传输完成后以为 着可以进行数据处理了,这个时候为了防止数据被覆盖(网上还有其他方法防 止数据被覆盖)。

1>关于定时器的 PWM 输出

一开始我用定时器 1 的 CH1 来作为 AD 的触发信号对应的管脚是 PA8,管 脚配置的时候配置成复用模式没有调用 GPIO_PinAFConfig,将 PA8 复用成 TIM1 的输出脚,关于定时器的时钟我忽略了一个重要的因素,所以设置的频 率一直不对

查看 stmf4 的参考手册 如果 APBx_PRESC 为 1 则定时器的时钟为 PCLKx 的时钟 否则为 2 倍的 PCLKx

-如果是定时器 1 和定时器 8 需要调用 TIM_CtrlPWMOutputs 来开启 pwm 输出之后通过示波器可以正确查看 PA8 的的波形输出。

2>AD 转换

-ADC_CommonInitStructure.ADC_DMAAccessMode ADC_DMAAccessMode_Disabled;

我对这句一点都不懂,通过查资料发现 stm32F4 的 ADC 的 DMA 有 4 种模 式,主要是为了通过联合使用 ADC 模块提升采样速度,其中默认模式和模 式 1 差不多,

DMA mode 1 enabled (2 / 3 half-words one by one - 1 then 2 then 3)

=

//从依次取 ADC 的值,分辨率为 12 位,

DMA mode 2 enabled (2 / 3 half-words by pairs - 2&1 then 1&3 then 3&2)

//可以联合使用这三个 ADC 模块进行采样,采样速度也是单独的三倍 (2.4*3Msps),分辨率是 12 位,完成两次转换后,将值取走应该是

//ADC2+ADC1 ,ADC1+ADC3 ,ADC3+ADC2

DMA mode 3 enabled (2 / 3 bytes by pairs - 2&1 then 1&3 then 3&2)

//模式 3 和模式 2 差不多 但是分辨率要求是 8 位或 6 位,虽然分辨率降低 了但是转换时间相对 12 位的要短。

-ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;

//连续模式必须被禁止,不然定时器触发就失去了意义

ADC_InitStructure.ADC_ExternalTrigConvEdge ADC_ExternalTrigConvEdge_Rising;

//查看寄存器,发现需要使能外部触发,上面就是开启并制定触发信号的极 性

=