
二、软件实验 2.1 ADC读取实验 [1 ADC介绍] [1.1> 读取的三种模式] ADC读取的方式有三种:一种是所谓的连续模式,另一种是不连续模式,还有一种是单次模式。只看上面的名字似乎并不能搞清楚每种都是什么意思。假定我们要使用CH0,3,7这三个通道读取ADC的数据。在采集过程中采集方向不发生改变,假定是升序采集。我通过软件触发或者硬件触发来启动ADC转换,在下面我直接称这个过程叫做“触发采集”。 连续模式的意思是,在触发采集一次之后,ADC模块自动按照0-3-7-0-3-7的顺序循环采集者三个通道的数据。在每个通道采集完触发EOC事件,每一遍完成之后触发EOSEQ事件。 单次模式是,触发采集一次之后,ADC模块自动按照0-3-7的顺序采集三个通道的数据。采集完成之后停止运行,直到才一次触发采集来引起对ADC的采集。相对于上面的区别是,新的一轮采集需要新的触发采集事件。 不连续模式下,每次触发采集动作执行一个通道的触发。 因此你可以看出ADC的每个通道事实上不能单独操作的。如果你这段时间使用通道0和1,下一段时间只是用通道2和3.那么你最好是在发生改变的时候重新配置ADC。在这种情况下cubemx就无能为力了,你只能先按照前者配置,在程序中在编写这部分改变的代码。 对了每次的EOC和EOSEQ都需要软件来复位,否则不能执行下一次采集。详情见参考手册RM0377中ADC部分. [1.2> 数据处理的模式] 每一次转换的结果都存储在ADC_DR这个16位寄存器里面,因为ADC的分辨率和对齐方向可以配置,所以具体的数据含义可以参考自己的设置。 下图很形象的给出数据的排列含义: ADCæ°æ®å¯¹é½ ![]() 因为所有通道的数据采集是按照顺序执行的,而且数据采集的结果如果不读取可能会被overwrite或者触发overrun信号。如果及时的从ADC_DR中读出数据并放到正确的位置是很重要的。采用DMA是一种方法,当然另一种是不采用DMA。在转换速度很慢切没有其他任务需要紧急执行时可以不适用DMA,而是用软件轮训的方式来检测EOC,不过这种方式还是有潜在的overrun的危险。还有一种不用DMA的方式是将OVERMOD设置成1,然后每次读取ADC_DR里面的数据时只获取最新的数据,数据的通道可能是转换序列中的任何一个,这种方式在一些特殊场景中有用。最好用的方式当然是使用DMA了。但是采用DMA的方法技术也稍微复杂,可使用one-shot和circular模式。前者每完成DMA transfer之后就停止ADC的扫描序列等动作,后者则更适合完成一系列的ADC转换。 [1.3> 时钟的配置] 在上个帖子中简单介绍了一下ADC时钟来源的问题。除了哪里介绍的同步和异步模式外,还需要注意的是:对于STM32L0 ADC模块的最高时钟频率是16MHZ,因此在配置时钟时无论同步异步在分频后的频率一定不能超过这个频率。那异步模式来说,频率是由HSI提供的而L031K6的HSI频率是16MHZ。这个数据时刚好的。当然你还可以2/4/8分频,至于同步模式就一定要注意分频的数目。
[2 实验介绍] 我比较喜欢使用HAL变成,因为ST的新硬件都是以HAL作为主要的驱动平台。ADC的使用除了按照我上面的介绍来设置外,还需要对API做一些简单的了解。稍后可以看我在cube里面的配置,但是程序对其配置有些修改。在实验时遇到了一些问题。在下面的介绍中做了详细介绍。 首先,我在PA1、PA3上接上摇杆的XY轴电位器,另外打开了温度采集通道。当然其它硬件连接也就绪了。通过UART2输出信息,但是因为SB3没有接上0欧姆电阻所以通过STlink的USB并不能输出直接输出信息。所以如果需要开通ST-Link的VCP通道需要焊接SB3上的电阻。具体可以看原理图。 下面是连接的硬件,硬件原理图可以看下一个实验的文档,因为硬件连接差别不大。 实验内容就是通过串口将ADC的数据输出,ADC采样通过DMA循环采样,但是UART输出和LD3闪动同步,大约200毫秒输出一次。下面是实验场景图 ![]() 这里说明一下实验过程中遇到的几个问题。第一个问题是温度的ADC数据采集之后如何处理成温度。第二个是DMA的数据如何接受,还有就是实验结束的标志是什么。本实验没有用到,按道理应该是我需要的数据转换结束后,通过中断来调用ADC显示任务。第三个问题是ADC影响HAL_Delay()。第四个是ADC的串扰问题。前两个问题不涉及具体实验现象问题,可以通过搜索RM文档找相关关键字找到解决办法。这里具体讲后两个问题。 第三个问题起初的原因是这样的我的配置打开了ADC的continuous模式,就是说我的ADC是采集完一轮之后再去转换。DMA的优先级我设置的比systick中断高.ADC的一直运行,ADC转换的结果一直调用DMA处理新数据。所以Systick一直来不及处理Systick的中断处理函数。所以最终的现象是我的LED一直处于亮起的状态,而不闪动。在检查代码是我发现程序一直回调Delay的函数。解决办法就是我在闪动一次LED时采集一次,然后显示。当然这样做只是为了测试ADC,后期我上RTOS的时候再设计一种更好的调用方式。 第三个问题是第二路ADC对温度采集有串扰。具体表现是第一路摇杆左右移动时,不影响第二路输出,本身正常。但是第二路在前后移动时,影响温度传感器的输出值,而且变化很大。我之前在用Arduino时遇到过这种问题,但是没有遇到过只是其中一路对下一路影响的。但是还是决定是串扰问题,我自己也尝试修改采样时间,但改动不大,温度的输出值变化还是有。直到我找到官方的一篇文章介绍之后,才发现自己的设置还是太小。 我将文档上传,请看: ![]() |
不过感谢ST了,学习还要靠自己
谢谢苏柚
欢迎光临
谢谢。
找了一家,尽管不是特别理想。但是whatever,先进步再说。