【GD32 MCU入门教程】四、GD32 MCU 常见外设介绍(13)DAC 模块介绍

[复制链接]
1640|1
 楼主| 聚沃科技 发表于 2024-8-22 09:25 | 显示全部楼层 |阅读模式
本帖最后由 聚沃科技 于 2024-9-18 15:59 编辑

DAC是一种把二进制数字量形式的离散信号转换成以标准量(或参考量)为基准的模拟量的转换器,它常用于过程控制计算机系统的输出通道,与执行器相连,实现对生产过程的自动控制。
13.1.GD32 DAC 外设原理简介
因篇幅有限,本文无法详细介绍GD32所有系列的DAC,下面以GD32F30x为例,先着重介绍下GD32F30x的DAC及其结构框图,然后介绍下各个系列DAC的差异。
GD32F30x DAC 主要特性
◼ 8位或12位分辨率,数据左对齐或右对齐;
◼ 每个通道带有DMA功能;
◼ 同步更新转换;
◼ 外部事件触发转换;
◼ 可配置的内部缓冲区;
◼ 输入参考电压VREF+;
◼ 噪声波生成(LSFR噪声模式和三角噪声模式);
◼ 双DAC并发模式。
DAC 结构框图介绍
1.png
GD32F30x一共有两个DAC,分别为DAC0和DAC1,其输出DAC_OUT0和DAC_OUT1分别对应PA4和PA5。由于DAC输出为模拟量,因此在使能DAC模块前,需要把相应的GPIO口设置为模拟模式。DAC的输出集成了输出缓冲器Buff,可用来降低输出阻抗,并在不增加外部运算放大器的情况下直接驱动外部负载。通过设置DAC_CTL寄存器的DBOFFx位,可以使能或禁止各DAC通道输出缓冲器。
DAC的输出可以由多种触发源控制,触发源的选择由DAC_CTL寄存器的DTSELx[2:0]位控制,具体为:
000:TIMER5_TRGO
001:TIMER2_TRGO(互联型产品)
TIMER7_TRGO(非互联型产品)
010:TIMER6_TRGO
011:TIMER4_TRGO
100:TIMER1_TRGO
101:TIMER3_TRGO
110:EXTI9
111:SWTRIG
有两种方式可以将噪声波加载到DAC输出数据:LFSR噪声波和三角波。噪声波模式可以通过DAC_CTL寄存器的DWMx位来进行选择。噪声的幅值可以通过配置DAC_CTL寄存器的DAC噪声波位宽(DWBWx)位来进行设置。
LFSR噪声模式:为了生成可变振幅的伪噪声,可使用LFSR(线性反馈移位寄存器)。LFSR的值与DACx_DH值相加后写入到DAC数据输出寄存器(DACx_DO)。LFSR中的预加载值为0xAAA,在每次触发事件发生后,该寄存器的值会依照特定的算法完成更新。
三角波模式:在DAC的输出信号上可以叠加一个小幅度的三角波。该三角波幅值的最小值为0,最大值为(2<<DWBWx)-1。DAC叠加三角波噪声的波形图如下图所示。
2.png
DAC可以实现8位或者12位分辨率,也可以实现数据左对齐或者右对齐,这取决于用户的实际需求。当分辨率为12位时,DAC的模拟输出电压与数字量的关系为:
3.png
上式中,DAC_DO为DAC数据输出寄存器的值,VREF+为DAC的参考电压,其范围为2.6V~VDDA。
每个DAC通道都具有DMA功能。两个DMA通道分别用于处理DAC通道的DMA请求。当DAC_CTL寄存器的DDMAENx置位时,如果发生了外部触发(而不是软件触发),则将产生DMA请求。
各系列 DAC 功能差异
GD32系列MCU有关DAC外设各系列功能差异如下表所示
4.png
13.2.软件配置说明
本小节讲解DAC_Example历程中DAC模块的配置说明,主要包括外设时钟配置、GPIO引脚配置、DAC外设配置、主函数介绍以及运行结果。本例程主要介绍GD32 MCU各系列DAC0模块输出模拟电压,有关DAC其他功能例程可参考各系列固件库例程。
外设时钟配置
外设时钟配置如代码清单DAC例程时钟配置所示,在GD32全系列MCU中需打开GPIOA和DAC0的时钟,因为使用到PA4引脚以及DAC0模块。
代码清单 DAC 例程时钟配置
  1. void rcu_config(void)
  2. {
  3. rcu_periph_clock_enable(RCU_GPIOA);
  4. rcu_periph_clock_enable(RCU_DAC);
  5. }
GPIO 引脚配置
GPIO引脚配置如代码清单DAC例程GPIO引脚配置所示,GD32F10X、GD32F20X、GD32F30X、GD32E10X、GD32F403系列GPIO配置相同;GD32F1X0、GD32F4XX、GD32F350系列GPIO配置相同。注意,以上所呈现的不同,只是调用gpio初始化函数不同,配置是一样的,都是把PA4配置为模拟模式。
代码清单 DAC 例程 GPIO 引脚配置
  1. void gpio_config(void)
  2. {
  3. #if defined (GD32F10X_HD)||(GD32F20X_CL)||(GD32F30X_HD)||(GD32E10X)
  4. gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, GPIO_PIN_4);
  5. #elif defined (GD32F1X0) || (GD32F4XX) || defined (GD32F350)
  6. gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_4);
  7. #endif
  8. }
