74HC4051+DAC80501实现一路模拟电压的8路复用
本文围绕多通道模拟信号复用与高精度DAC控制展开,结合74HC4051模拟多路复用器与DACx0501系列数模转换器,提出了一种高效的低频多通道电压输出解决方案。
一、74HC4051简介
1. 74HC4051原理
当同时需要输出或者采集8个低频的电压但是又为了要减少DAC/ADC的数量,可以使用多路复用器74HC4051。
74HC4051是一款8通道模拟多路复用器/解复用器,其核心功能是通过数字控制信号选择某一通道导通,与38译码器不同的是,74HC4051是模拟信号的导通,可以理解为导线的直接相连。导通是双向的。既可以在8路电压中选择一路输出,也可以将一路公共电压映射到8路输出的任意一路。
74HC4051的模拟开关本质是物理通道切换。当切换通道时,前一路的物理连接会被断开,芯片本身不会存储或维持之前通道的电压值。但是每个通道后端可以并联一个电容(时间常数τ=RC)以及一个运放,用于暂时的电压保持,因此74HC4051也需要不断地切换轮巡所有通道。避免电容放点时间过长,丧失电压保持的功能。
2. 74HC4051引脚定义


3. 74HC4051真值表
|
Input |
Channel ON |
|||
|
E_N |
C |
B |
A |
|
|
0 |
0 |
0 |
0 |
X0 to Z |
|
0 |
0 |
0 |
1 |
X1 to Z |
|
0 |
0 |
1 |
0 |
X2 to Z |
|
0 |
0 |
1 |
1 |
X3 to Z |
|
0 |
1 |
0 |
0 |
X4 to Z |
|
0 |
1 |
0 |
1 |
X5 to Z |
|
0 |
1 |
1 |
0 |
X6 to Z |
|
0 |
1 |
1 |
1 |
X7 to Z |
|
1 |
X |
X |
X |
switches off |
二、DACx0501
1. DACx0501简介
DACx0501是德州仪器(TI)推出的高精度、低功耗数模转换器(DAC)系列,包含16位的DAC80501、14位的DAC70501和12位的DAC60501三款型号。该系列专为工业、测试测量和通信等场景设计,具有以下核心特性:
1. 高精度与稳定性
分辨率与线性度:提供12-16位分辨率,最大积分非线性(INL)和微分非线性(DNL)均低于1LSB,确保输出信号的精确性。
内部基准电压:集成2.5V精密基准源,温度漂移低至5ppm/°C,支持1.25V、2.5V或5V的满量程输出电压范围,并可通过外部基准扩展灵活性。
2. 低功耗设计
工作电流仅1mA(5.5V供电时),在掉电模式下电流可降至15µA(典型值),适合电池供电或低功耗场景。
宽电源电压范围(2.7V至5.5V),兼容多种供电环境。
3. 灵活的接口与配置
数字接口:通过SPI2C引脚可切换为SPI或I²C模式。SPI模式下支持高达50MHz的时钟速率,I²C模式兼容标准(100kbps)、快速(400kbps)和快速+(1.0Mbps)速率。本文仅介绍其SPI模式。
上电复位功能:输出默认为零电平或中间电平,需写入有效代码后才会更新,防止系统启动时的不确定性
2. DACx0501配置
1.spi模式的数据帧格式
|
Bit24~21 |
Bit20~17 |
Bit16~1 |
|
0 |
4bit地址 |
8bit数据 |
2. 发送时序

