fpga_feixiang 发表于 2020-3-2 12:33:53

TLC549驱动的硬件编写

模块信号说明:
I_Adc_Data_In-------------------------------------------ADC输入的串行AD数据
O_CS_n----------------------------------------------------CS控制信号
O_Adc_Clk------------------------------------------------CLK控制时钟
O_Adc_Data_Vaild--------------------------------------标志Data_out端数据是否有效的指示端,有效时会输出一个高电平
O_Adc_Data_Out----------------------------------AD采样的8位数据,当Vaild端输出一个高电平脉冲后才表示有效

具体的FPGA程序如下:
module ADC_TLC549(
                I_Clk,
                I_Rst_n,
                I_Adc_Data_In,
                O_CS_n,
                O_Adc_Clk,
                O_Adc_Data_Out,
                O_Adc_Data_Vaild
    );


//I/O
input                        I_Clk;
input                        I_Rst_n;
input                        I_Adc_Data_In;

output                O_CS_n;
output                O_Adc_Clk;
output         O_Adc_Data_Out;
output                O_Adc_Data_Vaild;


/*************I/O时钟计数器********************/
parameter   IO_Clk_Freq=7'd99;//系统时钟50MHz,500k=50/100->99;
parameter   IO_Clk_Freq_div=7'd49;//采样时钟频率的两倍,对应与采样时钟上升沿
parameter   IO_Clk_Width=3'd7;

reg        R_IO_Clk_Count;
reg                           R_Clk_En;
always @ (posedge I_Clk)
begin
        if (~I_Rst_n)
       begin
          R_IO_Clk_Count<=7'b0;
       end
        else
       begin
          if (R_Clk_En)
           begin
             if (R_IO_Clk_Count==IO_Clk_Freq)
                  R_IO_Clk_Count<=7'b0;
               else
                  R_IO_Clk_Count<=R_IO_Clk_Count+7'd1;
           end
          else
           R_IO_Clk_Count<=7'b0;
       end
end

assign O_Adc_Clk=(R_IO_Clk_Count>IO_Clk_Freq_div)?1'b1:1'b0;

/***************转换时间计时器*********************************/
parameter                Delay_Time=9'd499;//转换时钟为4MHz,总等待时间需要超过34个周期,这里取40个周期,则为500个系统时钟
parameter                CS_n_Time=9'd449;
parameter                Transfer_Count_Width=4'd9;
reg                R_Transfer_Count;
reg                                           R_Transfer_En;
always @ (posedge I_Clk)
begin
   if (~I_Rst_n)
       begin
          R_Transfer_Count<=9'b0;
       end
   else
       begin
          if (R_Transfer_En)
           begin
            if (R_Transfer_Count==Delay_Time)
                  R_Transfer_Count<=R_Transfer_Count;
          else
                  R_Transfer_Count<=R_Transfer_Count+9'd1;
           end
          else
           R_Transfer_Count<=9'b0;       
       end
end

/**************总采样过程状态机***********************/
reg        R_State;
reg              R_CS_n;
reg        R_Data;
reg              R_Vaild;
always @ (posedge I_Clk)
begin
        if (~I_Rst_n)
       begin
          R_State<=4'b0;
          R_CS_n<=1'b1;
          R_Data<=8'b0;
          R_Transfer_En<=1'b0;
          R_Clk_En<=1'b0;
          R_Vaild<=1'b0;
       end
   else
          case (R_State)
          4'd0:
          begin
                  R_Vaild<=1'b0;
                  R_Transfer_En<=1'b1;
                  R_Clk_En<=1'b0;
                  R_CS_n<=1'b1;
                  if (R_Transfer_Count==CS_n_Time)
                   R_State<=R_State+4'd1;
                  else
                   R_State<=R_State;
               end
                4'd1:
                  begin
                   R_CS_n<=1'b0;
                   if (R_Transfer_Count==Delay_Time)
                       begin
                          R_State<=R_State+4'd1;
                          R_Transfer_En<=1'b0;
                       end
                        else
                       begin
                          R_State<=R_State;
                          R_Transfer_En<=1'b1;
                       end
                  end
               4'd2,4'd3,4'd4,4'd5,4'd6,4'd7,4'd8,4'd9:
                  begin
                   R_Clk_En<=1'b1;
                        if (R_IO_Clk_Count==IO_Clk_Freq_div)
                       begin
                          R_State<=R_State+4'd1;
                          R_Data<={R_Data,I_Adc_Data_In};
                       end
                        else
                          R_State<=R_State;
                  end       
               4'd10:
                  begin
                   if (R_IO_Clk_Count==IO_Clk_Freq)
                       begin
                          R_Clk_En<=1'b0;
                          R_State<=4'd0;
                          R_Vaild<=1'b1;
                          R_CS_n<=1'b1;
                       end
                        else
                       begin
                          R_Clk_En<=1'b1;
                          R_State<=R_State;
                          R_Vaild<=1'b0;       
                          R_CS_n<=1'b0;
                       end
                  end
          default:
              begin
                  R_State<=4'b0;
             R_CS_n<=1'b1;
             R_Data<=8'b0;
             R_Transfer_En<=1'b0;
             R_Clk_En<=1'b0;
             R_Vaild<=1'b0;                       
                        end
          endcase               
end

assign        O_CS_n=R_CS_n;
assign        O_Adc_Data_Out=R_Data;
assign        O_Adc_Data_Vaild=R_Vaild;
endmodule
————————————————

大鹏 发表于 2020-5-15 09:35:15

TLC549驱动的硬件编写
页: [1]
查看完整版本: TLC549驱动的硬件编写