tinnu 发表于 2020-10-8 00:22

【GD32450I-EVAL】ADC:软件触发+中断+单次转换模式

<p><span style="font-size:24px;"><span style="font-family:楷体;">(一)ADC性能</span></span></p>

<p>GD32F450拥有3个ADC,每个ADC的采样速度最高可以达到2.6Mpsp,这还是在12位最高精度的条件下,如果降低精度还能更快。</p>

<p>&nbsp;</p>

<p><span style="font-size:24px;"><span style="font-family:楷体;">(二)ADC概念</span></span></p>

<p>GD32的各种设计与国外大厂的很像:</p>

<p>&nbsp;</p>

<p>1-注入组和规则组<br />
规则组为常规转换,注入组类似于中断,中间插入一次计划外的转换</p>

<p><br />
2-通道<br />
有3个ADC,每个ADC有19路通道,每个ADC的每个通道都映射到固定的引脚,这可以在数据手册中查询到。</p>

<p><br />
3-转换序列<br />
相当于一个工作队列,序列第一位的转化完,第二位的接着,全部转化完后可以重新再转化一轮<br />
规则组可以控制多达16个序列<br />
注入组少一点,只能支持4个序列</p>

<p>&nbsp;</p>

<p><span style="font-size:24px;"><span style="font-family:楷体;">(三)ADC与IO映射关系</span></span></p>

<p>每个ADC的每个通道都映射到固定的引脚</p>

<p>比如本次使用的PC3引脚</p>

<p></p>

<p>就是与ADC012三个ADC的IN13通道映射起来的,只要配置了PC3为模拟功能(AFIO),ADC任意一个使能了13通道就可以获取该引脚的模拟量值。</p>

<p>配置代码:</p>

<div aria-label="代码段 小部件" contenteditable="false" role="region" tabindex="-1">
<pre data-widget="codesnippet">
<code class="hljs language-cpp">
    <span class="hljs-comment">// config the GPIO as analog mode, for ADC </span>
    gpio_mode_set(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_3);</code></pre>
