打印

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

[复制链接]
584|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
聚沃科技|  楼主 | 2024-8-22 09:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
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方案商聚沃科技原创发布,了解更多GD32 MCU教程,关注聚沃科技官网,GD32MCU技术交流群:859440462

使用特权

评论回复
沙发
huquanz711| | 2024-8-24 19:40 | 只看该作者
DAC外设主要用于音频处理

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

170

主题

190

帖子

7

粉丝