DAC 外设配置
DAC外设配置如代码清单 DAC例程DAC外设配置所示。GD32全系列MCU中DAC外设配置基本相同,在本例程中,配置DAC为软件触发,每当使能一次软件触发,DAC就会把DAC数据寄存器的值转换为模拟电压输出。
代码清单 DAC 例程 DAC 外设配置
  1. void dac_config(void)
  2. {
  3. #if defined (GD32F10X_HD)||(GD32F20X_CL)||(GD32F30X_HD)||(GD32F4XX)||(GD32E10X)
  4. dac_deinit();
  5. dac_trigger_enable(DAC0);
  6. dac_trigger_source_config(DAC0,DAC_TRIGGER_SOFTWARE);
  7. /* enable DAC */
  8. dac_enable(DAC0);
  9. #elif defined (GD32F350)
  10. dac_deinit();
  11. dac_trigger_enable();
  12. dac_trigger_source_config(DAC_TRIGGER_SOFTWARE);
  13. /* enable DAC */
  14. dac_enable();
  15. #elif defined (GD32F1X0)
  16. dac_deinit();
  17. dac0_trigger_enable();
  18. dac0_trigger_source_config(DAC_TRIGGER_SOFTWARE);
  19. /* enable DAC */
  20. dac0_enable();
  21. #endif
  22. }
主函数说明
主函数如代码清单 DAC例程主函数所示,该主函数主要分成四部分,RCU时钟配置、GPIO配置、DAC外设配置和while(1)循环,前三部分已在前三小节介绍,在while(1)主循环中先设置一下DAC将要输出的模拟电压值,然后使能软件触发输出该模拟电压,延时一段时间后,再设置新的模拟电压值,如此循环。dac_value_set函数用于设置模拟输出电压值,单位为mV。delay函数是一个简单的软件延时函数,用于实现延时。这两个函数的代码清单如代码清单DAC例程部分函数说明所示。
代码清单 DAC 例程主函数
  1. int main(void)
  2. {
  3. /* peripheral clock enable */
  4. rcu_config();
  5. /* GPIO config */
  6. gpio_config();
  7. /* DAC config */
  8. dac_config();
  9. while(1)
  10. {
  11. #if defined (GD32F10X_HD)||(GD32F20X_CL)||(GD32F30X_HD)||(GD32F4XX)||(GD32E10X)
  12. dac_value_set(1000);//1000mV
  13. dac_software_trigger_enable(DAC0);
  14. delay(2000);
  15. dac_value_set(2000);//2000mV
  16. dac_software_trigger_enable(DAC0);
  17. delay(2000);
  18. #elif defined (GD32F350)
  19. dac_value_set(1000);//1000mV
  20. dac_software_trigger_enable();
  21. delay(2000);
  22. dac_value_set(2000);//2000mV
  23. dac_software_trigger_enable();
  24. delay(2000);
  25. #elif defined (GD32F1X0)
  26. dac_value_set(1000);//1000mV
  27. dac0_software_trigger_enable();
  28. delay(2000);
  29. dac_value_set(2000);//2000mV
  30. dac0_software_trigger_enable();
  31. delay(2000);
  32. #endif
  33. }
  34. }
代码清单 DAC 例程部分函数说明
  1. /*!
  2. \brief set DAC output voltage
  3. \param[in] vol: output voltage, unit: mV
  4. \param[out] none
  5. \retval none
  6. */
  7. static void dac_value_set(uint16_t vol)
  8. {
  9. uint16_t dac_reg_value;
  10. dac_reg_value = vol*4096.0/3300;
  11. #if defined (GD32F10X_HD)||(GD32F20X_CL)||(GD32F30X_HD)||(GD32F4XX)||(GD32E10X)
  12. dac_data_set(DAC0,DAC_ALIGN_12B_R,dac_reg_value);
  13. #elif defined (GD32F350)
  14. dac_data_set(DAC_ALIGN_12B_R,dac_reg_value);
  15. #elif defined (GD32F1X0)
  16. dac0_data_set(DAC_ALIGN_12B_R,dac_reg_value);
  17. #endif
  18. }
  19. /*!
  20. \brief delay
  21. \param[in] cnt: delay count
  22. \param[out] none
  23. \retval none
  24. */
  25. static void delay(uint16_t cnt)
  26. {
  27. while(cnt--);
  28. }
运行结果
将DAC_Example例程按照对应的芯片工程编译完成后,下载到对应芯片中,用示波器查看PA4引脚波形,如下图图DAC输出电压波形图所示,可以看到,DAC输出的模拟电压与我们所设置的值是一样的。
7c3c2125658f6d7bfc1b2156aaf5d3ec.png
13.3.DAC 使用注意事项
(1) 在使能DAC模块前,GPIO口(PA4对应DAC0,PA5对应DAC1)应该配置为模拟模式;
(2) 将DAC_CTL寄存器中的DENx位置1可以给DAC上电。DAC子模块完全启动需要等tWAKEUP时间。
(3) 为了实现更好的输出带载能力,建议打开DAC的输出缓冲器。

教程由GD32 MCU方案商聚沃科技原创发布,了解更多GD32 MCU教程,关注聚沃科技官网,GD32MCU技术交流群:859440462

huquanz711 发表于 2024-8-24 19:40 来自手机 | 显示全部楼层
DAC外设主要用于音频处理
您需要登录后才可以回帖 登录 | 注册

本版积分规则

170

主题

190

帖子

13

粉丝
快速回复 在线客服 返回列表 返回顶部