- UID
- 1029342
- 性别
- 男
|
给TLC2355写一个驱动,由EPM570控制它采样,TLC2355为14位串行AD,采样率达3.5M(串行时钟可达63M,63M/18=3.5M),其实只要弄懂这个串行AD的操作时序,写起代码就比较简单了。最后板上调试的时候比较顺利,用信号发生器给信号,采的结果比较好。
部分代码如下:
说明:输入时钟clk=25M,AD采样率1M,检测到start_conv上升沿,启动信号AD转换,采样70000个数据停止采样(实际应用中start_conv是由串口发送指令控制的)
- module TLC2355_single_conv(
- clk, //25M
- // clk_10m,
- start_conv,
- //stop_conv,
- LTC2355_SCK,
- LTC2355_SDO,
- ADdata_en,
- // State,
- AD_data,
- LTC2355_CONV //1M
- );
- //input clk_10m;
- output ADdata_en;
- output [15:0] AD_data;
- //output [4:0] State;
- input clk;
- input start_conv;
- //input stop_conv;
- output LTC2355_SCK;
- input LTC2355_SDO;
- output LTC2355_CONV;
- ////////////////////////////////////////
- reg start_conv_tmp;
- reg start_conv_tmp1;
- wire start_pulse;
- always @ (posedge clk) //1MHz
- begin
- start_conv_tmp <= start_conv;
- start_conv_tmp1 <= start_conv_tmp;
- end
- assign start_pulse = start_conv_tmp1&&(~start_conv_tmp);
- //////////////////////////////////////////////////////////////
- /*
- reg stop_conv_tmp;
- reg stop_conv_tmp1;
- wire stop_pulse;
- always @ (posedge clk)
- begin
- stop_conv_tmp <= stop_conv;
- stop_conv_tmp1 <= stop_conv_tmp;
- end
- assign stop_pulse = stop_conv_tmp1&&(~stop_conv_tmp);*/
- ////////////////////////////////////////////////////////////////////
- parameter NUMBER=17'd70000;
- reg [16:0] ad_num;
- always @ (posedge clk)
- if(start_pulse)
- ad_num <= 0;
- else if(ad_num==NUMBER)
- ad_num <= 0;
- else if(cnt==24)
- ad_num <= ad_num + 1;
- reg LTC2355_CONV_en;
- always @ (posedge clk)
- if(start_pulse)
- LTC2355_CONV_en <= 1;
- else if(ad_num==NUMBER)
- LTC2355_CONV_en <= 0;
- ////////////////////////////////////////////////////////
- reg [4:0] cnt;
- always @ (posedge clk) //25M/25=1MHz
- if(cnt==24)
- cnt <= 0;
- else if(LTC2355_CONV_en)
- cnt <= cnt + 1;
- else
- cnt <= 0;
- reg [4:0] state;
- always @ (negedge clk) //falling edge
- if(LTC2355_CONV && LTC2355_CONV_en)
- state <= 5'd31;
- else
- begin
- case(state)
- 5'd31: state <= 5'd0;
- 5'd0: state <= 5'd1;
- 5'd1: state <= 5'd2;
- 5'd2: state <= 5'd3;
- 5'd3: state <= 5'd4;
- 5'd4: state <= 5'd5;
- 5'd5: state <= 5'd6;
- 5'd6: state <= 5'd7;
- 5'd7: state <= 5'd8;
- 5'd8: state <= 5'd9;
- 5'd9: state <= 5'd10;
- 5'd10: state <= 5'd11;
- 5'd11: state <= 5'd12;
- 5'd12: state <= 5'd13;
- 5'd13: state <= 5'd14;
- 5'd14: state <= 5'd15;
- 5'd15: state <= 5'd16;
- 5'd16: state <= 5'd17;
- 5'd17: state <= 5'd17;
- default:;
- endcase
- end
- ///////////////////////////////////////////
- reg AD_bit;
- always @ (negedge clk)
- AD_bit <= LTC2355_SDO;
- reg [13:0] AD_data_reg;
- always @ (negedge clk)
- if(state>1&&state<16)
- AD_data_reg <= {AD_data_reg[12:0],AD_bit};
- reg conv_over;
- //wire ADdata_en;
- always @ (negedge clk)
- if(state==16)
- conv_over <= 1;
- else
- conv_over <= 0;
- assign ADdata_en = conv_over && (ad_num==0)||(ad_num==1); //must last long enough
- //AD_clk 50MHz ==>50M/18= 2.77MHz < 3.5MHz
- assign LTC2355_SCK = clk;
- assign LTC2355_CONV = (cnt==1) ? 1 : 0;
- //assign ADdata_en = start_pulse ? 1 : 0; just for debug
- assign AD_data = {2'b00,AD_data_reg};//ADdata_en ? {2'b00,AD_data_reg} : 16'bz;
- endmodule
|
|