3.寄存器
|
名称 |
地址 |
功能描述 |
关键字段/位定义 |
|
NOOP |
0x0 |
无操作寄存器,用于维持当前状态或填充通信帧。 |
命令位0000,无数据操作。 |
|
DEVID |
0x1 |
设备识别寄存器,读取芯片型号和版本信息。 |
RESOLUTION位标识DAC分辨率,RSTSEL保留位需置0。 |
|
SYNC |
0x2 |
同步控制寄存器,管理多DAC同步更新。 |
DAC_SYNC位控制同步模式,SYNC_EN使能硬件同步引脚。 |
|
CONFIG |
0x3 |
核心配置寄存器,控制参考电压、缓冲器和功耗模式。 |
REF_PWDWN(参考电压使能)、BUF_GAIN(输出缓冲增益)、DAC_PWD(DAC关断)。 |
|
GAIN |
0x4 |
增益校准寄存器,设置输出范围(如0-VREF或0-2VREF)。 |
BUF_GAIN位选择增益倍数(bit8置位:1/2,1x或bit0置位:2x),RESERVED位需置0。 |
|
TRIGGER |
0x5 |
触发控制寄存器,配置DAC更新触发方式。 |
LDAC位选择立即更新或同步触发,SOFT_RESET位触发软件复位。 |
|
STATUS |
0x7 |
状态监控寄存器,检测参考电压异常或配置错误。 |
REF_ALARM位指示参考电压故障,需通过写1清除标志。 |
|
DAC_DATA |
0x8 |
DAC数据寄存器,写入待转换的数字值(16~20位,取决于分辨率)。 |
数据位直接映射到模拟输出,需按分辨率对齐有效位。 |
4.verilog代码
// 顶层模块:DAC多路复用控制器
module dac_multiplexer (
input clk, // 系统时钟(如50MHz)
input reset_n, // 异步复位
// SPI接口
output spi_sclk, // SPI时钟
output reg spi_cs, // SPI片选(低有效)
output spi_mosi, // SPI主输出
input spi_miso, // SPI主输入(未使用)
// 74HC4051控制
output [2:0] mux_sel, // 通道选择ABC
output mux_en_n, // 使能信号(低有效)
// 状态指示
output reg [2:0] state_led // 状态机指示
);
// ---------- 参数定义 ----------
parameter NUM_CHANNELS = 8; // 复用通道数
parameter CLK_DIV = 16; // SPI时钟分频系数
parameter HOLD_TIME = 1000; // 电压保持时间(时钟周期数)
// ---------- 寄存器定义 ----------
reg [15:0] dac_data[0:7]; // 8通道DAC数据缓存
reg [23:0] spi_tx_data; // SPI待发送数据(4位保留+4位地址+16位数据)
reg [7:0] spi_counter; // SPI位计数器
reg [24:0] hold_counter; // 电压保持时间计数器
reg [2:0] current_channel; // 当前通道编号
// ---------- 状态机定义 ----------
typedef enum {
IDLE,
SPI_START,
SPI_TX,
CHANNEL_HOLD,
CHANNEL_SWITCH
} state_t;
reg [2:0] state;
// ---------- SPI时钟生成 ----------
reg [7:0] clk_div_counter;
reg spi_clk;
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
clk_div_counter <= 0;
spi_clk <= 0;
end else begin
if (clk_div_counter >= CLK_DIV/2 - 1) begin
clk_div_counter <= 0;
spi_clk <= ~spi_clk;
end else begin
clk_div_counter <= clk_div_counter + 1;
end
end
end
assign spi_sclk = (state == SPI_TX) ? spi_clk : 1'b0;
// ---------- 主状态机控制 ----------
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
state <= IDLE;
spi_cs <= 1'b1;
current_channel <= 3'b0;
hold_counter <= 0;
end else begin
case (state)
IDLE: begin
state_led <= 3'b001;
if (current_channel < NUM_CHANNELS-1)
current_channel <= current_channel + 1;
else
current_channel <= 0;
state <= SPI_START;
end
SPI_START: begin
state_led <= 3'b010;
spi_cs <= 1'b0;
spi_counter <= 23; // 24位数据长度
spi_tx_data <= {4'd0,4'h8, dac_data[current_channel]}; // DAC_DATA寄存器地址0x8
state <= SPI_TX;
end
SPI_TX: begin
state_led <= 3'b011;
if (spi_clk && spi_counter > 0) begin
spi_counter <= spi_counter - 1;
spi_tx_data <= spi_tx_data << 1;
end
if (spi_counter == 0) begin
spi_cs <= 1'b1;
state <= CHANNEL_HOLD;
end
end
CHANNEL_HOLD: begin
state_led <= 3'b100;
if (hold_counter < HOLD_TIME)
hold_counter <= hold_counter + 1;
else begin
hold_counter <= 0;
state <= CHANNEL_SWITCH;
end
end
CHANNEL_SWITCH: begin
state_led <= 3'b101;
mux_sel <= current_channel;
state <= IDLE;
end
endcase
end
end
// ---------- 74HC4051控制 ----------
assign mux_en_n = (state == CHANNEL_SWITCH) ? 1'b0 : 1'b1;
// ---------- SPI数据输出 ----------
assign spi_mosi = spi_tx_data[23];
// ---------- 初始化数据加载(示例) ----------
initial begin
// 初始化DAC数据缓存(可根据实际应用修改)
dac_data[0] = 16'h8000; // 通道0中间电平
dac_data[1] = 16'h4000; // 通道1 25%电平
dac_data[2] = 16'hC000; // 通道2 75%电平
// ... 其他通道初始化
end
endmodule
更多推荐



所有评论(0)