ADC + 数码管显示

REVIEW

前面已经学习过:

ADC:ADC模-数转换原理与实现-CSDN博客

key:基于状态机的按键消抖实现-CSDN博客

数码管:SPI接口的74HC595驱动数码管实现_用spi和hc74595通信-CSDN博客

1.  今日摸鱼计划

按键启动ADC

将结果显示在数码管上

2.  key + ADC

key.v

module key_one(
                 input clk , 
                 input reset_n,
                 input key,
                 output reg key_flag,
                 output reg key_state
                 );
           
                 
        // nedge_key pedge_key
        reg dff_k_0 , dff_k_1 ;
        reg r_key; 
        wire  nedge_key, pedge_key;
        always@(posedge clk )    
            dff_k_0 <= key ;
        always@(posedge clk )    
            dff_k_1 <= dff_k_0 ;
        always@(posedge clk )    
            r_key <= dff_k_1 ;
            
        assign nedge_key = (r_key == 1)&&(dff_k_1 == 0);
        assign pedge_key = (r_key == 0)&&(dff_k_1 == 1);
   
        // key_now   0:IDLE   1:FILTER0   2:DOWN   3:FILTER1
        // cnt 20ms/20ns = 1000000 ;
        reg [1:0]key_now;
        reg [19:0] cnt;
        parameter cnt_N = 1000;   //测试使用
        always@(posedge clk or negedge reset_n ) 
            if(!reset_n) 
                begin
                    key_now <= 0 ;
                    cnt <= 0;
                    key_flag <= 0;
                    key_state <= 1;
                end
            else 
                begin
                    key_flag <= 0;
                    case(key_now)
                        0:
                           if(!nedge_key) key_now <= 0;
                           else 
                               begin 
                                 cnt <= 0 ;
                                 key_now <= 1; 
                               end
                               
                        1:
                            if(pedge_key) key_now <= 0;
                            else if(cnt >= cnt_N - 1) 
                                begin
                                    cnt <= 0 ;
                                    key_now <= 2;
                                    key_flag <= 1;
                                    key_state <= 0;
                                end
                            else cnt <= cnt + 1'b1;
                            
                        2:
                            if(!pedge_key) key_now <= 2;
                            else
                                begin
                                    cnt <= 0 ;
                                    key_now <= 3;
                                end
                        
                        3:
                            if(nedge_key) key_now <= 2;
                            else if(cnt >= cnt_N - 1)
                                 begin
                                    cnt <= 0 ;
                                    key_now <= 0;
                                    key_flag <= 1;
                                    key_state <= 1;
                                end
                            else cnt <= cnt + 1'b1;    
                        
                    endcase
                end

endmodule

adc128s102.v

