首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

利用CPLD控制TLC2355串行AD

利用CPLD控制TLC2355串行AD

给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
继承事业,薪火相传
返回列表