【ST NUCLEO-U5A5ZJ-Q开发板测评】ADC体验之二 DMA数据搬运工
<div class='showpostmsg'><p>STM32U5的DMA称之为GPDMA与LPDMA,在用户手册《RM0456》中有如下的介绍:</p><p> 我们常称之为数据搬动工。</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> 2、打开GPDMA设置,我这里设置了GPDMA1的通道10。模式我这里选用循环(circual)</p>
<p> 3、由于STM32U5的GPDMA需要用linked List来实现。所以需要添加自己的list配置:</p>
<p> 在ADCNode节点中我配置了Request Configuration为GPDMA1——ADC1。长度为1word</p>
<p> </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——10连接起来。同时使能DMA转换,结果放在指定的数组之中。</p>
<pre>
<code>MX_ADCQueue_Config();
__HAL_LINKDMA(&hadc1,DMA_Handle, handle_GPDMA1_Channel10);
if(HAL_DMAEx_List_LinkQ(&handle_GPDMA1_Channel10, &ADCQueue) != HAL_OK)
{
Error_Handler();
}
if(HAL_ADC_Start_DMA(&hadc1, (uint32_t *)aADCxConvertedData, (ADC_CONVERTED_DATA_BUFFER_SIZE)) != HAL_OK)
{
Error_Handler();
}</code></pre>
<p>7、测试代码,在主循环中,我使用串口打印出32个转换数据,来观察效果,下载程序后效果如下:</p>
<p> 变化电压后,也反映非常的灵敏,说明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> <pre>
<code>while (1)
{
total_val = 0;
for(int i=0; i<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> </p>
<p> </p>
<p> </p>
lugl4313820 发表于 2024-2-17 15:00
while (1)
{
total_val = 0;
for(int i=0; i<32;i++)
{
total_val +=aADCxConve ...
<p>这是把ADC和DMA一次玩了个通透了,学习受教了!!!</p>
HonestQiao 发表于 2024-2-18 17:58
这是把ADC和DMA一次玩了个通透了,学习受教了!!!
<p>感谢帮主大佬的关注,我这是摸着石头过河,多谢是大佬您指点要深挖,不过还没有深入到寄存的操作,大佬们用寄存器,可能配置还要简单,效率还会更加高。</p>
页:
[1]