HPMicro MCU片上DAC使用指南
HPMicro MCU片上DAC使用指南
1. 引言
DAC是数字模拟转换器(Digital-to-Analog Converter),它是一种将数字信号转换为模拟信号(以电流、电压或电荷的形式)的设备。在很多数字系统中(例如计算机,单片机),信号以数字方式存储和传输,而数字模拟转换器可以将这样的信号转换为模拟信号,从而使得它们能够被外界(人或其他非数字系统)识别。
2. HPMicro MCU片上DAC具有的特点
- 最大1MHz更新率
- 12位分辨率
- 内置DMA
- 支持中断
- 支持多种工作模式:直接模式、阶梯模式、内存模式
5. HPMicro MUC片上DAC具有的工作模式
-
直接模式(direct mode)
- 通过写12位数值到寄存器中,直接控制DAC输出相应电压
-
阶梯模式(step mode)
- DAC输出电压从起始值到终止值
- 可递增或递减
- 阶梯值可配置
- 到达终止值时,可控制DAC停止在终止值或回到起始值继续
- 最多支持4组阶梯配置,每组可独立配置
-
内存模式(buffer mode)
- 内存长度可设置,以4字节为单位
- 内存数据结构,可设置为32位表示1个点或2个点,低16位为第一个点,高16位为第二个点
- 内置DMA通过访问两段内存,以内存长度为单位,交替读取数据并控制DAC输出相应电压
6. 如何通过HPM SDK来使用HPMicro MCU片上的DAC?
-
DAC管脚初始化
-
设置指定管脚IO PAD的FUNC_CTL寄存器的BIT8(IOC_PAD_FUNC_CTL_ANALOG_MASK),用于隔离指定管脚所复用的数字功能
以HPM6300为例,PC03既有数字功能, 也有模拟功能:
因此对于此管脚需要使用模拟功能时,就需要隔离数字功能,程序设置如下:
void init_dac_pins(DAC_Type *ptr) { if (ptr == HPM_DAC) { HPM_IOC->PAD[IOC_PAD_PC03].FUNC_CTL = IOC_PAD_FUNC_CTL_ANALOG_MASK; } }
-
-
DAC时钟初始化
-
DAC时钟结构,HPMicro MCU的所有系列的用户手册上的功能时钟章节中都有时钟结构框图,如下图所示:
注:
-
目前HPMicro MCU片上DAC的时钟结构一般都具有两级(部分型号只有第二级),第一级为BUS时钟或者ANAn时钟,第二级为DAC时钟
-
BUS为AHB或AXI,由MCU的设计决定,具体可通过查阅SYSCTL寄存器中的DACCLK的MUX选择位来确认
-
-
设置DAC的输入时钟, 用于配置BUS时钟或者ANAn时钟
示例:以HPM6300为例,选择166MHz的ANA3时钟作为DAC0的输入时钟
a) 设置PLL0输出400MHz, 再设置CLK_TOP_ANA3时钟来源于PLL0CLK1的2分频输出, 因此得到166MHz的时钟pllctlv2_init_pll_with_freq(HPM_PLLCTLV2, pllctlv2_pll0, 400000000); /* PLL0 400MHz */ pllctlv2_set_postdiv(HPM_PLLCTLV2, pllctlv2_pll0, pllctlv2_clk1, pllctlv2_div_1p2); /* PLL0CLK1 333MHz */ clock_set_source_divider(clock_ana3, clk_src_pll0_clk1, 2) /* ANA3 166MHz */
b) 选择ANA3时钟作为DAC0的输入时钟
clock_set_dac_source(clock_dac0, clk_dac_src_ana3);
-
-
DAC初始化
DAC初始化分为两部分,模拟部分和数字部分, 其中模拟部分为通用属性,而数字部分分为三种模式:直接模式、阶梯模式、内存模式,下面以阶梯模式为例进行说明:
-
设置DAC通用属性
a) 通用设置结构体定义
typedef struct { bool sync_mode; /* 用于标记DAC的输入时钟与BUS时钟是否相同 */ uint8_t dac_mode; /* 用于设置DAC工作模式,可以选择直接模式、阶梯模式、内存模式 */ uint8_t ana_div; /* 用于设置DAC输入时钟分频系数 */ } dac_config_t;
b) 示例:设置DAC以阶梯模式输出,标记输入时钟与BUS不同
dac_config_t config; dac_get_default_config(&config); /* 默认设置ana_div为2分频 */ config.dac_mode = dac_mode_step; config.sync_mode = false; dac_init(BOARD_DAC_BASE, &config);
-
使能DAC
dac_enable_conversion(BOARD_DAC_BASE, true);
-
设置阶梯模式属性
a) 阶梯模式属性
阶梯模式设置结构体定义,如下:
typedef struct { uint16_t start_point; /* 起始点 */ uint16_t end_point; /* 终止点 */ uint8_t round_mode; /* 循环方式: 0表示步进停止,1表示步进循环 */ uint8_t up_down; /* 步进方向: 0表示向上,1表示向下 */ uint8_t step_num; /* 步进值 */ } dac_step_config_t;
示例:向上递增,从0起点到最大值点,步进量为1,步进循环
dac_step_config_t config0; printf("Set DAC to output data in step mode\n"); printf("DAC is outputting a saw tooth waveform in step mode\n"); /* saw tooth waveform */ config0.up_down = dac_step_up; config0.start_point = 0; config0.end_point = DAC_SOC_MAX_DATA; config0.step_num = 1; config0.round_mode = dac_round_mode_loop; dac_set_step_config(BOARD_DAC_BASE, DAC_STEP_CFG_IDX, &config0); dac_set_output_frequency(BOARD_DAC_BASE, clock_get_frequency(BOARD_APP_DAC_CLOCK_NAME), DAC_SOC_MAX_OUTPUT_FREQ);
b)触发源
-
硬件触发:通过硬件触发源,经过互联管理器(trigmux)到达DAC,触发DAC启动转换
- 具体指的是对于所选择的互联管理器的外设进行初始化(此处不做详解)
-
软件触发:通过调用如下API, 即可完成一次软件触发DAC转换
dac_set_step_sw_trigger(BOARD_DAC_BASE, 0); /* 软件触发阶梯模式的GROUP0 */
-
-
中断事件
DAC中断事件的定义如下:#define DAC_AHB_ERROR_EVENT DAC_IRQ_EN_AHB_ERROR_MASK /** AHB总线异常事件 */ #define DAC_FIFO_EMPTY_EVENT DAC_IRQ_EN_FIFO_EMPTY_MASK /** 缓冲模式缓冲区为空事件 */ #define DAC_BUF1_COMPLETE_EVENT DAC_IRQ_EN_BUF1_CMPT_MASK /** 缓冲模式缓冲区1完成事件 */ #define DAC_BUF0_COMPLETE_EVENT DAC_IRQ_EN_BUF0_CMPT_MASK /** 缓冲模式缓冲区0完成事件 */
此处,由于此篇文章仅讨论阶梯模式,未涉及相关中断,因此不对中断进行展开讨论
-
-
波形观察
根据上述设置,通过示波器测量DAC的输出管脚,观察所得如下波形: