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),
// ... 以下代码略,完整源码请下载压缩包查看

代码文件(付费下载)

📥 付费后此处显示完整工程压缩包下载链接。
1、代码文件需要付费后才可见。
2、支付问题请联系微信公众号客服。
3、优质Verilog/VHDL代码资源,所见即所得。
Verilog/VHDL资源下载 » ADS7828 八通道采样与 I2C 读取控制 Verilog Quartus

注册为本站会员,充值100得150,详情咨询客服

目前为止共有 *** 位优秀的会员加入! 立刻加入会员