当前位置:AIGC资讯 > 数据采集 > 正文

双通道FPGA数据采集卡

采集卡指标:FPGA(altera)、AD(输入范围正负5V、AD9226、12bit、65MHz)、SDRAM(16bit数据位、13bit地址线)、串口(CH340)

1. 电路:
(1)FPGA最小系统:

(2)SDRAM:

(3)双路AD:

(4)PCB布局:

(5)实物图:

2. 程序:
依托双通路采集卡的电路板可以完成多种功能,这里面只展示一种,就是将两通道(每个采样率都为65MHz)的数据融合为一路(130MHz),然后在SDRAM中缓存,缓存一定量的数据之后,就将数据通过串口发送到上位机中。具体的程序如下所示:

module AD(
	input clk,
	input rst_n,
	
	input key_in0,					//按键0按下,开始存AD9226的数据
	input key_in1,					//按键1按下开始读取已经存下的数据
	output Rs232_Tx,
	
	input [11:0]ADA_IN,
	input [11:0]ADB_IN,
	
	output CLKA,
	output CLKB,
	output CLK_130M,
	
	output [11:0]Data_a,
	output [11:0]Data_b,
	output reg [11:0]Data,
	
	output reg[2:0]led
);
	
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n)
			led[2] <= 1'b0;
		else
			led[2] <= 1'b1;
	end
	
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n)
			led[0] <= 1'b0;
		else if(key_flag0 & !key_state0)
			led[0] <= 1'b1;
		else if(key_flag1 & !key_state1)
			led[0] <= 1'b0;
		else
			led[0] <= led[0];
	end
	
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n)
			led[1] <= 1'b0;
		else if(key_flag1 & !key_state1)
			led[1] <= 1'b1;
		else if(key_flag0 & !key_state0)
			led[1] <= 1'b0;
		else
			led[1] <= led[1];
	end
	
	
	//AD
	wire CLK_65M_P;
	wire CLK_65M_N;
	
	pll pll_inst (
		.areset 	( ~rst_n 	),
		.inclk0 	( clk 		),
		.c0 		( CLK_65M_P	),
		.c1		( CLK_65M_N ),
		.c2 		( CLK_130M 	)
	);
	
	assign CLKA = CLK_65M_P;
	assign CLKB = CLK_65M_N;
	assign Data_a = ADA_IN;
	assign Data_b = ADB_IN;
	
	
	//Integrate two channels of data
	reg flag;
	always@(posedge CLK_130M or negedge rst_n)begin
		if(!rst_n)
			flag <= 1'b0;
		else
			flag <= ~flag;
	end
	
	always@(posedge CLK_130M or negedge rst_n)begin
		if(!rst_n)
			Data <= 'd0;
		else if(flag)
			Data <= Data_a;
		else 
			Data <= Data_b;
	end
	
	//key
	wire key_flag0;
	wire key_state0;
	
	key_filter key_filter0(
		.clk			(clk  		),
		.rst_n		(rst_n		),
		.key_in		(key_in0 	),
		.key_flag	(key_flag0 	),
		.key_state	(key_state0 )
	);
	
	wire key_flag1;
	wire key_state1;
	
	key_filter key_filter1(
		.clk			(clk  		),
		.rst_n		(rst_n		),
		.key_in		(key_in1 	),
		.key_flag	(key_flag1 	),
		.key_state	(key_state1 )
	);

	
	//write 4096 Byte Data 
	reg  [19:0]wr_cnt;
	reg        data_in_req;
	
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n)
			data_in_req <= 1'b0;
		else if(key_flag0 & !key_state0)
			data_in_req <= 1'b1;
		else if(wr_cnt >= 'd4095)
			data_in_req <= 1'b0;
		else
			data_in_req <= data_in_req;
	end
	
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n)
			wr_cnt <= 'd0;
		else if(data_in_req)
			wr_cnt <= wr_cnt + 1'b1;
		else	
			wr_cnt <= 'd0;
	end
	
	wire [7:0]data_byte;
	
	FIFO	FIFO_inst (
		.data  	( Data[11:4]  	),
		.rdclk 	( clk       	),
		.rdreq 	( pos_tx_done 	),
		.wrclk 	( CLK_130M  	),
		.wrreq 	( data_in_req 	),
		.q     	( data_byte   	),
		.rdempty (  				),
		.wrfull 	(  				)
	);
	
	
	
	//Read data and sent out through serial port
	reg  send_en;
	wire tx_done;
	reg  tx_done_r;
	wire pos_tx_done;
	reg [19:0]tx_done_cnt;
	
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n)
			tx_done_r <= 1'b0;
		else
			tx_done_r <= tx_done;
	end
	
	assign pos_tx_done = tx_done & (!tx_done_r);
	
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n)
			tx_done_cnt <= 'd0;
		else if(pos_tx_done)
			tx_done_cnt <= tx_done_cnt + 1'b1;
		else
			tx_done_cnt <= tx_done_cnt;
	end
	
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n)
			send_en <= 1'b0;
		else if(key_flag1 & !key_state1)
			send_en <= 1'b1;
		else if(tx_done_cnt >= 'd4095)
			send_en <= 1'b0;
		else
			send_en <= send_en;
	end
	
	
	uart_byte_tx uart_byte_tx(
		.Clk			(clk			),
		.Rst_n		(rst_n		),
		.data_byte	(data_byte	),
		.send_en		(send_en		),
		.baud_set	(3'd4			),
		
		.Rs232_Tx	(Rs232_Tx	),
		.Tx_Done		(tx_done		),
		.uart_state	( 				)
	);
	

	

endmodule

3. 测试效果:

以上从电路到程序的展示就完成了,如果对电路资料和程序资料感兴趣的可以添加QQ:2859340499.

更新时间 2023-11-08