四、GD32 MCU 常见外设介绍 (13) DAC 模块介绍

DAC是一种把二进制数字量形式的离散信号转换成以标准量(或参考量)为基准的模拟量的转换器,它常用于过程控制计算机系统的输出通道,与执行器相连,实现对生产过程的自动控制。

13.1.GD32 DAC 外设原理简介

因篇幅有限,本文无法详细介绍GD32所有系列的DAC,下面以GD32F30x为例,先着重介绍下GD32F30x的DAC及其结构框图,然后介绍下各个系列DAC的差异。

GD32F30x DAC 主要特性

◼ 8位或12位分辨率,数据左对齐或右对齐;

◼ 每个通道带有DMA功能;

◼ 同步更新转换;

◼ 外部事件触发转换;

◼ 可配置的内部缓冲区;

◼ 输入参考电压VREF+;

◼ 噪声波生成(LSFR噪声模式和三角噪声模式);

◼ 双DAC并发模式。

DAC 结构框图介绍

输入图片说明

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叠加三角波噪声的波形图如下图所示。

输入图片说明

DAC可以实现8位或者12位分辨率,也可以实现数据左对齐或者右对齐,这取决于用户的实际需求。当分辨率为12位时,DAC的模拟输出电压与数字量的关系为:

输入图片说明

上式中,DAC_DO为DAC数据输出寄存器的值,VREF+为DAC的参考电压,其范围为2.6V~VDDA。

每个DAC通道都具有DMA功能。两个DMA通道分别用于处理DAC通道的DMA请求。当DAC_CTL寄存器的DDMAENx置位时,如果发生了外部触发(而不是软件触发),则将产生DMA请求。

各系列 DAC 功能差异

GD32系列MCU有关DAC外设各系列功能差异如下表所示

输入图片说明

13.2.软件配置说明

本小节讲解DAC_Example历程中DAC模块的配置说明,主要包括外设时钟配置、GPIO引脚配置、DAC外设配置、主函数介绍以及运行结果。本例程主要介绍GD32 MCU各系列DAC0模块输出模拟电压,有关DAC其他功能例程可参考各系列固件库例程。

外设时钟配置

外设时钟配置如代码清单DAC例程时钟配置所示,在GD32全系列MCU中需打开GPIOA和DAC0的时钟,因为使用到PA4引脚以及DAC0模块。

代码清单 DAC 例程时钟配置

void rcu_config(void)
{
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_DAC); 
}

GPIO 引脚配置

GPIO引脚配置如代码清单DAC例程GPIO引脚配置所示,GD32F10X、GD32F20X、GD32F30X、GD32E10X、GD32F403系列GPIO配置相同;GD32F1X0、GD32F4XX、GD32F350系列GPIO配置相同。注意,以上所呈现的不同,只是调用gpio初始化函数不同,配置是一样的,都是把PA4配置为模拟模式。

代码清单 DAC 例程 GPIO 引脚配置

void gpio_config(void)
{
#if defined (GD32F10X_HD)||(GD32F20X_CL)||(GD32F30X_HD)||(GD32E10X)
 gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, GPIO_PIN_4);
#elif defined (GD32F1X0) || (GD32F4XX) || defined (GD32F350)
 gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_4);
#endif
}

DAC 外设配置

DAC外设配置如代码清单 DAC例程DAC外设配置所示。GD32全系列MCU中DAC外设配置基本相同,在本例程中,配置DAC为软件触发,每当使能一次软件触发,DAC就会把DAC数据寄存器的值转换为模拟电压输出。

代码清单 DAC 例程 DAC 外设配置

