请选择 进入手机版 | 继续访问电脑版

你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】基于STM32G4芯片的DAC应用示例

[复制链接]
STMCU小助手 发布时间:2021-12-8 22:00
有人使用STM32G431芯片做DAC应用,具体来说就是通过DMA将数据从指定内存传送给DAC数据寄存器,并由定时器触发DAC转换。他发现总是没法实现该功能。这里简单介绍下相关实现过程,并做些提醒。这里要演示的基本功能就是让DAM将内存数据周期性传输给DAC数据寄存器,最后输出一路正弦波。

8c8aec0947a9e081baa317138ac945de.png



结合STM32G4芯片的特性,这里可以有两种实现方式。

第一种,DMA的请求来自于DAC1的转换事件。第二种,DMA的请求来自于定时器事件,下面用到的是定时器的更新事件。这里就两种实现方式的配置及相关用户代码简单介绍下,以供参考。

我们先看第一种方式,即DMA请求来自DAC转换事件,定时器3触发DAC的转换。

使用CubeMx进行配置,主要配置如下:
d1020b7d0f8f4894eb7b709ab4cbed6d.png



ddd67d8a4616146cdf0ec6419da513ec.png


0f1f5180cdc185196607e3ef27b9e215.png


完成配置后生成初始代码,再添加下面代码即可验证测试:

  1. #define   Tpai     (2*3.14159)

  2. uint32_t  PData[200],Dac_data;

  3. uint16_t     i;

  4. for (i=0;i<200;i++)

  5. {undefined

  6. PData<i>=</i>

  7. (uint32_t ) (2000*(sin((Tpai/200)*i))+2000);

  8. } //prepare data for DAC

  9. HAL_DAC_Start_DMA(&hdac1,DAC_CHANNEL_1,(uint32_t*)&PData[0],  200,DAC_ALIGN_12B_R);

  10. __HAL_TIM_ENABLE(&htim3);
复制代码



上面配置的DMA传输方向是从内存到外设,目的和源的访问宽度都是32位WORD. 当然也可以是内存访问宽度为16位的半字,外设访问宽度为32位字。即DMA的配置像下面这样也是可以的。

d1a3b9537ab66535982e8b0cb86d3bbc.png


其它配置不动,代码稍微改动和整理下即可。参见下面代码:

  1. Uint16_t  PData[200],Dac_data;

  2. #define   Tpai (2*3.14159)

  3. uint16_t     i;

  4. for (i=0;i<200;i++)

  5. {undefined

  6. PData=

  7. (uint16_t )(2000*(sin((Tpai/200)*i))+2000);

  8. } //prepare data for DAC

  9. SET_BIT(hdac1.Instance->CR,DAC_CR_DMAEN1);



  10. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );

  11. HAL_Delay(2);



  12. HAL_DMA_Start_IT(&hdma_dac1_ch1,(uint32_t)&PData[0],(uint32_t)&DAC1->DHR12R1, 200);



  13. __HAL_TIM_ENABLE(&htim3);
复制代码




第一种方式就介绍到这里,再来看看第二种实现方式,即TIMER更新事件作为DMA请求源,同时作为DAC转换触发源。

基于CubeMx配置,主要调整下DMA配置,其它配置基本不动。




主要是DMA请求事件变了,其它配置跟第一种模式基本一样。

配置完成后生成初始化代码,再添加下面用户代码:

  1. #define   Tpai     (2*3.14159)

  2. uint16_t PData[200], Dac_data;

  3. uint16_t     i;

  4. for (i=0;i<200;i++)

  5. {undefined

  6. PData=

  7. (uint16_t )(2000*(sin((Tpai/200)*i))+2000);

  8. }

  9. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );

  10. HAL_Delay(3);



  11. HAL_DMA_Start(&hdma_tim3_up,(uint32_t)&PData[0],(uint32_t)&DAC1->DHR12R1, 200);



  12. __HAL_TIM_ENABLE_DMA(&htim3, TIM_DMA_UPDATE);

  13. __HAL_TIM_ENABLE(&htim3);
复制代码


这里要提醒一点,G4系列的DAC1的数据保持寄存器可以一次放2个通道的数据,在使用DMA传输时,即使只用到1个通道,DMA对它的访问也要遵循WORD对齐,不然你可能会遇到麻烦。

如果说,我们不使用DMA做数据传输,只是手动给DAC喂数据,那如何实现上述效果呢?这时我们可以使用软件触发DAC的传输,手动给DAC的数据保持寄存器赋值,参考配置及实现代码如下:

81958bbf0c7325cd86a0ecbf4dc138ef.png



相关用户代码如下:

  1. #define   Tpai (2*3.14159)

  2. uint16_t PData[200],Dac_data;

  3. uint16_t     i;

  4. for (i=0;i<200;i++)

  5. {undefined

  6. PData<span style="font-style: italic;"><span style="font-style: normal;">=

  7. (uint16_t)(2000*(sin((Tpai/200)*i))+2000);

  8. }

  9. HAL_DAC_Start(&hdac1,DAC_CHANNEL_1 );

  10.    HAL_Delay(3);



  11. while(1)

  12. {undefined

  13. for(i=0;i<200;i++)

  14. {undefined

  15. DAC1->DHR12R1= PData</span><span style="font-style: normal;">;

  16. SET_BIT(hdac1.Instance->SWTRIGR,DAC_SWTRIGR_SWTRIG1);

  17.       HAL_Delay(5);



  18. Dac_data = DAC1->DOR1;//for debug



  19. }

  20. }
  21. </span></span>
复制代码

总之,不论使用哪种方式,都可以实现我们所期望的结果,即输出如下正弦波。

692bd68b1c31d5aa2a4b73541244f56e.png


好,关于STM32G4的DAC应用就简单介绍到这里,STM32G4系列的模拟外设丰富而强大,此处算是抛砖引玉。这里做些分享也是为了让其他有需要的人少走弯路,加速开发进程。【文中代码都很简短、直观,就没做注释说明了。还有个客观原因就是在微信公众号里排版也很费劲,字符不太好对齐。若有需要交流的可以后台留言。】


79bba335bff508c4f57300f0f57049de.png
收藏 评论0 发布时间:2021-12-8 22:00

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版