锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

FPGA学习之模数转换(TLC549)(调节电位器改变ADC的模拟输入量,读取采样值后,数码管显示,并比较两个值...

时间:2022-09-19 21:00:00 r1216电位器ad数模转换电位器ad值r9011电位器

点击此处添加图片说明文字

TLC549是模数转换芯片,只需要外接时钟(clk),芯片选择(cs)并输入模拟信号(ANIN)控制,当cs被拉低时,ADC数据线数据转换的最高位立即出现在数据线上DAT当时钟下降时,后续数据会发生变化

因为ADC的位宽为8bits,因此,采样电压为v=(D*V(ref))/256

(D为ADC转换后读取的8位二进制数,V(ref)参考电压)

1.TLC549芯片驱动模块:

点击这里添加图片说明文字

module tcl549_Driver(     input clk,     input rst_n,     input en,        //ADC转换能量,高电平有效     input ADC_in,    //输入ADC的串行数据          output reg ADC_clk,   //输出ADC的时钟     output reg ADC_cs,   //输出ADC的片选信号     output reg Get_Flag,  //     output reg [7:0] data       //ADC转换后的电压值      );  reg [10:0] cnt;   //系统时钟计数器 reg [7:0] data_temp;      ///数据寄存器  always @(posedge clk or negedge rst_n) begin     if(!rst_n)         cnt <= 11'd0;     else if(!en)         cnt <= 11'd0;     else if(cnt == 1310)         cnt <= 11'd0;     else         cnt <= cnt   1;    end  always @(posedge clk or negedge rst_n) begin     if(!rst_n)         begin             ADC_clk <= 0;             ADC_cs <= 1;             Get_Flag <= 0;             data <= 8'd0;             data_temp <= 8'd0;         end     else if(en)         begin             case(cnt)                                    1:ADC_cs <= 0;    //1~71,因为正在测量内部电路CS下降沿后,                     //等待两个内部时钟上升和一个下降,然后确认变化,                     ///最后自动将前一次转换结果的最高位置(D7)位输出到DATAOUT端上。                     71:begin                            ADC_clk <= 1;                            data_temp[7] <= ADC_in;                        end                     96:ADC_clk <= 0;                     121:begin                            ADC_clk <= 1;                            data_temp[6] <= ADC_in;                        end                     146:ADC_clk <= 0;                     171:begin                            ADC_clk <= 1;                            data_temp[5] <= ADC_in;                        end                     196:ADC_clk <= 0;                     221:begin                            ADC_clk <= 1;                            data_temp[4] <= ADC_in;                        end                     246:ADC_clk <= 0;                     271:begin                            ADC_clk <= 1;                            data_temp[3] <= ADC_in;                        end                     296:ADC_clk <= 0;                     321:begin                            ADC_clk <= 1;                            data_temp[2] <= ADC_in;                        end                     346:ADC_clk <= 0;                     371:begin                            ADC_clk <= 1;                            data_temp[1] <= ADC_in;                        end                     396:ADC_clk <= 0;                     421:begin                            ADC_clk <= 1;                            data_temp[0] <= ADC_in;                        end                     446:begin                             ADC_clk <= 0;                             ADC_cs <= 1;                             Get_Flag <= 1;                         end                     447:begin                            Get_Flag <= 0;                            data <= data_temp;                        end                     1310:;                     default : ;                              endcase         end     else         begin             ADC_clk <= 0;             ADC_cs <= 1;         end end   endmodule

2.数据控制模块

点击此处添加图片说明文字

module control(     input clk,     input rst_n,     input  Get_Flag,  //新数据采集完成标志位     input [7:0] ADC_data,   //输入ADC采集数据          output reg [23:0] seg_data    ///数字管要显示的数据 );  reg [3:0] qianwei; //千位 reg [3:0] baiwei; reg [3:0] shiwei; reg [3:0] gewei; reg [15:0] tenvalue; ///采样电压值  //采集电压值计算 always @(posedge clk or negedge rst_n) begin     if(!rst_n)         tenvalue <= 0;     else         tenvalue <= (ADC_data*100*25)/256;    ///模数转换 end  //二进制转BCD码 always @(posedge clk or negedge rst_n) begin     if(!rst_n)         begin             qianwei <= 0;             baiwei <= 0;            shiwei <= 0;
            gewei <= 0;
        end
    else
        begin
            qianwei <= tenvalue/1000;
            baiwei <= (tenvalue/100)%10;
            shiwei <= (tenvalue/10)%10;
            gewei <= tenvalue%10;
        end       
end

//数码管显示数值
always @(posedge clk or negedge rst_n)
begin
    if(!rst_n)
        seg_data <= 0;
    else
        seg_data <= {qianwei,baiwei,shiwei,gewei,8'hFF};    //显示值
end

endmodule

3.数码管显示模块

点击此处添加图片说明文字

module dig_led_drive(
    input clk,
    input rst_n,
    input [23:0] data,   //待显示数据
    
    output [7:0] dig_led_seg,   //段选信号
    output [7:0] dig_led_sel   //位选信号
);


parameter system_clk = 50_000_000;

localparam cnt_max = 24;   //在仿真时使用
//localparam localparam cnt_max = system_clk/1000/2 - 1;   //在板级验证时使用

reg [14:0] cnt1;   //分频计数器
reg clk_1k;     //扫描时钟
reg [2:0] sel_r;    //数码管的位选信号
reg [2:0] seg_r;
reg [3:0] disp_data;    //显示数据缓存

//1khz的时钟分频计数器
always @(posedge clk or negedge rst_n) 
begin
    if(!rst_n)
        cnt1 <= 0;
    else if(cnt1 == cnt_max)
        cnt1 <= 0;
    else
        cnt1 <= cnt1 + 1;   
end

//得到1khz的时钟
always @(posedge clk or negedge rst_n) 
begin
    if(!rst_n)
        clk_1k <= 0;
    else if(cnt1 == cnt_max)
        clk_1k <= ~clk_1k;
end

//位选信号控制
always @(posedge clk or negedge rst_n) 
begin
    if(!rst_n)
        sel_r <= 0;
    else if(sel_r == 3)
        sel_r <= 0;
    else
        sel_r <= sel_r + 1'b1;   
end
//选择不同的待显示数据
always @(posedge clk or negedge rst_n) 
begin
    if(!rst_n)
        disp_data <= 4'd0;    
    else
        begin
            case(sel_r)
                3'd0:disp_data = data[23:20];
                3'd1:disp_data = data[19:16];
                3'd2:disp_data = data[15:12];
                3'd3:disp_data = data[11:8];
                3'd4:disp_data = data[7:4];
                3'd5:disp_data = data[3:0];
            endcase
        end
end

always @(*) 
begin
    if(!rst_n)
        seg_r <= 8'hff;    
    else
        begin
            case(disp_data)
                4'd0:seg_r = 8'hc0;
                4'd1:seg_r = 8'hf9;
                4'd2:seg_r = 8'ha4;
                4'd3:seg_r = 8'hb0;
                4'd4:seg_r = 8'h99;
                4'd5:seg_r = 8'h92;
                4'd6:seg_r = 8'h82;
                4'd7:seg_r = 8'hf8;
                4'd8:seg_r = 8'h80;
                4'd9:seg_r = 8'h90;
                4'd10:seg_r = 8'h88;
                4'd11:seg_r = 8'h83;
                4'd12:seg_r = 8'hc6;
                4'd13:seg_r = 8'ha1;
                4'd14:seg_r = 8'h86;
                4'd15:seg_r = 8'h8e;
                default : seg_r <= 8'hff; 
            endcase
        end
end
assign dig_led_seg = seg_r;
assign dig_led_sel = sel_r;
endmodule

 

4.顶层文件

点击

module AD_TLC549(
    input clk,
    input rst_n,
  
    input ADC_in,    //输入ADC的串行数据
    
    output  ADC_clk,   //输出ADC的时钟
    output  ADC_cs,   //输出ADC的片选信号
    output [7:0] dig_led_seg,   //段选信号
    output [7:0] dig_led_sel   //位选信号
);

wire Get_Flag;
wire ADC_data;
wire seg_data;

tcl549_Driver tcl549_Driver(
    .clk(clk),
    .rst_n(rst_n),
    .en(1'b1),
    .ADC_in(ADC_in),
    .ADC_clk(ADC_clk),
    .ADC_cs(ADC_cs),
    .data(ADC_data),
    .Get_Flag(Get_Flag)
);

control control(
    .clk(clk),
    .rst_n(rst_n),
    .ADC_data(ADC_data),
    .seg_data(seg_data),
    .Get_Flag(Get_Flag)
);

dig_led_drive dig_led_drive(
    .clk(clk),
    .rst_n(rst_n),
   
    .dig_led_seg(dig_led_seg),
    .dig_led_sel(dig_led_sel),
   
    .data(seg_data),
    
);
endmodule

此处添加图片说明文字

5.RTL图

点击此处添加图片说明文字

 

 

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章