ad采集板卡需要按照一定时序工作,工作部分教程相关代码已有现成例子,直接用即可。
always @(posedge ad_clk_i)
begin
if(ad_rst_o||ad_rst_i)begin
ad_convst <= 1'b1;
AD_S <= 2'd0;
end
else begin
case(AD_S)
2'd0:if(clk_en2)begin //即ad_sclk_o上升沿时
ad_convst <= 1'b0;
AD_S <= 2'd1;
end
2'd1:if(clk_en2)begin //延迟60ns,开始计时,即下一次ad_sclk_o上升沿
ad_convst <= 1'b1;
AD_S <= 2'd2;
end
2'd2:if(clk_en2&&ad_busy_i)//延迟60ns,busy 肯定为高
AD_S <= 2'd3;
2'd3:if(cycle_end)//等待转换结束
AD_S <= 2'd0;
endcase
end
end
该代码中,AD_S作为状态机,在0、1、2状态已经完成了ad板卡信号的控制工作,3状态则为等待状态,使采集的信号可以通过SPI传输出去。(教程中的状态机各个状态直接使用数字表示,状态含义不明,程序已经进行相应修改)
其中,cycle_end在每轮采样周期结束时升为高电平,采样时钟信号通过该信号可以控制ad板卡工作状态,实现按照设定的采样频率采样。例如,使用200KHz的采样时钟信号,则每5us,cycle_end信号会产生一次高电平脉冲,控制板卡采样状态机工作。
SPI通过移位操作实现数据传输。ad_out_i是ad板卡采样信号通过SPI传输后的输出内容,采样4路16位信号,可以理解成被合并为一个64位信号,每个SPI时钟周期会移位1个信号出来。此时使用移位操作将信号移入寄存器中即可实现数据传输功能。
//read spi adc data
always@(posedge ad_clk_i) begin
if(ad_rst_o) begin // 复位
ad_out_a <= 64'd0;
ad_out_b <= 64'd0;
nbits <= 8'd0;
end
else if(ad_cs_o)begin // ad_cs_o高电平时复位nbits
nbits <= 8'd0;
end
else if(cap_en)begin // SPI时钟下降沿进行移位操作,将采集信号移入寄存器
nbits <= nbits + 1'b1;
ad_out_a <= {ad_out_a[62:0],ad_out_a_i};
ad_out_b <= {ad_out_b[62:0],ad_out_b_i};
end
end
采集数据移位寄存入ad_out中,当移位操作完成后,即可读取ad_out中信号,此时ad_out就是存储本次采样后的采集数据。移位操作完成可以通过nbits判断,当nbits=64时,即可判定移位操作完成。
首先,对于采样周期的控制,只需要提供一个外部采样时钟信号即可,上述程序内,cycle_end信号逻辑设置为采样时钟信号上升沿时高电平即可。
之后,采集数据发送至子卡进行编码处理。子卡编码模块输入信号有三个关键信号:
需要设计相对应的采集数据预处理逻辑,将单通道64位数据转换为多通道16位数据,各个通道数据依次输出,输出各个通道数据过程中rd_en信号升为高电平。该部分逻辑在原来的程序中已有设计,可以参考借鉴。
另外,需要注意到,教程的程序使用的时钟是100Mhz,而编码模块的数据写时钟是200Mhz,数据预处理模块需要注意。
此外,在实际测试时,也需要注意到,ad7606板卡最大采样频率为200KHz,原来的数据传输系统中设置的采样时钟信号是2MHz,远高于最大采样频率,需要调整。
先基于原有教程代码进行修改,创建了一个AD采样的demo,并使用信号发生器生成正弦波信号源。
在ad_cap_en信号上升沿时读取各个通道的信号,实测可以抓取到正弦波信号。
目前正在将AD采样demo工程文件中程序对接到原来的数据传输工程文件中,AD采样功能已经完成,还需要编写数据预处理模块,将采样后获得的采集数据处理为多个通道的16位数据,便于数据编码模块接收。
使用外部的采样时钟信号控制ad采集,仿真测试,可以输出8路16位信号ad_out_8ch。
仔细观察仿真信号,发现在ad_cap_en信号下降沿时,采集数据ad_out_8ch会更新,因此数据预处理模块可以根据ad_cap_en信号下降沿作为标志,更新采集数据并寄存,之后再对寄存的数据进行处理,依次输出多通道16位信号。
本文章使用limfx的vscode插件快速发布