ADS7828 八通道采样与 I2C 读取控制 Verilog Quartus
名称:ADS7828 八通道采样与 I2C 读取控制 Verilog Quartus
软件:Quartus
语言:Verilog
功能介绍
本工程使用 Verilog 实现 ADS7828 的 I2C 读取与八通道顺序采样控制,采用 Quartus 工程组织。顶层模块 ADS7828 接收采样触发信号,依次发起通道 0~7 的读取,并将各通道结果保存到独立的 12 位输出寄存器 AD_0~AD_7。
外部接口包括 clk_50M、高电平复位 reset_p、采样触发 trigger,以及 I2C 时钟 AD_scl 和双向数据线 AD_sda。空闲时接收到 trigger 上升沿后启动一轮采样,逐通道读取并更新结果,完成通道 7 后返回空闲状态,等待下一次触发。
工程适合用于学习 FPGA 与 ADS7828 的通信控制、单次读取驱动与多通道调度之间的握手,以及采样结果的寄存器保存方式。配套测试平台和模拟从机模型可用于仿真分析,帮助理解触发、通道切换和数据更新的时序关系。
运行环境
开发语言:Verilog。工程软件:Quartus,工程文件为 ADS7828.qpf 和 ADS7828.qsf,顶层模块为 ADS7828。仿真工程具有 ModelSim 工作目录及 NativeLink 仿真报告文件。
顶层时钟输入为 clk_50M,复位 reset_p 采用高电平异步复位形式。与外部器件连接的信号为 AD_scl 和双向 AD_sda;上层逻辑通过 trigger 发起采样,通过八路 12 位输出读取各通道结果。
设计思路
设计将八通道采样调度与单次 I2C 读取分开处理。顶层 ADS7828 管理触发、通道编号和结果寄存器,通过 drv_start、drv_cmd 向 ads7828_driver 发起读取,再通过 drv_sample、drv_done 接收结果与完成状态。这样的接口划分便于分别理解采样顺序和器件通信过程。
触发处理使用 trigger 的当前值与上一拍值生成上升沿脉冲。顶层处于空闲状态时接收该脉冲,设置 busy 并启动通道 0;忙碌期间继续执行当前采样序列,不对新触发进行排队。gen_cmd 函数按通道编号生成控制字节,通道 0~7 分别对应 8'h8C、8'hCC、8'h9C、8'hDC、8'hAC、8'hEC、8'hBC、8'hFC。
通道推进采用完成信号边沿握手。drv_done 上升沿到来时,顶层将 drv_sample 写入当前通道寄存器;如果尚未完成通道 7,则更新通道编号和控制字节,并设置 wait_next。随后等待 drv_done 下降沿再发出下一次启动脉冲,以衔接驱动返回空闲的过程。通道 7 完成后清除 busy,结束本轮采样。
八路结果按通道逐次更新,因此一轮采样过程中,各输出寄存器的更新时间不同。集成到其他逻辑时,应结合这一更新方式安排数据读取;若应用需要整组数据同时交付,可围绕采样序列结束条件扩展整组有效标志或缓存逻辑。
模块结构
ADS7828 为顶层采样控制模块,负责 trigger 上升沿检测、busy 状态管理、通道编号推进、控制字节生成,以及 AD_0~AD_7 的结果保存。
ads7828_driver 为顶层实例化的 ADS7828 I2C 读取驱动,通过 start 和 command 接收请求,通过采样数据及 done 信号与顶层交互,对外连接 AD_scl、AD_sda。
tb_ads7828 为仿真测试平台,fake_ads7828_slave 为模拟从机模块,便于围绕采样与通信流程进行仿真分析。另有 iic_com 和 i2c 两个通信相关模块,可结合完整代码查看其接口与调用关系。
仿真图/仿真说明/设计文档图片
仿真分析可结合 tb_ads7828 测试平台、fake_ads7828_slave 模拟从机,以及 i2c.vcd 波形文件展开。重点观察 trigger 触发后 drv_start 与 drv_cmd 的变化、drv_done 的上升沿和下降沿,以及 AD_0~AD_7 的逐通道更新过程。
检查通道切换时,可同时关注 ch_idx、wait_next 和 drv_done,确认结果写入与下一通道启动之间的握手关系;结合 AD_scl、AD_sda 观察通信时序,可进一步分析顶层调度与驱动执行的对应关系。
部分代码
以下展示顶层模块 ADS7828 的部分代码,完整源码请下载压缩包查看。
module ADS7828(
input clk_50M,//
input reset_p, //高电平分为
output AD_scl, // I2C时钟
inout AD_sda, // I2C数据线(双向)
input trigger ,//采样触发信号(脉冲信号),高电平时触发一次通道0~7的采样
output reg [11:0] AD_0, // 通道0转换结果
output reg [11:0] AD_1, // 通道1转换结果
output reg [11:0] AD_2, // 通道2转换结果
output reg [11:0] AD_3, // 通道3转换结果
output reg [11:0] AD_4, // 通道4转换结果
output reg [11:0] AD_5, // 通道5转换结果
output reg [11:0] AD_6, // 通道6转换结果
output reg [11:0] AD_7 // 通道7转换结果
);
// 与驱动模块交互的信号
reg drv_start;
reg [7:0] drv_cmd;
wire [11:0] drv_sample;
wire drv_done;
// 触发检测与通道序列控制
reg trigger_d;
wire trigger_pulse = trigger & ~trigger_d;
always @(posedge clk_50M or posedge reset_p) begin
if (reset_p) trigger_d <= 1'b0;
else trigger_d <= trigger;
end
reg [2:0] ch_idx;
reg busy;
reg wait_next;
reg done_d;
wire done_rise = drv_done & ~done_d;
wire done_fall = ~drv_done & done_d;
always @(posedge clk_50M or posedge reset_p) begin
if (reset_p) done_d <= 1'b0;
else done_d <= drv_done;
end
// 控制字节生成(内部参考)
function [7:0] gen_cmd;
input [2:0] ch;
begin
case (ch)
3'd0: gen_cmd = 8'h8C;
3'd1: gen_cmd = 8'hCC;
3'd2: gen_cmd = 8'h9C;
3'd3: gen_cmd = 8'hDC;
3'd4: gen_cmd = 8'hAC;
3'd5: gen_cmd = 8'hEC;
3'd6: gen_cmd = 8'hBC;
3'd7: gen_cmd = 8'hFC;
default: gen_cmd = 8'h8C;
endcase
end
endfunction
// 顶层采样顺序状态机:收到trigger后顺序采样0~7通道
always @(posedge clk_50M or posedge reset_p) begin
if (reset_p) begin
drv_start <= 1'b0;
drv_cmd <= 8'h8C;
ch_idx <= 3'd0;
busy <= 1'b0;
AD_0 <= 12'd0; AD_1 <= 12'd0; AD_2 <= 12'd0; AD_3 <= 12'd0;
AD_4 <= 12'd0; AD_5 <= 12'd0; AD_6 <= 12'd0; AD_7 <= 12'd0;
end else begin
// 默认不启动
drv_start <= 1'b0;
if (!busy) begin
if (trigger_pulse) begin
busy <= 1'b1;
ch_idx <= 3'd0;
drv_cmd <= gen_cmd(3'd0);
wait_next<= 1'b0;
drv_start<= 1'b1; // 发起通道0
end
end else begin
// 正在采样序列
if (done_rise) begin
// 完成一个通道,写入结果
case (ch_idx)
3'd0: AD_0 <= drv_sample;
3'd1: AD_1 <= drv_sample;
3'd2: AD_2 <= drv_sample;
3'd3: AD_3 <= drv_sample;
3'd4: AD_4 <= drv_sample;
3'd5: AD_5 <= drv_sample;
3'd6: AD_6 <= drv_sample;
3'd7: AD_7 <= drv_sample;
default: ;
endcase
if (ch_idx == 3'd7) begin
busy <= 1'b0; // 序列结束
wait_next <= 1'b0;
end else begin
ch_idx <= ch_idx + 3'd1;
drv_cmd <= gen_cmd(ch_idx + 3'd1);
wait_next<= 1'b1; // 等待驱动回到IDLE后再启动
end
end else if (wait_next && done_fall) begin
drv_start <= 1'b1; // 驱动已回到IDLE,启动下一个通道
wait_next <= 1'b0;
end
end
end
end
// 实例化ADS7828 I2C读驱动
ads7828_driver u_drv (
.clk_50M (clk_50M),
.reset_p (reset_p),
.AD_scl (AD_scl),
.AD_sda (AD_sda),
.start (drv_start),
.command (drv_cmd),
// ... 以下代码略,完整源码请下载压缩包查看
代码文件(付费下载)
2、支付问题请联系微信公众号客服。
3、优质Verilog/VHDL代码资源,所见即所得。
Verilog/VHDL资源下载 » ADS7828 八通道采样与 I2C 读取控制 Verilog Quartus