lugl4313820 发表于 2024-2-17 14:44

【ST NUCLEO-U5A5ZJ-Q开发板测评】ADC体验之二 DMA数据搬运工

<div class='showpostmsg'><p>STM32U5的DMA称之为GPDMA与LPDMA,在用户手册《RM0456》中有如下的介绍:</p>

<p>&nbsp; 我们常称之为数据搬动工。</p>

<p>我们的ADC数据转换也可以通过GPDMA来实现不需要CPU来控制转换,我们只需要在需要时去把转换好的数据取出来就行了,非常之方便。</p>

<p>【配置】</p>

<p>1、在上次实现ADC单片转换的工程上修改两个配置,一是<b>Conversion Data Management Mode,配置为</b>DMA circular mode,二是<b>DMA Continuous Requests使能。如下图所示。</b></p>

<p>&nbsp; 2、打开GPDMA设置,我这里设置了GPDMA1的通道10。模式我这里选用循环(circual)</p>

<p>&nbsp; 3、由于STM32U5的GPDMA需要用linked List来实现。所以需要添加自己的list配置:</p>

<p>&nbsp; 在ADCNode节点中我配置了Request Configuration为GPDMA1&mdash;&mdash;ADC1。长度为1word</p>

<p> &nbsp;</p>

<p>4、在以上配置结束后,生成代码。</p>

<p>5、添加用户代码,主要是引用linked_linst.h头文件,声明变量,还有就是定义一个32长度的用于存放ADC转换结果的数组aADCxConvertedData。</p>

<pre>
<code>#include "linked_list.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
extern ADC_HandleTypeDef hadc1;
extern DMA_HandleTypeDef handle_GPDMA1_Channel10;
extern DMA_NodeTypeDef ADCNode;
extern DMA_QListTypeDef ADCQueue;
#define ADC_CONVERTED_DATA_BUFFER_SIZE   ((uint32_t)32)   /* Size of array aADCxConvertedData[] */
/* Variable containing ADC conversions data */
uint32_t   aADCxConvertedData;</code></pre>

<p>6、接着我配置ADCQueue,并使用 LINKDMA把hadc与GPDMA1&mdash;&mdash;10连接起来。同时使能DMA转换,结果放在指定的数组之中。</p>

<pre>
<code>MX_ADCQueue_Config();
__HAL_LINKDMA(&amp;hadc1,DMA_Handle, handle_GPDMA1_Channel10);
if(HAL_DMAEx_List_LinkQ(&amp;handle_GPDMA1_Channel10, &amp;ADCQueue) != HAL_OK)
{
          Error_Handler();
}
if(HAL_ADC_Start_DMA(&amp;hadc1, (uint32_t *)aADCxConvertedData, (ADC_CONVERTED_DATA_BUFFER_SIZE)) != HAL_OK)
{
          Error_Handler();
}</code></pre>

<p>7、测试代码,在主循环中,我使用串口打印出32个转换数据,来观察效果,下载程序后效果如下:</p>

<p>&nbsp; 变化电压后,也反映非常的灵敏,说明GPDMA成功应用。</p>
</div><script>                                        var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;"   style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
                                       
                                        if(parseInt(discuz_uid)==0){
                                                                                                (function($){
                                                        var postHeight = getTextHeight(400);
                                                        $(".showpostmsg").html($(".showpostmsg").html());
                                                        $(".showpostmsg").after(loginstr);
                                                        $(".showpostmsg").css({height:postHeight,overflow:"hidden"});
                                                })(jQuery);
                                        }                </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>

lugl4313820 发表于 2024-2-17 15:00

<pre>
<code>while (1)
{
          total_val = 0;
          for(int i=0; i&lt;32;i++)
          {
                  total_val +=aADCxConvertedData;
          }
          printf("ADC VaL:%d voltage:%.4f \r\n   ", total_val/32, (float)(total_val/32)*3.3/16384);
          HAL_Delay(500);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
}</code></pre>

<p>使用平均法进行处理,发现数据波动会小很多:</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

HonestQiao 发表于 2024-2-18 17:58

lugl4313820 发表于 2024-2-17 15:00
while (1)
{
          total_val = 0;
          for(int i=0; i&lt;32;i++)
          {
                  total_val +=aADCxConve ...

<p>这是把ADC和DMA一次玩了个通透了,学习受教了!!!</p>

lugl4313820 发表于 2024-2-18 19:42

HonestQiao 发表于 2024-2-18 17:58
这是把ADC和DMA一次玩了个通透了,学习受教了!!!

<p>感谢帮主大佬的关注,我这是摸着石头过河,多谢是大佬您指点要深挖,不过还没有深入到寄存的操作,大佬们用寄存器,可能配置还要简单,效率还会更加高。</p>
页: [1]
查看完整版本: 【ST NUCLEO-U5A5ZJ-Q开发板测评】ADC体验之二 DMA数据搬运工