<img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" /><span style="background: url(&quot;https://bbs.eeworld.com.cn/static/editor/plugins/widget/images/handle.png&quot;) rgba(220, 220, 220, 0.5); top: -15px; left: 0px; display: block;"><img height="15" role="presentation" src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" title="点击并拖拽以移动" width="15" /></span></div>

<p>&nbsp;</p>

<p><span style="font-size:24px;"><span style="font-family:楷体;">(四)ADC寄存器</span></span></p>

<p>ADC的寄存器看上去不少,但实际上只使用规则组进行单个通道转化的时候绝大部分都是用不到的。</p>

<p>看门狗、过采样、注入、摘要这些都不需要管。</p>

<p>因为转换的只有一个通道,就不需要涉及多个通道轮流转换的问题(即转换序列),因此同步相关配置也暂时无用。</p>

<p>&nbsp;</p>

<p>所以需要配置的寄存器只有控制寄存器01、采样时间寄存器01、规则序列寄存器012</p>

<p>&nbsp;</p>

<p><span style="font-size:24px;"><span style="font-family:楷体;">(五)ADC配置流程</span></span></p>

<p>如果采用最简单的单次转化的工作方式,参考手册给出了配置流程:</p>

<p>看着有8步,实际上:</p>

<p>第1步是设置ADC工作方式,在单次转化中,这些相关位都是保持为0,即复位值,如果是初始化配置根本不需要理睬。</p>

<p>第4步是配置硬件触发方式</p>

<p>第5-8步都不是初始化的工作</p>

<p>即实际最简单初始化只需要做第2、3步</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p><span style="font-size:24px;"><span style="font-family:楷体;">(六)初始化</span></span></p>

<p>1-配置RSQ:</p>

<p>调用函数,设置该ADC有多少个序列,这里只有一个通道需要转换,只有一个序列:</p>

<div aria-label="代码段 小部件" contenteditable="false" role="region" tabindex="-1">
<pre data-widget="codesnippet">
<code class="hljs">    adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 1);</code></pre>
<img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" /><span style="background: url(&quot;https://bbs.eeworld.com.cn/static/editor/plugins/widget/images/handle.png&quot;) rgba(220, 220, 220, 0.5); top: -15px; left: 0px; display: block;"><img height="15" role="presentation" src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" title="点击并拖拽以移动" width="15" /></span></div>

<p>操作 ADC_RSQ0 的 RL位&nbsp;&nbsp; &nbsp;规则通道序列长度&nbsp;&nbsp; &nbsp;规则通道转换序列中的总的通道数目为 RL+1。<br />
操作 ADC_ISQ 的 TL 位&nbsp;&nbsp; &nbsp;注入通道组长度&nbsp;&nbsp; &nbsp;注入组总的通道数目为 IL+1。</p>

<p>参数功能:</p>

<p>2-规则组或者注入组</p>

<p>3-多少个序列</p>

<p>&nbsp;</p>

<p>2-配置SAMPT</p>

<p>设置具体哪个通道对应哪个序列</p>

<div aria-label="代码段 小部件" contenteditable="false" role="region" tabindex="-1">
<pre data-widget="codesnippet">
<code class="hljs language-cpp">adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_13, ADC_SAMPLETIME_15);
</code></pre>
<img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" /><span style="background: url(&quot;https://bbs.eeworld.com.cn/static/editor/plugins/widget/images/handle.png&quot;) rgba(220, 220, 220, 0.5); top: -15px; left: 0px; display: block;"><img height="15" role="presentation" src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" title="点击并拖拽以移动" width="15" /></span></div>

<p>操作寄存器的过程比较复杂,同时操作了 ADC_RSQ2 寄存器<br />
和操作 ADC_SAMPT1 寄存器&nbsp;&nbsp; &nbsp;设置通道采样时间</p>

<p>函数参数功能:</p>

<div aria-label="代码段 小部件" contenteditable="false" role="region" tabindex="-1">
<pre data-widget="codesnippet">
<code class="hljs language-cpp"><span class="hljs-comment">/*!
    \brief      configure ADC regular channel
    \paramadc_periph: ADCx,x=0,1,2
    \paramrank: the regular group sequencer rank,this parameter must be between 0 to 15
    \paramadc_channel: the selected ADC channel
                only one parameter can be selected which is shown as below:
      \arg      ADC_CHANNEL_x(x=0..18): ADC Channelx
    \paramsample_time: the sample time value
                only one parameter can be selected which is shown as below:
      \arg      ADC_SAMPLETIME_3: 3 cycles
      \arg      ADC_SAMPLETIME_15: 15 cycles
      \arg      ADC_SAMPLETIME_28: 28 cycles
      \arg      ADC_SAMPLETIME_56: 56 cycles
      \arg      ADC_SAMPLETIME_84: 84 cycles
      \arg      ADC_SAMPLETIME_112: 112 cycles
      \arg      ADC_SAMPLETIME_144: 144 cycles
      \arg      ADC_SAMPLETIME_480: 480 cycles
    \param none
    \retval   none
*/</span></code></pre>
<img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" /><span style="background: url(&quot;https://bbs.eeworld.com.cn/static/editor/plugins/widget/images/handle.png&quot;) rgba(220, 220, 220, 0.5); top: -15px; left: 0px; display: block;"><img height="15" role="presentation" src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" title="点击并拖拽以移动" width="15" /></span></div>

<p>2-第三个参数配置的通道,在规则组哪个序列</p>

<p>3-哪个通道</p>

<p>4-转换多少个时钟</p>

<p>&nbsp;</p>

<p><span style="font-size:24px;"><span style="font-family:楷体;">(七)使能中断功能</span></span></p>

<p>ADC的所有中断都在同一个中断向量里:</p>

<p>使能:</p>

<p>&nbsp;</p>

<div aria-label="代码段 小部件" contenteditable="false" role="region" tabindex="-1">
<pre data-widget="codesnippet">
<code class="hljs language-cpp">    <span class="hljs-comment">//ADC INT</span>
    adc_interrupt_enable(ADC0, ADC_INT_EOC);
    nvic_irq_enable(ADC_IRQn, <span class="hljs-number">2U</span>, <span class="hljs-number">0U</span>);</code></pre>
<img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" /><span style="background: url(&quot;https://bbs.eeworld.com.cn/static/editor/plugins/widget/images/handle.png&quot;) rgba(220, 220, 220, 0.5); top: -15px; left: 0px; display: block;"><img height="15" role="presentation" src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" title="点击并拖拽以移动" width="15" /></span></div>

<p>服务函数:</p>

<div aria-label="代码段 小部件" contenteditable="false" role="region" tabindex="-1">
<pre data-widget="codesnippet">
<code class="hljs language-cpp"><span class="hljs-keyword">void</span> ADC_IRQHandler(<span class="hljs-keyword">void</span>)
{
    uint16_t i=<span class="hljs-number">0</span>;
    <span class="hljs-keyword">char</span> t_char[<span class="hljs-number">30</span>] = <span class="hljs-string">&quot;&quot;</span>;
    <span class="hljs-keyword">if</span>(adc_interrupt_flag_get(ADC0, ADC_INT_FLAG_EOC)==SET)
    {
      i = adc_regular_data_read(ADC0);

      <span class="hljs-built_in">sprintf</span>(t_char, <span class="hljs-string">&quot;adc:%x\t%f\r\n&quot;</span>, i, (<span class="hljs-keyword">float</span>)i/<span class="hljs-number">0xFFF</span>*<span class="hljs-number">3.3</span>);
      PRINTF_UART0(t_char);
      adc_interrupt_flag_clear(ADC0, ADC_INT_FLAG_EOC);
    }
}
</code></pre>
<img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" /><span style="background: url(&quot;https://bbs.eeworld.com.cn/static/editor/plugins/widget/images/handle.png&quot;) rgba(220, 220, 220, 0.5); top: -15px; left: 0px; display: block;"><img height="15" role="presentation" src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" title="点击并拖拽以移动" width="15" /></span></div>

<p>&nbsp;</p>

<p><span style="font-size:24px;"><span style="font-family:楷体;">(八)软件启动转换</span></span></p>

<p>前面第五步提到,软件启动是置位 SWRCST ,这个位会硬件复位。对应库函数:</p>

<div aria-label="代码段 小部件" contenteditable="false" role="region" tabindex="-1">
<pre data-widget="codesnippet">
<code class="hljs language-cpp">adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL);</code></pre>
<img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" /><span style="background: url(&quot;https://bbs.eeworld.com.cn/static/editor/plugins/widget/images/handle.png&quot;) rgba(220, 220, 220, 0.5); top: -15px; left: 0px; display: block;"><img height="15" role="presentation" src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" title="点击并拖拽以移动" width="15" /></span></div>

<p>&nbsp;</p>

<p>在主循环中调用:</p>

<p>1-使能ADC并校准</p>

<div aria-label="代码段 小部件" contenteditable="false" role="region" tabindex="-1">
<pre data-widget="codesnippet">
<code class="hljs language-cpp">    <span class="hljs-comment">// enable ADC interface </span>
    adc_enable(ADC0);
    <span class="hljs-comment">// wait for ADC stability </span>
    delay_ms(<span class="hljs-number">1</span>);
    <span class="hljs-comment">// ADC calibration and reset calibration </span>
    adc_calibration_enable(ADC0);</code></pre>
<img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" /><span style="background: url(&quot;https://bbs.eeworld.com.cn/static/editor/plugins/widget/images/handle.png&quot;) rgba(220, 220, 220, 0.5); top: -15px; left: 0px; display: block;"><img height="15" role="presentation" src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" title="点击并拖拽以移动" width="15" /></span></div>

<p>2-主循环内</p>

<pre>
<code>    while(1){
      delay_ms(4);
               
                if(t_ledshark &gt;20){
                        t_ledshark = 0;
                        gd_eval_led_toggle(LED1);
            adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL);
                }
                t_ledshark++;
}</code></pre>

<p>&nbsp;</p>

<p><span style="font-size:24px;"><span style="font-family:楷体;">(九)效果</span></span></p>

<p></p>

<p>更清晰的视频等审核之后再传</p>

okhxyyo 发表于 2020-10-9 15:49

<p><a href="https://bbs.eeworld.com.cn/thread-1140981-1-1.html" target="_blank">兆易GD32450I-EVAL</a></p>

<p>汇总贴:<a href="https://bbs.eeworld.com.cn/thread-1140981-1-1.html">https://bbs.eeworld.com.cn/thread-1140981-1-1.html</a></p>

freebsder 发表于 2020-10-11 21:41

<p>写的很详细!大概看了下好像使用上差不多.</p>

啊啊啊啊啊1 发表于 2020-10-15 09:24

<p>好好好</p>

tinnu 发表于 2020-10-25 22:46

<p><iframe allowfullscreen="true" frameborder="0" height="450" src="http://player.youku.com/embed/XNDg5NDE0NjU5Mg" style="background:#eee;margin-bottom:10px;" width="750"></iframe><br />
补充个视频</p>
页: [1]
查看完整版本: 【GD32450I-EVAL】ADC:软件触发+中断+单次转换模式