module adc128s102(
                input clk,
                input reset_n,
                
                input Conv_Go,//使能信号
                input [2:0]Addr,
                
                input ADC_DOUT,
                output reg ADC_SCLK,
                output reg ADC_CS_N,
                output reg ADC_DIN,
                
                output reg Conv_Done,
                output reg[11:0]Data
                );

    parameter CLOCK_FREQ = 50_000_000;
    parameter SCLK_FREQ = 12_500_000;
    parameter MCNT_DIV_CNT = CLOCK_FREQ/(SCLK_FREQ * 2) - 1;

    reg[7:0]DIV_CNT;
    reg [5:0]LSM_CNT;
    reg [11:0]Data_r;
    reg [2:0]r_Addr;
    
    always@(posedge clk)
    if(Conv_Go)    
        r_Addr <= Addr;
    else
        r_Addr <= r_Addr;
    
    reg Conv_En; //转换使能
    
    always@(posedge clk or negedge reset_n )
    if(!reset_n )
        Conv_En <= 1'd0;
    else if(Conv_Go)
        Conv_En <= 1'd1;
    else if((LSM_CNT == 6'd34) && (DIV_CNT == MCNT_DIV_CNT))
        Conv_En <= 1'd0;
    else
        Conv_En <= Conv_En;
    
    always@(posedge clk or negedge reset_n)
    if(!reset_n)
        DIV_CNT <= 0;
    else if(Conv_En)
        begin
            if(DIV_CNT == MCNT_DIV_CNT)
                DIV_CNT <= 0;
            else    
                DIV_CNT <= DIV_CNT + 1'd1;
        end
    else
        DIV_CNT <= 0;

    always@(posedge clk or negedge reset_n)
    if(!reset_n)
        LSM_CNT <= 6'd0;
    else if(DIV_CNT == MCNT_DIV_CNT)
        begin
            if(LSM_CNT == 6'd34)
                LSM_CNT <= 6'd0;
            else
                LSM_CNT <= LSM_CNT + 1'd1; 
        end
    else
        LSM_CNT <= LSM_CNT;


    always@(posedge clk or negedge reset_n )
    if(!reset_n )begin
        Data_r <= 12'd0;
        ADC_SCLK <= 1'd1;
        ADC_DIN <= 1'd1;
        ADC_CS_N <= 1'd1;
    end
    else if(DIV_CNT == MCNT_DIV_CNT)begin
        case(LSM_CNT)
            0 : begin ADC_CS_N <= 1'd1; ADC_SCLK <= 1'd1;end
            1 : begin ADC_CS_N <= 1'd0;end
            2 : begin ADC_SCLK <= 1'd0;end
            3 : begin ADC_SCLK <= 1'd1;end
            4 : begin ADC_SCLK <= 1'd0;end
            5 : begin ADC_SCLK <= 1'd1;end    
            6 : begin ADC_SCLK <= 1'd0;ADC_DIN <= r_Addr[2]; end
            7 : begin ADC_SCLK <= 1'd1;end    
            8 : begin ADC_SCLK <= 1'd0;ADC_DIN <= r_Addr[1]; end
            9 : begin ADC_SCLK <= 1'd1;end    
            10 :begin ADC_SCLK <= 1'd0;ADC_DIN <= r_Addr[0]; end
            11: begin ADC_SCLK <= 1'd1;Data_r[11] <= ADC_DOUT; end
            12: begin ADC_SCLK <= 1'd0;ADC_DIN <= 1'd1;end
                                        //这里跟之前有一点不一样,将ADC_DIN <= 1'd1;
            13: begin ADC_SCLK <= 1'd1;Data_r[10] <= ADC_DOUT; end
            14: begin ADC_SCLK <= 1'd0;end    
            15: begin ADC_SCLK <= 1'd1;Data_r[9] <= ADC_DOUT; end
            16: begin ADC_SCLK <= 1'd0;end
            17: begin ADC_SCLK <= 1'd1;Data_r[8] <= ADC_DOUT; end
            18: begin ADC_SCLK <= 1'd0;end    
            19: begin ADC_SCLK <= 1'd1;Data_r[7] <= ADC_DOUT; end
            20: begin ADC_SCLK <= 1'd0;end
            21: begin ADC_SCLK <= 1'd1;Data_r[6] <= ADC_DOUT; end
            22: begin ADC_SCLK <= 1'd0;end    
            23: begin ADC_SCLK <= 1'd1;Data_r[5] <= ADC_DOUT; end
            24: begin ADC_SCLK <= 1'd0;end
            25: begin ADC_SCLK <= 1'd1;Data_r[4] <= ADC_DOUT; end
            26: begin ADC_SCLK <= 1'd0;end    
            27: begin ADC_SCLK <= 1'd1;Data_r[3] <= ADC_DOUT; end
            28: begin ADC_SCLK <= 1'd0;end
            29: begin ADC_SCLK <= 1'd1;Data_r[2] <= ADC_DOUT; end
            30: begin ADC_SCLK <= 1'd0;end    
            31: begin ADC_SCLK <= 1'd1;Data_r[1] <= ADC_DOUT; end
            32: begin ADC_SCLK <= 1'd0;end
            33: begin ADC_SCLK <= 1'd1;Data_r[0] <= ADC_DOUT; end
            34: begin ADC_SCLK <= 1'd1;ADC_CS_N <= 1'd1; end
            default: ADC_CS_N <= 1'd1; 
        endcase
    end

    always@(posedge clk or negedge reset_n )
    if(!reset_n )
        begin
            Data <= 12'd0;
            Conv_Done <= 0;
        end
    else if((LSM_CNT == 34) && (DIV_CNT == MCNT_DIV_CNT))
        begin
            Conv_Done <= 1'd1;
            Data <= Data_r;
        end
    else 
        begin
            Conv_Done <= 1'd0;
            Data <= Data;
        end

endmodule

key_adc.v


module key_adc(
                 input clk , 
                 input reset_n,
                 input key,
                 
                 input [2:0]Addr,
                 input ADC_DOUT,
                 output  ADC_SCLK,
                 output  ADC_CS_N,
                 output  ADC_DIN,
                
                 output  Conv_Done,
                 output [11:0]Data
                    );
                    
                    
     wire key_flag , key_state ;               
     key_one key_one_(
                     . clk(clk) , 
                     . reset_n(reset_n),
                     . key(key),
                     . key_flag(key_flag),
                     . key_state(key_state)
                     );     
                     
                               
     reg  Conv_Go ;  
     always@(posedge clk or negedge reset_n )
     if(!reset_n ) 
        Conv_Go <= 1'b0 ;
     else if((key_flag)&&(key_state==1))
                    //(key_flag)&&(key_state==1)代表按键按下后松开
                    //之前都是按下作为判定,本次有一点不同
        Conv_Go <= 1'b1 ;
     else
        Conv_Go <= 1'b0 ;
        
     adc128s102 adc_(
                . clk(clk),
                . reset_n(reset_n),
                
                . Conv_Go(Conv_Go),//使能信号
                . Addr(Addr),
                
                . ADC_DOUT(ADC_DOUT),
                . ADC_SCLK(ADC_SCLK),
                . ADC_CS_N(ADC_CS_N),
                . ADC_DIN(ADC_DIN),
                
                . Conv_Done(Conv_Done),
                . Data(Data)
                );   
        
        
        
                    
                    
endmodule

key_adc_tb.v

`timescale 1ns / 1ns

module key_adc_tb(    );

        reg clk;
        reg reset_n;
        reg key ;
        reg [2:0]Addr;
        reg ADC_DOUT;
        wire ADC_SCLK;
        wire ADC_CS_N;
        wire ADC_DIN;
        wire Conv_Done;
        wire[11:0]Data;

        
       key_adc key_adc_(
                         . clk(clk) , 
                         . reset_n(reset_n),
                         . key(key),
                         
                         . Addr(Addr),
                        
                         . ADC_DOUT(ADC_DOUT),
                         . ADC_SCLK(ADC_SCLK),
                         . ADC_CS_N(ADC_CS_N),
                         . ADC_DIN(ADC_DIN),
                        
                        . Conv_Done(Conv_Done),
                        . Data(Data)
                    );
        
        initial clk = 1;
        always #10 clk = ~clk;
        
         initial 
    begin
        reset_n = 0;
        Addr = 2;
        key = 1 ;
        #201;
        reset_n = 1;
        #200;
        key_press(2);
         
        wait(!ADC_CS_N);
        //16'h0A58
        @(negedge ADC_SCLK);
        ADC_DOUT = 0; //DB15 
        @(negedge ADC_SCLK);
        ADC_DOUT = 0; //DB14 
        @(negedge ADC_SCLK);
        ADC_DOUT = 0; //DB13        
        @(negedge ADC_SCLK);
        ADC_DOUT = 0; //DB12        
        @(negedge ADC_SCLK);
        ADC_DOUT = 1; //DB11          
        @(negedge ADC_SCLK);
        ADC_DOUT = 0; //DB10         
        @(negedge ADC_SCLK);
        ADC_DOUT = 1; //DB9         
        @(negedge ADC_SCLK);
        ADC_DOUT = 0; //DB8         
        @(negedge ADC_SCLK);
        ADC_DOUT = 0; //DB7         
        @(negedge ADC_SCLK);
        ADC_DOUT = 1; //DB6         
        @(negedge ADC_SCLK);
        ADC_DOUT = 0; //DB5         
        @(negedge ADC_SCLK);
        ADC_DOUT = 1; //DB4        
        @(negedge ADC_SCLK);
        ADC_DOUT = 1; //DB3         
        @(negedge ADC_SCLK);
        ADC_DOUT = 0; //DB2        
        @(negedge ADC_SCLK);
        ADC_DOUT = 0; //DB1         
        @(negedge ADC_SCLK);
        ADC_DOUT = 0; //DB0      
        wait(ADC_CS_N);
        #2000;   
             
        
        Addr = 7;
        #20;
      key_press(2);     
        wait(!ADC_CS_N);
        //16'h0893
        @(negedge ADC_SCLK);
        ADC_DOUT = 0;
        @(negedge ADC_SCLK);
        ADC_DOUT = 0;
        @(negedge ADC_SCLK);
        ADC_DOUT = 0;        
        @(negedge ADC_SCLK);
        ADC_DOUT = 0;        
        @(negedge ADC_SCLK);
        ADC_DOUT = 1;          
        @(negedge ADC_SCLK);
        ADC_DOUT = 0;         
        @(negedge ADC_SCLK);
        ADC_DOUT = 0;         
        @(negedge ADC_SCLK);
        ADC_DOUT = 0;         
        @(negedge ADC_SCLK);
        ADC_DOUT = 1;         
        @(negedge ADC_SCLK);
        ADC_DOUT = 0;         
        @(negedge ADC_SCLK);
        ADC_DOUT = 0;         
        @(negedge ADC_SCLK);
        ADC_DOUT = 1;         
        @(negedge ADC_SCLK);
        ADC_DOUT = 0;         
        @(negedge ADC_SCLK);
        ADC_DOUT = 0;         
        @(negedge ADC_SCLK);
        ADC_DOUT = 1;         
        @(negedge ADC_SCLK);
        ADC_DOUT = 1;       
        wait(ADC_CS_N);
        #200;    
        #100000;

        $stop;
    end

reg [13:0] rand;
 task key_press;
    input[3:0]seed;
    begin
        key =  1 ;
        #100000;
        repeat(10)
            begin
                rand = {$random(seed)} % 10000;
                #rand;
                key=~key;
            end
        key = 0 ;
        #100000;
         key =  1 ;
    end 
endtask      
        
        
endmodule

分析

adc中做了这样一个小改动,没什么别的作用,这个就是摸鱼怪觉得看起来好看一点。

关于按键的判断,这里是因为在调试按键按下后,发现wait等不到CS下降沿信号,从而DOUT未触发。

测试结果如下:

经过分析,测试文件一直走不到 wait(!ADC_CS_N);

是因为!ADC_CS_N 在 key_press(2);结束之前已经发生了

因此为了测试分析,本次选择使用按键松开为判定

注意:本次测试为了可以 wait(!ADC_CS_N);

按键松开后,不要停留过长时间!

此时看以看出,进行了两次正常的读取。

3.  key + ADC + 数码管

hex_8.v

module hex_8(
             input clk,
             input reset_n,
             input [31:0]disp_data,
             output reg [7:0]sel,
             output reg [7:0]seg
             );

//[31:0]disp_data  16hex 4*8
//[7:0]sel 位选信号
//[7:0]seg 段选信号

// 1kHz分频时钟 
    reg [14:0]div_clk;
    always@(posedge clk or negedge reset_n)
    if(!reset_n) 
        div_clk <= 1'b0;
    else if(div_clk == 24999) 
        div_clk <= 1'b0;
    else 
        div_clk <= div_clk + 1'b1;
    reg disp_en;
   always@(posedge clk or negedge reset_n)
    if(!reset_n) 
        disp_en <= 1'b0;
    else if(div_clk == 24999) 
        disp_en <= 1'b1;
    else 
        disp_en <= 1'b0;    

//  位选sel
    reg[2:0]sel_num;
    always@(posedge clk or negedge reset_n)
    if(!reset_n) 
        sel_num <= 3'b000;
    else if(disp_en) 
        sel_num <= sel_num + 1'b1;
        
    always@(posedge clk or negedge reset_n)
    if(!reset_n) 
        sel <= 8'b0000_0000;
    else case(sel_num) 
         0:sel <= 8'b0000_0001;
         1:sel <= 8'b0000_0010;
         2:sel <= 8'b0000_0100;
         3:sel <= 8'b0000_1000;
         4:sel <= 8'b0001_0000;
         5:sel <= 8'b0010_0000;
         6:sel <= 8'b0100_0000;
         7:sel <= 8'b1000_0000;
    endcase   
   
// 段选seg   [31:0]disp_data  16hex 4*8
    reg [3:0] dis_tmp;
    always@(posedge clk )
    case(sel_num) //高位放前面
         7:dis_tmp <= disp_data[31:28];
         6:dis_tmp <= disp_data[27:24];
         5:dis_tmp <= disp_data[23:20];
         4:dis_tmp <= disp_data[19:16];
         3:dis_tmp <= disp_data[15:12];
         2:dis_tmp <= disp_data[11:8];
         1:dis_tmp <= disp_data[7:4];
         0:dis_tmp <= disp_data[3:0];
    endcase 
    
    always@(posedge clk )
    case(dis_tmp) 
         0:seg <= 8'hc0;
         1:seg <= 8'hf9;
         2:seg <= 8'ha4;
         3:seg <= 8'hb0;
         4:seg <= 8'h99;
         5:seg <= 8'h92;
         6:seg <= 8'h82;
         7:seg <= 8'hf8;
         8:seg <= 8'h80;
         9:seg <= 8'h90;
         4'ha:seg <= 8'h88;
         4'hb:seg <= 8'h83;
         4'hc:seg <= 8'hc6;
         4'hd:seg <= 8'ha1;
         4'he:seg <= 8'h86;
         4'hf:seg <= 8'h8e;
    endcase 

endmodule

hc595_driver.v

module hc595_driver(
                        input clk,
                        input reset_n,
                        input [15:0]data ,
                        input s_en ,
                        output reg sh_cp ,
                        output reg st_cp ,
                        output reg ds
                        );
        //接收到s_en才改变r_data                
        reg [15:0]r_data;
        always@(posedge clk)
        if(s_en)
          r_data <= data;
          
        //分频计数器;  
        parameter CNT_MAX = 2; 
        reg [7:0]divider_cnt;
        always@(posedge clk or negedge reset_n)
        if(!reset_n)
            divider_cnt <= 0;
        else if(divider_cnt == CNT_MAX - 1'b1)
            divider_cnt <= 0;
        else
            divider_cnt <= divider_cnt + 1'b1; 
        
        
        wire sck_plus;
    assign sck_plus = (divider_cnt == CNT_MAX - 1'b1);
        
    reg [5:0]SHCP_EDGE_CNT;
    
    always@(posedge clk or negedge reset_n)
    if(!reset_n)
        SHCP_EDGE_CNT <= 0;
    else if(sck_plus)
        begin
            if(SHCP_EDGE_CNT == 6'd32)
                SHCP_EDGE_CNT <= 0;
            else
                SHCP_EDGE_CNT <= SHCP_EDGE_CNT + 1'b1;
        end
    else
        SHCP_EDGE_CNT <= SHCP_EDGE_CNT;
        
    always@(posedge clk or negedge reset_n)
    if(!reset_n)
        begin
            st_cp <= 1'b0;
            ds <= 1'b0;
            sh_cp <= 1'd0;
        end 
    else 
        begin
            case(SHCP_EDGE_CNT)
                0: begin sh_cp <= 0; st_cp <= 1'd0;ds <= r_data[15];end
                1: begin sh_cp <= 1; st_cp <= 1'd0;end
                2: begin sh_cp <= 0; ds <= r_data[14];end
                3: begin sh_cp <= 1; end
                4: begin sh_cp <= 0; ds <= r_data[13];end    
                5: begin sh_cp <= 1; end
                6: begin sh_cp <= 0; ds <= r_data[12];end    
                7: begin sh_cp <= 1; end
                8: begin sh_cp <= 0; ds <= r_data[11];end    
                9: begin sh_cp <= 1; end
                10: begin sh_cp <= 0; ds <= r_data[10];end    
                11: begin sh_cp <= 1; end
                12: begin sh_cp <= 0; ds <= r_data[9];end    
                13: begin sh_cp <= 1; end
                14: begin sh_cp <= 0; ds <= r_data[8];end    
                15: begin sh_cp <= 1; end
                16: begin sh_cp <= 0; ds <= r_data[7];end    
                17: begin sh_cp <= 1; end
                18: begin sh_cp <= 0; ds <= r_data[6];end    
                19: begin sh_cp <= 1; end
                20: begin sh_cp <= 0; ds <= r_data[5];end    
                21: begin sh_cp <= 1; end
                22: begin sh_cp <= 0; ds <= r_data[4];end    
                23: begin sh_cp <= 1; end
                24: begin sh_cp <= 0; ds <= r_data[3];end    
                25: begin sh_cp <= 1; end
                26: begin sh_cp <= 0; ds <= r_data[2];end    
                27: begin sh_cp <= 1; end
                28: begin sh_cp <= 0; ds <= r_data[1];end            
                29: begin sh_cp <= 1; end
                30: begin sh_cp <= 0; ds <= r_data[0];end
                31: begin sh_cp <= 1; end
                32: st_cp <= 1'd1;
                default:        
                    begin
                        st_cp <= 1'b0;
                        ds <= 1'b0;
                        sh_cp <= 1'd0;
                    end
            endcase
        end

        
        
        
endmodule

key_adc_hex8.v


module key_adc_hex8(
                 input clk , 
                 input reset_n,
                 input key,
                 
                 input [2:0]Addr,
                 input ADC_DOUT,
                 output  ADC_SCLK,
                 output  ADC_CS_N,
                 output  ADC_DIN,
                 output  Conv_Done,
                 
                 output sh_cp,
                 output st_cp,
                 output ds
                    );
                    
                    
     wire key_flag , key_state ;               
     key_one key_one_(
                     . clk(clk) , 
                     . reset_n(reset_n),
                     . key(key),
                     . key_flag(key_flag),
                     . key_state(key_state)
                     );     
                     
                               
         reg  Conv_Go ;  
         always@(posedge clk or negedge reset_n )
         if(!reset_n ) 
            Conv_Go <= 1'b0 ;
         else if((key_flag)&&(key_state==1))
            Conv_Go <= 1'b1 ;
         else
            Conv_Go <= 1'b0 ;
        
      wire [11:0]  Data;
     adc128s102 adc_(
                . clk(clk),
                . reset_n(reset_n),
                
                . Conv_Go(Conv_Go),//使能信号
                . Addr(Addr),
                
                . ADC_DOUT(ADC_DOUT),
                . ADC_SCLK(ADC_SCLK),
                . ADC_CS_N(ADC_CS_N),
                . ADC_DIN(ADC_DIN),
                
                . Conv_Done(Conv_Done),
                . Data(Data)
                );   
        
    reg [31:0]disp_data;
    wire [7:0] sel;//数码管位选(选择当前要显示的数码管)
    wire [7:0] seg;//数码管段选(当前要显示的内容)  
    always@(posedge clk or negedge reset_n )
     if(!reset_n ) 
        disp_data <= 0 ;
     else 
        disp_data <= 32'h0000_0000 + Data ;    
                    
     
     hc595_driver hc595_driver(
        .clk(clk),
        .reset_n(reset_n),
        .data({seg,sel}),  //将段选与位选信号拼接在一起
        .s_en(1'b1),
        .sh_cp(sh_cp),
        .st_cp(st_cp),
        .ds(ds)
    );
    
    hex_8 hex8(
        .clk(clk),
        .reset_n(reset_n),
        .disp_data(disp_data),
        .sel(sel),
        .seg(seg)
    );
     
     
                    
endmodule

key_adc_hex8_tb.v

`timescale 1ns / 1ns

module key_adc_hex8_tb(    );
        
        reg clk;
        reg reset_n;
        reg key ;
        reg [2:0]Addr;
        reg ADC_DOUT;
        wire ADC_SCLK;
        wire ADC_CS_N;
        wire ADC_DIN;
        wire Conv_Done;
        wire sh_cp,st_cp, ds;
        
        
     key_adc_hex8    k_hex8(
                  clk , 
                  reset_n,
                  key,
                 
                Addr,
                  ADC_DOUT,
                   ADC_SCLK,
                   ADC_CS_N,
                   ADC_DIN,
                   Conv_Done,
                 
                  sh_cp,
                  st_cp,
                  ds
                    );
        
     initial clk = 1;
        always #10 clk = ~clk;
        
         initial 
    begin
        reset_n = 0;
        Addr = 2;
        key = 1 ;
        #201;
        reset_n = 1;
        #200;
        key_press(2);
         
        wait(!ADC_CS_N);
        //16'h0A58
        @(negedge ADC_SCLK);
        ADC_DOUT = 0; //DB15 
        @(negedge ADC_SCLK);
        ADC_DOUT = 0; //DB14 
        @(negedge ADC_SCLK);
        ADC_DOUT = 0; //DB13        
        @(negedge ADC_SCLK);
        ADC_DOUT = 0; //DB12        
        @(negedge ADC_SCLK);
        ADC_DOUT = 1; //DB11          
        @(negedge ADC_SCLK);
        ADC_DOUT = 0; //DB10         
        @(negedge ADC_SCLK);
        ADC_DOUT = 1; //DB9         
        @(negedge ADC_SCLK);
        ADC_DOUT = 0; //DB8         
        @(negedge ADC_SCLK);
        ADC_DOUT = 0; //DB7         
        @(negedge ADC_SCLK);
        ADC_DOUT = 1; //DB6         
        @(negedge ADC_SCLK);
        ADC_DOUT = 0; //DB5         
        @(negedge ADC_SCLK);
        ADC_DOUT = 1; //DB4        
        @(negedge ADC_SCLK);
        ADC_DOUT = 1; //DB3         
        @(negedge ADC_SCLK);
        ADC_DOUT = 0; //DB2        
        @(negedge ADC_SCLK);
        ADC_DOUT = 0; //DB1         
        @(negedge ADC_SCLK);
        ADC_DOUT = 0; //DB0      
        wait(ADC_CS_N);
        #2000;   
         #1000000;    
        
        Addr = 7;
        #20;
      key_press(2);     
        wait(!ADC_CS_N);
        //16'h0893
        @(negedge ADC_SCLK);
        ADC_DOUT = 0;
        @(negedge ADC_SCLK);
        ADC_DOUT = 0;
        @(negedge ADC_SCLK);
        ADC_DOUT = 0;        
        @(negedge ADC_SCLK);
        ADC_DOUT = 0;        
        @(negedge ADC_SCLK);
        ADC_DOUT = 1;          
        @(negedge ADC_SCLK);
        ADC_DOUT = 0;         
        @(negedge ADC_SCLK);
        ADC_DOUT = 0;         
        @(negedge ADC_SCLK);
        ADC_DOUT = 0;         
        @(negedge ADC_SCLK);
        ADC_DOUT = 1;         
        @(negedge ADC_SCLK);
        ADC_DOUT = 0;         
        @(negedge ADC_SCLK);
        ADC_DOUT = 0;         
        @(negedge ADC_SCLK);
        ADC_DOUT = 1;         
        @(negedge ADC_SCLK);
        ADC_DOUT = 0;         
        @(negedge ADC_SCLK);
        ADC_DOUT = 0;         
        @(negedge ADC_SCLK);
        ADC_DOUT = 1;         
        @(negedge ADC_SCLK);
        ADC_DOUT = 1;       
        wait(ADC_CS_N);
        #200;    
        #1000000;






        $stop;
    end
reg [13:0] rand;
 task key_press;
    input[3:0]seed;
    begin
        key =  1 ;
        #100000;
        repeat(10)
            begin
                rand = {$random(seed)} % 10000;
                #rand;
                key=~key;
            end
        key = 0 ;
        #100000;
         key =  1 ;
    end 
endtask          

endmodule

.xdc

set_property IOSTANDARD LVCMOS33 [get_ports clk]
set_property IOSTANDARD LVCMOS33 [get_ports reset_n]
set_property IOSTANDARD LVCMOS33 [get_ports st_cp]
set_property IOSTANDARD LVCMOS33 [get_ports sh_cp]
set_property IOSTANDARD LVCMOS33 [get_ports ds]

set_property PACKAGE_PIN U18 [get_ports clk]
set_property PACKAGE_PIN D20 [get_ports ds]
set_property PACKAGE_PIN E19 [get_ports sh_cp]
set_property PACKAGE_PIN F17 [get_ports st_cp]

set_property IOSTANDARD LVCMOS33 [get_ports {Addr[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {Addr[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {Addr[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports ADC_CS_N]
set_property IOSTANDARD LVCMOS33 [get_ports ADC_DIN]
set_property IOSTANDARD LVCMOS33 [get_ports ADC_DOUT]
set_property IOSTANDARD LVCMOS33 [get_ports ADC_SCLK]
set_property IOSTANDARD LVCMOS33 [get_ports Conv_Done]
set_property IOSTANDARD LVCMOS33 [get_ports key]
set_property PACKAGE_PIN H18 [get_ports key]
set_property PACKAGE_PIN H20 [get_ports reset_n]
set_property PACKAGE_PIN K14 [get_ports {Addr[0]}]
set_property PACKAGE_PIN L15 [get_ports {Addr[1]}]
set_property PACKAGE_PIN G14 [get_ports {Addr[2]}]
set_property PACKAGE_PIN M19 [get_ports ADC_DIN]
set_property PACKAGE_PIN M20 [get_ports ADC_DOUT]
set_property PACKAGE_PIN L19 [get_ports ADC_SCLK]
set_property PACKAGE_PIN M18 [get_ports ADC_CS_N]
set_property PACKAGE_PIN G17 [get_ports Conv_Done]

分析

测试代码符合预期

板级验证:

拨码开关选取地址

测量短路时,电压为0

测量小电池,电压比较准(手边没万用表,划划水啦~)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/742177.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

OnlyOffice-8.1版本深度测评

2024年6月19日&#xff0c;ONLYOFFICE 发布了最新版本 8.1&#xff0c;带来了超过30项新功能和432个 bug 修复。本文将详细评测该版本的新功能和改进&#xff0c;帮助用户全面了解这一升级带来的实际体验提升。 一、功能全面的 PDF 编辑器 PDF 是日常工作中不可或缺的文件格式…

汽车汽配图纸管理、产品研发管理解决方案

汽车汽配图纸管理、产品研发管理解决方案 随着全球汽车市场的快速发展&#xff0c;中国汽车汽配行业迎来了前所未有的发展机遇。然而&#xff0c;在这一过程中&#xff0c;企业也面临着诸多挑战&#xff0c;如研发能力的提升、技术资料管理的复杂性、以及跨部门协作的困难等。为…

【CPP】插入排序:直接插入排序、希尔排序

目录 1.插入排序1.1直接插入排序简介代码分析 1.2直接插入对比冒泡排序简介代码对比分析(直接插入排序与冒泡的复杂度效率区别) 1.3希尔排序简介代码分析 1.插入排序 基本思想&#xff1a;把一个待排数字按照关键码值插入到一个有序序列中&#xff0c;得到一个新的有序序列。 …

施耐德ATV310变频器参数设置

1、ATV610变频器参数设置请参考下面文章链接&#xff1a; 施耐德ATV610变频器MODBUS通信应用(SMART PLC)-CSDN博客文章浏览阅读131次。提升MODBUS-RTU通信数据刷新速度的常用方法_modbus rtu通讯慢-CSDN博客文章浏览阅读1k次。https://rxxw-control.blog.csdn.net/article/det…

03 Shell编程之循环语句与函数

目录 3.1 for 循环语句 3.1.1 for 语句的结构 3.1.2 for 语句应用示例 1. 根据姓名列表批量添加用户 2. 根据IP地址列表检查主机状态 3.2 使用while循环语句 3.2.1 while语句的结构 3.2.2 while语句应用示例 1. 批量添加规律编号的用户 2. 猜价格游戏 3.3 until 循环语句 3.…

IDEA集成Docker实现快捷部署

本文已收录于专栏 《运维》 目录 背景介绍优势特点操作步骤一、修改Docker配置二、配置Docker插件三、编写Maven插件四、构建Docker镜像五、创建Docker容器 总结提升 背景介绍 在我们手动通过Docker部署项目的时候&#xff0c;都是通过把打包好的jar包放到服务器上并且在服务器…

深圳比创达电子EMC|EMI电磁干扰行业:提升电子产品质量的关键

随着电子技术的飞速发展&#xff0c;电磁干扰&#xff08;EMI&#xff09;问题日益凸显&#xff0c;成为影响电子产品性能和市场竞争力的重要因素。 一、EMI电磁干扰行业的概述 电磁干扰&#xff0c;即电子设备在运行过程中产生的电磁波对其他设备或系统产生的干扰。这种干扰…

视频集市新增支持多格式流媒体拉流预览

流媒体除了常用实时流外还有大部分是以文件的形式存在&#xff0c;做融合预览必须要考虑多种兼容性能力&#xff0c;借用现有的ffmpeg生态可以迅速实现多种格式的支持&#xff0c;现在我们将按需拉流预览功能进行了拓展&#xff0c;正式支持了ffmpeg的功能&#xff0c;可快捷方…

Kotlin 中的数据类型有隐式转换吗?

在 Kotlin 中&#xff0c;数据类型不可隐式转换。在 Java 中&#xff0c;如果数据是从小到大&#xff0c;是可以隐式转换的&#xff0c;数据类型将自动提升。 下面以 int 类型的数据为例&#xff0c;在 Java 中这样写是可以的&#xff1a; int a 2312; long b a;但是在 Kot…

Python21 k-近邻算法

k-近邻算法&#xff08;k-Nearest Neighbors, k-NN&#xff09;是一种基本且广泛使用的分类与回归算法。它的工作原理非常直观&#xff1a;通过测量不同特征点之间的距离&#xff0c;来进行分类或回归分析。 1.K-NN算法 基本概念 1.基于实例的学习&#xff1a;k-NN是一种基于…

three.js - matcap材质(MeshMatcapMaterial)

说一下matcap纹理 先总结&#xff1a;MeshMatcapMaterial材质&#xff0c;通过采样含有光照信息的贴图来模拟光照效果。这种材质特别适用于模拟静态光源下的光照&#xff0c;并且&#xff0c;因其简单性和快速性而被广泛应用于各种场景。但是&#xff0c;由于其性能考虑&#x…

浅层神经网络

浅层神经网络 神经网络概述 一个完整的神经网络由N多个神经元之间形成的复杂连接&#xff0c;但对于每个神经元仅执行简单的线性计算。 神经网络的表示 &#x1d44e; ^ [0]可以用来表示输入层的激活值 &#x1d44e; ^ [1]可以用来表示隐藏层的激活值 &#x1d465;表示输…

一种502 bad gateway nginx/1.18.0的解决办法

背景:上线的服务突然挂掉了 step1&#xff0c;去后端日志查看&#xff0c;发现并无异常&#xff0c;就是请求无法被接收 step2&#xff0c;查看了nginx的错误日志&#xff0c;发现该文件为空 step3&#xff0c;查看了niginx的运行日志&#xff0c;发现了以下问题 [error] 38#…

JeecgFlow事件网关概念及案例

事件网关 通常网关基于连线条件决定后续路径&#xff0c;但事件网关有所不同&#xff0c;其基于事件决定后续路径。事件网关的每条外出顺序流都需要连接一个捕获中间事件。 事件网关只有分支行为&#xff0c;流程的走向完全由中间事件决定。可以从多条候选分支中选择事件最先达…

Struts2 S2-061 远程命令执行漏洞(CVE-2020-17530)

目录 Struts2介绍 漏洞介绍 环境搭建 漏洞探测 执行命令 反弹shell 这一篇还是参考大佬的好文章进行Struts2 S2-061远程命令执行漏洞的学习和练习 Struts2介绍 百度百科 Struts2框架是一个用于开发Java EE网络应用程序的开放源代码网页应用程序架构。它利用并延伸了Ja…

面试-java并发与多线程的部分函数

1.sleep和wait的区别 基本的差别&#xff1a; Sleep是Thread的方法。Wait是object方法。Wait不传参&#xff0c;最终也是调用wait(native)的传参方法。 Sleep方法可以在任何地方使用。 Wait方法只能在synchronized方法或synchronized方法块中使用。 最主要的本质区别&#xf…

web前端——CSS

目录 一、css概述 二、基本语法 1.行内样式表 2.内嵌样式表 3.外部样式表 4.三者对比 三、选择器 1.常用的选择器 2. 选择器优先级 3.由高到低优先级排序 四、文本,背景,列表,伪类,透明 1.文本 2.背景 3.列表 4.伪类 5.透明 五、块级,行级,行级块标签, dis…

OCR的有效数据增强

背景 我面临着需要尽可能准确识别手写金额的挑战。难点在于保持误判率低于0.01%。由于数据集中样本数量固定&#xff0c;因此数据增强是合乎逻辑的选择。快速搜索未发现针对光学字符识别&#xff08;OCR&#xff09;的现成方法。因此&#xff0c;我挽起袖子&#xff0c;亲自创建…

discuz插件之优雅草超级列表互动增强v1.2版本更新

https://doc.youyacao.com/9/2142 v1.2更新 discuz插件之优雅草超级列表互动增强v1.2版本更新 [title]20220617 v1.2发布[/title] 增加了对php8的支持 增加了 对discuz3.5的支持

跟着DW学习大语言模型-什么是知识库,如何构建知识库

建立一个高效的知识库对于个人和组织来说非常重要。无论是为了个人学习和成长&#xff0c;还是为了组织的持续创新和发展&#xff0c;一个完善的知识管理系统都是不可或缺的。那么&#xff0c;如何建立一个高效的知识库呢&#xff1f; 在建立知识库之前&#xff0c;首先需要确定…