void dac_config(void)
{
#if defined (GD32F10X_HD)||(GD32F20X_CL)||(GD32F30X_HD)||(GD32F4XX)||(GD32E10X)
 dac_deinit();
 dac_trigger_enable(DAC0);
 dac_trigger_source_config(DAC0,DAC_TRIGGER_SOFTWARE);
 /* enable DAC */
 dac_enable(DAC0);
#elif defined (GD32F350)
 dac_deinit();
 dac_trigger_enable();
 dac_trigger_source_config(DAC_TRIGGER_SOFTWARE);
 /* enable DAC */
 dac_enable();
#elif defined (GD32F1X0)
 dac_deinit();
 dac0_trigger_enable();
 dac0_trigger_source_config(DAC_TRIGGER_SOFTWARE);
 /* enable DAC */
 dac0_enable();
#endif 
}

主函数说明

主函数如代码清单 DAC例程主函数所示,该主函数主要分成四部分,RCU时钟配置、GPIO配置、DAC外设配置和while(1)循环,前三部分已在前三小节介绍,在while(1)主循环中先设置一下DAC将要输出的模拟电压值,然后使能软件触发输出该模拟电压,延时一段时间后,再设置新的模拟电压值,如此循环。dac_value_set函数用于设置模拟输出电压值,单位为mV。delay函数是一个简单的软件延时函数,用于实现延时。这两个函数的代码清单如代码清单DAC例程部分函数说明所示。

代码清单 DAC 例程主函数

int main(void)
{
 /* peripheral clock enable */
 rcu_config();
 /* GPIO config */
 gpio_config();
 /* DAC config */
 dac_config();
 while(1)
 {
 #if defined (GD32F10X_HD)||(GD32F20X_CL)||(GD32F30X_HD)||(GD32F4XX)||(GD32E10X)
 dac_value_set(1000);//1000mV
 dac_software_trigger_enable(DAC0);
 delay(2000);
 dac_value_set(2000);//2000mV
 dac_software_trigger_enable(DAC0);
 delay(2000);
 #elif defined (GD32F350)
 dac_value_set(1000);//1000mV
 dac_software_trigger_enable();
delay(2000);
 dac_value_set(2000);//2000mV
 dac_software_trigger_enable();
 delay(2000);
 #elif defined (GD32F1X0)
 dac_value_set(1000);//1000mV
 dac0_software_trigger_enable();
 delay(2000);
 dac_value_set(2000);//2000mV
 dac0_software_trigger_enable();
 delay(2000);
 #endif 
 }
}

代码清单 DAC 例程部分函数说明

/*!
 \brief set DAC output voltage
 \param[in] vol: output voltage, unit: mV
 \param[out] none
 \retval none
*/
static void dac_value_set(uint16_t vol)
{
 uint16_t dac_reg_value;
 dac_reg_value = vol*4096.0/3300;
#if defined (GD32F10X_HD)||(GD32F20X_CL)||(GD32F30X_HD)||(GD32F4XX)||(GD32E10X)
 dac_data_set(DAC0,DAC_ALIGN_12B_R,dac_reg_value);
#elif defined (GD32F350)
 dac_data_set(DAC_ALIGN_12B_R,dac_reg_value);
#elif defined (GD32F1X0)
 dac0_data_set(DAC_ALIGN_12B_R,dac_reg_value);
#endif 
}
/*!
 \brief delay
 \param[in] cnt: delay count
 \param[out] none
 \retval none
*/
static void delay(uint16_t cnt)
{
 while(cnt--);
}

运行结果

将DAC_Example例程按照对应的芯片工程编译完成后,下载到对应芯片中,用示波器查看PA4引脚波形,如下图图DAC输出电压波形图所示,可以看到,DAC输出的模拟电压与我们所设置的值是一样的。

输入图片说明

13.3.DAC 使用注意事项

(1) 在使能DAC模块前,GPIO口(PA4对应DAC0,PA5对应DAC1)应该配置为模拟模式;

(2) 将DAC_CTL寄存器中的DENx位置1可以给DAC上电。DAC子模块完全启动需要等tWAKEUP时间。

(3) 为了实现更好的输出带载能力,建议打开DAC的输出缓冲器。

更多GD32 MCU相关咨询:https://www.gd32bbs.com/ 

  • 15
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值