hujj 发表于 2020-3-5 16:07

“玩板”+基于STM32F030Disco的ADC实验

<p>&nbsp; &nbsp; 经过几天的反复测试,基于STM32F030Disco核心板的ADC实验终于基本成功,为什么说基本成功呢,是因为我在实验中开通了四个通道(1~4),不知为何第4个通道却读不到正确的数据。</p>

<p>&nbsp; &nbsp; 通过这次实验,我对STM32的ADC转换有了初步的了解,实验了轮询和DMA模式,鉴于时间关系,中断模式暂未实验。</p>

<p>&nbsp; &nbsp; 首先是在STM32CubeMX下配置了ADC,开通了IN1~IN4通道,开始还不知道要添加DMA,是在实验完轮询模式之后才知道多通道必须通过DMA模式来获得数据。</p>

<p></p>

<p>&nbsp; &nbsp; 通过STM32CubeMX生成代码,然后就找如何读取数据的代码,从网上搜索了不少代码,反复摸索测试并观看结果,最后才知道要先用<b><span lang="EN-US" style="font-size:10.5pt"><span style="font-family:&quot;Calibri&quot;,&quot;sans-serif&quot;">HAL_ADC_Start()</span></span></b>函数开始转换、然后用<b><span lang="EN-US" style="font-size:10.5pt"><span style="font-family:&quot;Calibri&quot;,&quot;sans-serif&quot;">HAL_ADC_PollForConversion()</span></span></b>函数等待转换完成、之后再用<b><span lang="EN-US" style="font-size:10.5pt"><span style="font-family:&quot;Calibri&quot;,&quot;sans-serif&quot;">HAL_ADC_GetValue()</span></span></b>函数获得结果,最后用<b><span lang="EN-US" style="font-size:10.5pt"><span style="font-family:&quot;Calibri&quot;,&quot;sans-serif&quot;">HAL_ADC_Stop()</span></span></b>函数停止转换。弄清楚这些步骤花费了不少时间,然而在后面我将固件库文件拷贝出来,并逐段翻译阅读后才清楚的,如果早点做这步工作肯定可以节省不少时间。</p>

<p>&nbsp;</p>

<p></p>

<p>&nbsp; &nbsp; 我是通过一个连接在3.3V电源上的10K电位器给通道IN1信号的,通过每隔0.1V读取一次转换数据,然后将这些数据填在EXCEL表格中,生成折线图来观察电压值与转换数据的关系。下表是手工测量记录的数据,由于数据跳动厉害,记录的数据会有一些误差。</p>

<p></p>

<p>&nbsp; &nbsp; 制成折线图之后可以发现转换数据与电压值在接近两端时不是直线。</p>

<p></p>

<p>&nbsp; &nbsp; 开始我先配置了一条直线,试图找到其数学模型,以便从获得的转换数据计算出实际电压(见下图)。</p>

<p></p>

<p>&nbsp; &nbsp; 反复试验了多次,最后还是通过分段计算的办法来获得比较接近实际的电压值。下面是读取和转换数据的代码:</p>

<pre>
<code class="language-cs">void Get_ADC_Val(uint8_t id)
{
    uint8_t i;

    HAL_ADC_Start_DMA(&amp;hadc,(uint32_t *) ADC_ConvertedValueLocal,4);

        HAL_ADC_ConvHalfCpltCallback(&amp;hadc);
        for ( i=0;i&lt;4;i++ )   //分别处理四路ADC
    {   
                if(ADC_ConvertedValueLocal&lt;600)
            adc_val = ADC_ConvertedValueLocal*10/214;
      else if(ADC_ConvertedValueLocal&lt;1200)
                        adc_val = (ADC_ConvertedValueLocal-600)*10/122+28;
                else if(ADC_ConvertedValueLocal&gt;3400)
                        adc_val = (ADC_ConvertedValueLocal-3400)*10/199+265;
                else
                        adc_val = (ADC_ConvertedValueLocal-1200)*10/117+77;
    }
           HAL_ADC_Stop_DMA(&amp;hadc);
}</code></pre>

<p>&nbsp;</p>

<p>&nbsp; &nbsp;&nbsp;下图是实验过程。</p>

<p></p>

<p>&nbsp; &nbsp;&nbsp;通过上网搜索才知道要添加硬件滤波和软件滤波才能平滑数据的抖动,由于是简单的实验,硬件滤波就暂时未加,先通过软件滤波来消抖,办法是每隔0.1秒读取一次转换数据并存放在数组中,每秒将10次数据的平均值显示出来,这样抖动就稍微好一点。</p>

threetigher 发表于 2020-3-5 19:32

<p>手动点赞!能否看看<a href="https://bbs.eeworld.com.cn/thread-1088653-1-1.html">https://bbs.eeworld.com.cn/thread-1088653-1-1.html</a>这个帖子,无法2个以上的adc同步采样,原因何在?谢谢</p>

hujj 发表于 2020-3-6 08:40

threetigher 发表于 2020-3-5 19:32
手动点赞!能否看看https://bbs.eeworld.com.cn/thread-1088653-1-1.html这个帖子,无法2个以上的adc同步采 ...

<p>谢谢提示!</p>

<p>不过这个帖子说的是如何同时开启多个ADC,而我是一个ADC开启多个通道,有点区别的。</p>
页: [1]
查看完整版本: “玩板”+基于STM32F030Disco的ADC实验