ADS8688驱动(FPGA)

ADS8688 为 16 位采样芯片,最大采样范围 − 10.24 V ∼ + 10.24 V -10.24V\sim+10.24V 10.24V+10.24V ,最大采样率 500 k S P S 500 kSPS 500kSPS,8 采样通道,每个通道都可支持双极性 ± 10.24 V \pm 10.24V ±10.24V ± 5.12 V \pm 5.12V ±5.12V ± 2.56 V \pm 2.56V ±2.56V,单极性 0 ∼ 10.24 V 0\sim 10.24V 010.24V 0 ∼ 5.12 V 0\sim 5.12V 05.12V

FPGA驱动代码如下

// 16位采样芯片 ADS8688 的FPGA驱动
// author	: 今朝无言
// date		: 2022.03.02
// 说明		: 本模块采用循环模式依次采样8个通道
module ads8688(
input				rst_n,					// FPGA 复位信号(下降沿动作)
input				CLK_50M,				// 50 MHz时钟输入

output	reg			RST	= 1,				// ADS8688 复位信号
output	reg			SDI,					// ADS8688 串行数字输入
output	reg			CS,						// ADS8688 片选信号(低电平有效)
output				SCLK,					// ADS8688 串行时钟
input				SDO,					// ADS8688 串行数字输出

input				datacs,					// 模块数据使能信号
input				RDdata					// 读使能信号
input		[3:0]	dataAddr,				// 数据通道,0~7
output	reg	[15:0]	out						// 采样数据
);

reg		[6:0]	cnt;
reg		[2:0]	order	= 0;				// 状态标志
reg		[15:0]	ch_sel;						// 配置寄存器,用于选择采样通道、设置采样电压范围等
reg		[15:0]	rddat;
reg		[15:0]	rddat0, rddat1, rddat2, rddat3, rddat4, rddat5, rddat6, rddat7;
wire			CLK_16_7M;

assign	SCLK	= ~CS & CLK_16_7M;

// 时钟分频模块
clkdiv clk_inst						
(
	.clk	(CLK_50M),
	.div	(16'd3),
	.clkout	(CLK_16_7M)
);

// 数据读取
always @(posedge CLK_50M or negedge rst_n)
begin
	if(!rst_n)
		out	<= 16'd0;						// 复位
	else if(datacs & RDdata) begin
		case(dataAddr)		
			4'd0: out	<= rddat0;
			4'd1: out	<= rddat1;
			4'd2: out	<= rddat2;
			4'd3: out	<= rddat3;
			4'd4: out	<= rddat4;
			4'd5: out	<= rddat5;
			4'd6: out	<= rddat6;
			4'd7: out	<= rddat7;
		default: ;
		endcase
	end
end

// SPI通信
always @(posedge CLK_16_7M or negedge rst_n)
begin
	if(!rst_n) begin
		cnt		<= 1'b0;
		CS		<= 1'b0;
		RST		<= 1'b0;
		order	<= 3'd0;
	end
	else begin
		RST		<= 1'b1;
		if(cnt < 7'd50)
		begin
			CS	<= 1'b1;
			cnt	<= cnt + 1'b1;
		end
		else if(cnt >= 7'd50 && cnt <= 7'd82)
		begin
			CS	<= 0;
			cnt	<= cnt + 1'b1;
		end

		if(cnt > 7'd82)								// 准备结束, 开始转换
		begin
			if(order==3'd0)
			begin
				ch_sel	<= 16'hC400;				//写控制字,指示下个通道选中通道1
				order	<= 3'd1;
				rddat7	<= rddat;					//读数据,此数据来自通道7
            end										//本次设置的控制字,下个周期才会生效(采样),再下个周期才能读到数据
			if(order==3'd1)
			begin
				ch_sel	<= 16'hC800;				//写控制字,指示下个通道选中通道2
				order	<= 3'd2;
				rddat0	<= rddat;					//读数据,此数据来自通道0     下同理
			end
			if(order==3'd2)
			begin
				ch_sel	<= 16'hCC00;
				order	<= 3'd3;
				rddat1	<= rddat;
			end
			else if(order==3'd3)
			begin 
				ch_sel	<= 16'hD000;
				order	<= 3'd4;
				rddat2	<= rddat;
			end
			else if(order==3'd4)
			begin 
				ch_sel	<= 16'hD400;
				order	<= 3'd5;
				rddat3	<= rddat;
			end
			else if(order==3'd5)
			begin 
				ch_sel	<= 16'hD800;
				order	<= 3'd6;
				rddat4	<= rddat;
			end
			else if(order==3'd6)
			begin 
				ch_sel	<= 16'hDC00;
				order	<= 3'd7;
				rddat5	<= rddat;
			end
			else if(order==3'd7)
			begin
				ch_sel	<= 16'hC000;				//写控制字,指示下个通道选中通道0
				order	<= 3'd0;
				rddat6	<= rddat;
			end
			CS	<= 1'b1;							// 一次转换结束, 拉高CS, 准备下一次配置与转换
			cnt	<= 7'd40;
		end
	end
end

always @(posedge CLK_16_7M or negedge rst_n)
begin
	if(!rst_n)
	begin
		SDI	<= 0;
	end
	else begin
		case (cnt)
			7'd50: SDI	<= ch_sel[15];			// 配置寄存器以选择转换通道、采样电压范围
			7'd51: SDI	<= ch_sel[14];
			7'd52: SDI	<= ch_sel[13];
			7'd53: SDI	<= ch_sel[12];
			7'd54: SDI	<= ch_sel[11];
			7'd55: SDI	<= ch_sel[10];
			7'd56: SDI	<= ch_sel[9];
			7'd57: SDI	<= ch_sel[8];
			7'd58: SDI	<= ch_sel[7];
			7'd59: SDI	<= ch_sel[6];
			7'd60: SDI	<= ch_sel[5];
			7'd61: SDI	<= ch_sel[4];
			7'd62: SDI	<= ch_sel[3];
			7'd63: SDI	<= ch_sel[2];
			7'd64: SDI	<= ch_sel[1];
			7'd65: SDI	<= ch_sel[0];
		endcase
	end
end

always @(negedge CLK_16_7M or negedge rst_n)
begin
	if(!rst_n)
	begin
		rddat	<= 0;
	end
	else if(order >= 3'd0) begin
		case(cnt)
			7'd67: rddat[15]	= SDO;			// 读取采样值
			7'd68: rddat[14]	= SDO;
			7'd69: rddat[13]	= SDO;
			7'd70: rddat[12]	= SDO;
			7'd71: rddat[11]	= SDO;
			7'd72: rddat[10]	= SDO;
			7'd73: rddat[9]		= SDO;
			7'd74: rddat[8]		= SDO;
			7'd75: rddat[7]		= SDO;
			7'd76: rddat[6]		= SDO;
			7'd77: rddat[5]		= SDO;
			7'd78: rddat[4]		= SDO;
			7'd79: rddat[3]		= SDO;
			7'd80: rddat[2]		= SDO;
			7'd81: rddat[1]		= SDO;
			7'd82: rddat[0]		= SDO;
		endcase
	end	
end

endmodule

  • 6
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 15
    评论
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

今朝无言

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值