[研电赛技术支持] 【GD32F303红枫派使用手册】第十四讲 DAC-输出电压实验

[复制链接]
2385|0
 楼主| 聚沃科技 发表于 2024-6-13 09:37 | 显示全部楼层 |阅读模式
红枫派首图.png
14.1 实验内容
通过本实验主要学习以下内容:
• DAC工作原理
使用DAC输出电压
14.2 实验原理
14.2.1 DAC工作原理
我们上几章学习了ADC,本章我们来学习DACADC是模-数转换,即模拟量转换为数字量,DAC正好相反,即数-模转换,是将MCU的数字量转换为模拟量——电压。
GD32F303有两个DAC,对应的IO口分别为PA4DAC0)和PA5DAC1),这两个DAC可以独立或并发工作。DAC可以将 12 位的数字数据转换为外部引脚上的电压输出。数据可以采用8位或12位,左对齐或右对齐模式。
如设置12位模式,IO口上输出的电压值和设置的数字值对应的计算公式为:
636d2d55-e817-41c1-b715-e5b1910d081b.png
其中VREF为参考电压,DAC_DO为设置的数字值。
DAC 的主要特征如下:
◼ 8 位或 12 位分辨率,数据右对齐或左对齐;
支持 DMA 功能;
同步更新转换;
外部事件触发转换;
可配置的内部缓冲区;
外部参考电压, VREF+
噪声波形(LSFR 噪声模式和三角噪声模式)
DAC 并发模式  
以下为GD32F303 DAC的框图:
图片1.png
这里着重讲下DAC的触发源,DAC触发源通过DAC_CTL寄存器中 DTSELx 位来进行选择。DAC的触发源见下表:
f38f0b2dc3dc06faac490af7b7dccdd1.png
DAC有两个类型的数据寄存器——DAC保持数据寄存器(DACx_DH)和DAC 数据输出寄存器(DACx_DO),用户将数字量写入到DACx_DH中,只有当DACx_DH中的数据被转移到DACx_DO时,IO口才会实际输出对应电压值。
当使能了外部触发模式(通过设置 DAC_CTL 寄存器的 DTENx 位控制),当已经选择的触发事件发生, DAC 保持数据(DACx_DH)会被转移到 DAC 数据输出寄存器(DACx_DO)。如果没有使能外部触发模式,当数据写到DACx_DH后就会立即转移到DACx_DO中,此时相应IO口即输出对应电压。
14.2.2 DAC 输出缓冲
为了降低输出阻抗并驱动外部负载,每个DAC 模块内部各集成了一个输出缓冲区。
缺省情况下, 输出缓冲区是开启的,可以通过设置 DAC_CTL 寄存器的 DBOFFx 位来开启或关闭缓冲区。打开缓冲区可以增强DAC对外驱动能力。  
14.2.3 DAC  DMA 功能
在外部触发使能的情况下,通过设置 DAC_CTL 寄存器的DDMAENx 位来使能 DMA 请求。 当有外部硬件触发的时候(不是软件触发),则产生一个DMA 请求。  
14.3 硬件设计
本实验功能是将设定的数字值转换为电压,硬件设计如下:
图片2.png
可以看到是使用PA5DAC1输出电压,读者可以通过测量H9口进行电压测量
14.4 代码解析
14.4.1 DAC 配置函数
driver_dac.c中定义了DAC的配置函数driver_dac_config
  1. C
  2. void driver_dac_config(uint32_t dac_periph)
  3. {
  4.     /*使能GPIOA时钟*/
  5.     rcu_periph_clock_enable(RCU_GPIOA);
  6.     /*使能DAC时钟*/
  7.     rcu_periph_clock_enable(RCU_DAC);
  8.     /*依据选择的DAC号来初始化IO口*/
  9.     if(dac_periph == DAC0)
  10.     {
  11.         gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, GPIO_PIN_4);
  12.     }
  13.     else
  14.     {
  15.         gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, GPIO_PIN_5);
  16.     }
  17.     /*DAC复位*/
  18.     dac_deinit();
  19.     /*DAC外部触发禁能,即数据写入到保持寄存器就会自动输出电压*/
  20.     dac_trigger_disable(dac_periph);
  21.     /*DAC噪声关闭*/
  22.     dac_wave_mode_config(dac_periph, DAC_WAVE_DISABLE);
  23.     /*输出缓冲打开*/
  24.     dac_output_buffer_enable(dac_periph);  
  25.     /*DAC使能*/
  26.     dac_enable(dac_periph);  
  27. }
14.4.2 DAC数据写入函数
driver_dac.c中定义了DAC的数据写入函数driver_dac_out,调用这个函数后即将数字值写入到DAC数据保持寄存器中:
  1. C
  2. void driver_dac_out(uint32_t dac_periph, uint32_t dac_align, uint16_t data)
  3. {
  4.      /*写入数据到DAC保持寄存器*/
  5.     dac_data_set(dac_periph,dac_align,data);
  6. }
14.4.3 main函数实现
以下为main函数代码:
  1. C
  2. int main(void)
  3. {
  4.         driver_init();//delay函数初始化
  5.         bsp_uart_init(&BOARD_UART);//BOARD_UART串口初始化
  6.         driver_dac_config(DACx);//DAC配置
  7.         while (1)
  8.         {        
  9.                 delay_ms(200);//延时200ms
  10.                 DAC_data += 200;//DAC_data值自增加200
  11.                 if(DAC_data>4000)//DAC防止溢出
  12.                 {
  13.                         DAC_data = 0;               
  14.                 }
  15.                
  16.                 printf(" the DAC_data is %d \r\n", DAC_data);//打印DAC data数据
  17.                 driver_dac_out(DACx,DAC_ALIGN_12B_R,DAC_data);//输出电压
  18.         }
  19. }
本例程main函数首先进行了延时函数初始化,再配置开发板上的USB串口,接着进行DAC配置。DAC配置函数中的实参通过main.c中定义,读者可根据实际需求修改:
  1. C
  2. #define DACx DAC1
main函数主循环中每200ms自增DAC_data 值,并将该值写入到数据保存寄存器中,然后将DAC_data 值打印出来。
14.5 实验结果
使用外用表测量开发板H9接口上的电压值,可以看到电压循环从低到高的变化。
图片3.png
图片4.png

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



您需要登录后才可以回帖 登录 | 注册

本版积分规则

170

主题

190

帖子

13

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