lugl4313820 发表于 2022-5-9 15:59

【GD32F310G-START】电压表

本帖最后由 lugl4313820 于 2022-5-9 15:59 编辑

<p>为了验证ADC的精度如何,今天做了个电压表:</p>

<p>电压输入IO选择为GPIOB1,从datasheet上查到为通道9:</p>

<p>&nbsp; 1、初始化ADC时钟:</p>

<pre>
<code>void rcu_config(void)
{
    /* enable GPIOC clock */
    rcu_periph_clock_enable(RCU_GPIOB);
    /* enable ADC clock */
    rcu_periph_clock_enable(RCU_ADC);
    /* config ADC clock */
    rcu_adc_clock_config(RCU_ADCCK_APB2_DIV6);
}</code></pre>

<p>2、初始化IO:PB1</p>

<pre>
<code>void gpio_config(void)
{
    /* config the GPIO as analog mode */
    gpio_mode_set(GPIOB, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_1);
}</code></pre>

<p>3、ADC配置:</p>

<pre>
<code>void adc_config(void)
{
    /* ADC data alignment config */
    adc_data_alignment_config(ADC_DATAALIGN_RIGHT);
    /* ADC channel length config */
    adc_channel_length_config(ADC_REGULAR_CHANNEL, 1U);

    /* ADC trigger config */
    adc_external_trigger_source_config(ADC_REGULAR_CHANNEL, ADC_EXTTRIG_REGULAR_NONE);
    /* ADC external trigger config */
    adc_external_trigger_config(ADC_REGULAR_CHANNEL, ENABLE);

    /* enable ADC interface */
    adc_enable();
    delay_1ms(1U);
    /* ADC calibration and reset calibration */
    adc_calibration_enable();
}</code></pre>

<p>4、转换函数:</p>

<pre>
<code>/*!
    \brief      ADC 转换函数
    \param通道数
    \param
    \retval   ADC值
*/
uint16_t ADC_Get_Channel(uint8_t channel)
{
    /* ADC regular channel config */
    adc_regular_channel_config(0U, channel, ADC_SAMPLETIME_7POINT5);
    /* ADC software trigger enable */
    adc_software_trigger_enable(ADC_REGULAR_CHANNEL);

    /* wait the end of conversion flag */
    while(!adc_flag_get(ADC_FLAG_EOC));
    /* clear the end of conversion flag */
    adc_flag_clear(ADC_FLAG_EOC);
    /* return regular channel sample value */
    return (adc_regular_data_read() &amp; 0xfff);
}</code></pre>

<p>5、多次采样,取平均值:</p>

<pre>
<code>//channel参数为ADC通道:ADC_CHANNEL_xx = 0...15
uint16_t adc_Channel_Average(uint8_t channel)
{
    uint32_t adc_raw = 0;
int i;
    uint8_t degree = 3;//读的次数的幂 2^3
    for(i = 0;i &lt; (1 &lt;&lt; degree);i++)
    {
      //读取ADC次数
      adc_raw += ADC_Get_Channel(channel);
      delay_1ms(2);
    }
   
    //这里循环8次读取,因此 &gt;&gt;3位就是除以8
    adc_raw &gt;&gt;= degree;

    return adc_raw;

}
</code></pre>

<p>6、主函数、获取平均ADC值,显示到LCD上:</p>

<pre>
<code>adc_value = adc_Channel_Average(ADC_CHANNEL_9);
vref_value = (float)adc_value*3.3f/4096.0f;
sprintf(show_adc_str,"%.4fV",vref_value);
LCD_ShowString(18,36,show_adc_str,WHITE,BLUE,32,0);</code></pre>

<p>7、为了验证采样的精度如何,我用了标准的数据电源、福禄克45、福禄克18B+进行了对比显示:</p>

<table align="center" border="1" cellpadding="1" cellspacing="1">
        <tbody>
                <tr>
                        <td>E3640A</td>
                        <td>&nbsp;0.00V&nbsp; &nbsp;</td>
                        <td>1.00V</td>
                        <td>2.00V</td>
                        <td>3.00V</td>
                        <td>3.30V</td>
                </tr>
                <tr>
                        <td>GD32F310</td>
                        <td>0..0000V</td>
                        <td>0.9894V</td>
                        <td>2.0029V</td>
                        <td>3.0043</td>
                        <td>3.2992V</td>
                </tr>
                <tr>
                        <td>福禄克45</td>
                        <td>0.89mV</td>
                        <td>1.0016V</td>
                        <td>2.0040V</td>
                        <td>3.0071</td>
                        <td>3.308V</td>
                </tr>
                <tr>
                        <td>福禄克18+</td>
                        <td>0.000V</td>
                        <td>0.996V</td>
                        <td>1.994V</td>
                        <td>2.992</td>
                        <td>3.291V</td>
                </tr>
                <tr>
                        <td>平均差值</td>
                        <td>&nbsp;</td>
                        <td>0.0094</td>
                        <td>-0.0039</td>
                        <td>-0.0047</td>
                        <td>0.0003</td>
                </tr>
        </tbody>
</table>

<p>(差值计算公式为:(福禄克45+福禄克18)/2-GD32F310)</p>

<p>0.00V图片:</p>

<p> &nbsp;</p>

<p>1.00V截图</p>

<p>&nbsp; 2.0V截图</p>

<p>&nbsp; 3.0V截图</p>

<p>&nbsp; 3.30V截图</p>

<p>&nbsp; 【总结】经过测评,GD32的ADC可以说非常让人佩服,相比我用过的其他32位的12ADC表现出不错的成绩。如果采用高精度的分压电阻,可以实现4位的电压电流表是木得问题的。</p>

serialworld 发表于 2022-5-9 18:20

<p>MCU不需要外接基准?</p>

lugl4313820 发表于 2022-5-9 18:33

serialworld 发表于 2022-5-9 18:20
MCU不需要外接基准?

<p>不用列,只直外挂电压输入的。</p>

lugl4313820 发表于 2022-5-9 20:05

<p>附视频如下:</p>

<p><iframe allowfullscreen="true" frameborder="0" height="510" src="https://training.eeworld.com.cn/shareOpenCourseAPI?isauto=true&amp;lessonid=33371" style="background:#eee;margin-bottom:10px;" width="700"></iframe><br />
&nbsp;</p>

m1185498705 发表于 2024-6-1 23:42

<p>这个代码可以用一下?</p><br/>

lugl4313820 发表于 2024-6-2 08:25

m1185498705 发表于 2024-6-1 23:42
这个代码可以用一下?

<p>过去了很久了,换了电脑了。核心代码都在帖子里了。</p>

赵小军 发表于 2024-8-21 18:06

<p>大佬们好!谁有GD32F310的例程源码,刚学不会,买你们的源码来学习</p>
页: [1]
查看完整版本: 【GD32F310G-START】电压表