FPGA Verilog 单芯片控制双AD7606芯片
前言
控制双ad7606的目的是因为所需要的通道数12,单个ad7606只有8个通道,因此需要控制2个ad7606满足12个通道的采样需求。
一、模式选择
1 转换之后进行读取:由这个图片可以确定ca cb 以及cs 信号的工作状态
2 串行读取模式:由这个图片可以确定sclk 与 数据读取的工作状态
3 数据存储以及发送:使用一个16位的寄存器对16个通道的数据进行依次保存,保存完之后立即发送出去,具体就是保存完ad通道1的数据后,里面发送出去,发送需要的时间比较长,因此发送结束之前就能够进行下一通道的采集。因此我的sclk是受控的,不是完全连续的。
二、AD7606 FPGA实现
1.ad7606部分
代码如下:
module ad7606(
input clk,
input res,
input dout_a, //ad7606通道a输入串行读取数据
input dout_b, //ad7606通道b输入串行读取数据
input ad_busy, //ad7606输入busy信号
input caiji_flag, //外界输入开始数据采集的标志
// output wire caiji_over,
output reg ad_ch_over, //ad8个通道采集over标志
output reg [3:0] stata,
output reg [4:0] cnt_bite,
output reg [5:0] cnt,
// output wire [15:0] crc_real,
output wire data_tx,
output wire start_ad_one,
output wire start_ad_two,
output wire crc_flag,
output reg crc_realflag,
output wire data_overflag,
output wire data_code,
output dis_clk ,
output dis_cs ,
output dis_miso ,
output dis_ca ,
output dis_busy ,
output reg [15:0]databuffa,
// output reg [15:0]data_ch,
output wire [15:0] datatx,
// output reg [15:0]databuffb,
output reg ad_cs, //读ad7606的使能信号
output reg ad_cs2, //读ad7606的使能信号
output reg ad_rd, //读ad7606的时钟信号
output reg ad_convstab //ad7606开始转换信号,低电平有效
);
/**----------------------ad工作ca cs rd信号 -------------------------------------**/
//输出信号
always@(posedge clk or negedge res)
if(!res)
ad_convstab <= 1'b1;
else if(stata == AD_CONV)
ad_convstab <= 1'b0;
else
ad_convstab <= 1'b1;
always@(posedge clk or negedge res)
if(!res)
ad_cs <= 1'b1;
else if(stata == WAIT_1 && ad_busy == 1'b0 && start_ad_one == 1'b1)
ad_cs <= 1'b0;
else if(stata == READ_STOP)
ad_cs <= 1'b1;
else
ad_cs <= ad_cs;
always@(posedge clk or negedge res)
if(!res)
ad_cs2 <= 1'b1;
else if(stata == WAIT_1 && ad_busy == 1'b0 && start_ad_two == 1'b1)
ad_cs2 <= 1'b0;
else if(stata == READ_STOP)
ad_cs2 <= 1'b1;
else
ad_cs2 <= ad_cs2;
always@(posedge clk or negedge res)
if(!res)
ad_rd <= 1'b1;
else if(stata == READ_CH1 || stata == READ_CH2 || stata == READ_CH3 || stata == READ_CH4 || stata == READ_CH5 || stata == READ_CH6 || stata == READ_CH7 || stata == READ_CH8)
if(cnt == (FIV_CLK-1) && cnt_bite < 16)
ad_rd <= 1'b0;
else if(cnt == 2*FIV_CLK-1 && cnt_bite < 16)
ad_rd <= 1'b1;
else
ad_rd <= ad_rd;
else
ad_rd <= 1'b1;
/**-----------------------------------------------------------------------------**/
/**----------------------缓存串行数据 -------------------------------------------**/
//处理输入的串行数据
always@(posedge clk or negedge res)
if(!res)begin
databuffa <= 16'd0;
end
else if(stata == READ_CH1 || stata == READ_CH2 || stata == READ_CH3 || stata == READ_CH4 || stata == READ_CH5 || stata == READ_CH6 || stata == READ_CH7 || stata == READ_CH8)begin
if(cnt == FIV_CLK && ad_rd == 1'b0 && ad_cs == 1'b0)begin
databuffa <= {databuffa[14:0],dout_a};
end
else if(cnt == FIV_CLK && ad_rd == 1'b0 && ad_cs2 == 1'b0)begin
databuffa <= {databuffa[14:0],dout_b};
end
else begin
databuffa <= databuffa;
end
end
else begin
databuffa <= 16'd0;
end
//将采集到的数据存储到data_ch中
always@(posedge clk or negedge res)
if(!res)begin
data_ch <= 16'd0;
end
else if(stata == READ_CH1 && cnt_bite == (CNT_CLK) )begin
data_ch <= databuffa ;
end
else if((stata == READ_CH2 || stata == READ_CH3 || stata == READ_CH4 || stata == READ_CH5 || stata == READ_CH6 || stata == READ_CH7 ||stata == READ_CH8 ) && cnt_bite == (CNT_CLK -1))begin
data_ch <= databuffa ;
end
else begin
data_ch <= data_ch ;
end
endmodule
2.数据发送
该部分就是一个简单的并行转串行模块