什么是ADC
DAC 是一种用于将数字信号转换为模拟信号的数字模拟转换器。我们知道,数字信号是离散的,仅能取有限的值。而模拟信号则是连续的,其取值可以在一定范围内任意变化。DAC 的工作原理是将数字信号通过解码转换为对应的电压或电流等模拟量,再通过滤波等处理,最终得到平滑连续的模拟信号。DAC 的分辨率越高(即能表示的数字量位数越多),转换出的模拟信号就越接近理想的连续信号,精度也就越高,不过这通常需要更复杂的电路设计和更高的成本。
DAC 的基本原理
DAC(数模转换器)是一种电子设备,用于将离散的数字信号转换为对应的连续模拟信号。这种转换过程涉及到几个基本原理:
- 解码:DAC 首先对数字信号进行解码。这意味着它将输入的二进制数字代码转换为对应的模拟量(如电压)的基本分量。解码过程基于数字信号的每一位权重,将二进制位转换为相应的模拟值分量。
- 重建:解码后的模拟分量被组合在一起,形成一个阶梯状的模拟信号。这个信号是离散的,对应于输入数字信号的各个采样点。
- 滤波:重建后的阶梯状信号通过低通滤波器进行平滑处理,去除高频分量,形成连续的模拟信号。
- 输出:最后,平滑后的连续模拟信号被输出到负载或者其他模拟设备,以供后续处理或使用。
这些基本原理构成了 DAC 的工作方式,使得它能够将数字系统(如微处理器、FPGA 等)产生的数字信号转换为模拟形式,以驱动模拟设备或与模拟环境进行交互。DAC 的性能指标(如分辨率、精度、建立时间等)直接影响转换后的模拟信号的质量和系统的整体性能。
DAC 的基础参数
分辨率:表示DAC转换器的输出精度,通常以位数(bit)表示,A6E2开发板是12位D/ a转换器。而 12 位 DAC 则可以表示 2¹²(4096)个值。位数越高,DAC 的输出精度越高,能够表示的模拟信号细节越丰富。
输出范围:指 DAC 能够输出的模拟信号的电压或电流范围。例如,一个输出范围为 0-3.3V 的 DAC 可以将数字输入转换为该范围内的任意电压值。输出范围通常由参考电压(VREF)决定,与 ADC 不同,DAC 的输出范围可以通过外部电路进行调整和扩展。
DAC12 I/O pins
引脚名称 | 输入/输出 | 功能 |
---|---|---|
AVCC0 | 输入 | ● 是ADC12、DAC12和TSN的模拟电源及模拟参考电压正端引脚。 ● 当这些模块不使用时,连接到VCC。 |
AVSS0 | 输入 | ● 是ADC12、DAC12和TSN的模拟地及模拟参考地引脚。 ● 当这些模块不使用时,连接到VSS。 |
VREFH0 | 输入 | DAC12的模拟参考电压正端引脚 |
VREFL0 | 输入 | DAC12的模拟参考地引脚 |
DA0 | 输出 | 通道0输出引脚为模拟信号,由DAC12控制 |
DA1 | 输出 | 通道1输出引脚为模拟信号,由DAC12处控制 |
DAC 实验
使用地奇星开发板的DAC功能实现一个阶梯波。
注:工程是 uart 的工程基础上进行开发的。
配置引脚 在 FSP Configuration -> Pins -> Peripherals -> Analog:DAC12 -> DAC120 接下来我们需要配置Operation Mode 选择 Enabled ,如下图所示:
接下来,添加 DAC 的模块, New Stack -> Analog -> DAC(r_dac) ,如下图所示:
接下来我们选择 DAC 模块,然后点击属性,然后放大,如下图所示:
需要修改的内容如下图所示:
程序编写
#include "Apply\app.h"
#include "uart\bsp_uart.h"
#include "dac\bsp_dac.h"
void Run(void)
{
uint16_t dac_value = 0;
float voltage = 0.0f;
UART0_Init();
DAC_Init();
printf("欢迎使用立创·地奇星RA6E2开发板\r\n");
printf("接下来开始 DAC 输出实验;\r\n");
while(1)
{
if(voltage>3.3)
{
voltage=0.0;
}
printf("输出电压=%.2f\r\n",voltage);
dac_value = Voltage_Transition(voltage);
DAC_Set_Value(dac_value);
voltage=voltage+0.1f;
R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_MILLISECONDS);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#ifndef __APP_H
#define __APP_H
#include "hal_data.h"
#include <stdio.h>
void Run(void);
#endif
2
3
4
5
6
7
8
9
#include "bsp_dac.h"
void DAC_Init(void)
{
fsp_err_t err = R_DAC_Open(&dac0_ctrl,&dac0_cfg);
if (err != FSP_SUCCESS)
{
printf("DAC初始化失败\r\n");
}
err = R_DAC_Start(&dac0_ctrl);
if (err != FSP_SUCCESS)
{
printf("DAC启动失败\r\n");
R_DAC_Close(&dac0_ctrl); // 关闭已打开的资源
}
}
void DAC_Set_Value(uint16_t Value)
{
fsp_err_t err = R_DAC_Write(&dac0_ctrl,Value);
if(err != FSP_SUCCESS)
{
printf("DAC通达打开失败\r\n");
}
}
uint16_t Voltage_Transition(float Value)
{
return (uint16_t)((Value/3.3f)*4095);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#ifndef __BSP_DAC_H_
#define __BSP_DAC_H_
#include "hal_data.h"
#include "uart\bsp_uart.h"
void DAC_Set_Value(uint16_t Value);
void DAC_Init(void);
uint16_t Voltage_Transition (float Value);
#endif
2
3
4
5
6
7
8
9
10
#include "hal_data.h"
#include "Apply\app.h"
FSP_CPP_HEADER
void R_BSP_WarmStart(bsp_warm_start_event_t event);
FSP_CPP_FOOTER
/*******************************************************************************************************************//**
* main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used. This function
* is called by main() when no RTOS is used.
**********************************************************************************************************************/
void hal_entry(void)
{
/* TODO: add your own code here */
Run();
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
实验现象
我这里是使用示波器进行波形抓取的,如下图所示: