ADC + 数码管显示

news2025/1/19 2:58:24

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.coloradmin.cn/o/1847964.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Reddit、Discord等社媒网站抓取总结:如何更高效实现网页抓取?

有效的网络抓取需要采取战略方法来克服挑战并确保最佳数据提取。让我们深入研究一些关键实践&#xff0c;这些实践将使您能够掌握复杂的网络抓取。 一、了解 Web 抓取检测 在深入探讨最佳实践之前&#xff0c;让我们先了解一下网站如何识别和抵御网络爬虫。了解您在这一过程中…

2024.6.23周报

目录 摘要 ABSTRACT 一、文献阅读 一、题目 二、摘要 三、网络架构 四、创新点 五、文章解读 1、Introduction 2、Method 3、实验 4、结论 二、代码实验 总结 摘要 本周阅读了一篇题目为NAS-PINN: NEURAL ARCHITECTURE SEARCH-GUIDED PHYSICS-INFORMED NEURAL N…

【vLLM】核心技术PagedAttention,调度原理

vLLM 简介 来自加州大学伯克利分校、斯坦福大学、加州大学圣迭戈分校的研究人员基于操作系统中经典的虚拟(Virtual)内存和分页(Page)技术&#xff0c;提出了一个新的注意力算法 PagedAttention&#xff0c;并打造了一个LLM服务系统——vLLM&#xff0c;官网为&#xff1a;http…

OS复习笔记ch11-4

磁盘调度 磁盘的物理结构 经典的温彻斯特盘 其中的几个概念&#xff1a; 盘面&#xff1a;可以看成是一个操场的平面&#xff0c;不同的盘面通过中间的轴串在一起磁道&#xff1a;磁道可以看成是操场的跑道&#xff0c;我们知道操场上有外道和内道&#xff0c;最内道中间往…

【FlowShop流水线作业排班问题【数学规划的应用(含代码)】阿里达摩院MindOpt】

本文主要讲述使用MindOpt工具优化FlowShop流水线作业排班的数学规划问题。 一、案例场景 FlowShop流水线作业排班也有称为生产下料问题&#xff0c;它涉及到多台机器、多个工序以及多个作业调度安排。在这个问题中&#xff0c;我们需要对多个作业在一组流水线上的处理顺序进行…

矩阵中严格递增的单元格数

题目链接&#xff1a;leetcode:矩阵中严格递增的单元格数 描述 给你一个下标从 1 开始、大小为 m x n 的整数矩阵 mat&#xff0c;你可以选择任一单元格作为 起始单元格 。 从起始单元格出发&#xff0c;你可以移动到 同一行或同一列 中的任何其他单元格&#xff0c;但前提是目…

修复kazam意外中断的视频文件

0. Problem 在用kazam录视频的过程中&#xff0c;PC意外重启了&#xff0c;然后kazam没有把文件自动转换成MP4&#xff0c;而是存为以下两个文件&#xff1a; kazam_xxxxx.movie kazam-xxxxx.movie.mux这两个文件一个0k&#xff0c;另一个是有size的&#xff0c;但是没办法直…

[SAP ABAP] 变量与常量

1.变量 定义变量的基本方式 DATA <name> TYPE <type> [VALUE <val>]. <name>&#xff1a;指定变量的名称 <type>&#xff1a;指定变量的数据类型 <val>&#xff1a;指定<name>的初始值 示例1 定义变量lv_data1和lv_data3 输出结果…

【CMake】CMake从入门到实战系列(十七)—— CMake添加环境检查

&#x1f525;博客简介&#xff1a;开了几个专栏&#xff0c;针对 Linux 和 rtos 系统&#xff0c;嵌入式开发和音视频开发&#xff0c;结合多年工作经验&#xff0c;跟大家分享交流嵌入式软硬件技术、音视频技术的干货。   ✍️系列专栏&#xff1a;C/C、Linux、rtos、嵌入式…

【C语言】16.动态内存管理

文章目录 1.为什么要有动态内存分配2.malloc和free2.1 malloc2.2 free 3.calloc和realloc3.1 calloc3.2 realloc 4.常见的动态内存的错误4.1 对NULL指针的解引⽤操作4.2 对动态开辟空间的越界访问4.3 对⾮动态开辟内存使⽤free释放4.4 使⽤free释放⼀块动态开辟内存的⼀部分4.5…

redis高可用-集群部署

一&#xff1a;背景 前面我们实现了redis的主从同步和哨兵模式&#xff0c;解决了单机redis的故障转移和流量分担&#xff0c;但是不管是主从或者哨兵模式都是一个主服务对应一个或者多个从服务&#xff0c;并且主服务和从服务的数据是一样的&#xff0c;这样就实现不了redis大…

JSP基础知识概述

目录 JSP一、什么是JSP1.1 概念1.2 创建JSP1.3 JSP编写Java代码1.4 JSP实现原理 二、JSP与HTML集成2.1 普通脚本2.2 声明脚本2.3 输出脚本2.4 JSP指令2.5 动作标签 三、内置对象3.1 四大域对象 JSP 一、什么是JSP 1.1 概念 简化的Servlet设计&#xff0c;在HTMl标签中嵌套Jav…

Python学习打卡:day12

day12 笔记来源于&#xff1a;黑马程序员python教程&#xff0c;8天python从入门到精通&#xff0c;学python看这套就够了 目录 day1292、全国疫情地图构建数据整理获取数据数据整体结构&#xff08;全国&#xff09;省数据结构获取每个省份的确诊数据上述代码执行后输出&…

Homebrew使用

官网&#xff1a;https://brew.sh/ 安装&#xff1a; 简介&#xff1a;https://www.jianshu.com/p/f4c9cf0733ea 比如&#xff0c;安装maven: 1、brew install maven 2、查看安装路径&#xff1a;brew list maven 具体参考&#xff1a;https://blog.csdn.net/m0_67402970/arti…

创业众筹网

摘 要 创业是社会经济发展的重要动力&#xff0c;其在任何经济发展时期任何国家都最具活力与桃战性。然而创业的资金却是90%创业者面临的首要问题。包括积蓄不足、无不动产、负债、不知如何向银行申贷,及无法预估所创行业之总资金、成本。部分创业者虽然有心创业&#xff0c;但…

Python学习笔记16:进阶篇(五)异常处理

异常 在编程中&#xff0c;异常是指程序运行过程中发生的意外事件&#xff0c;这些事件通常中断了正常的指令流程。它们可能是由于错误的输入数据、资源不足、非法操作或其他未预料到的情况引起的。Python中&#xff0c;当遇到这类情况时&#xff0c;会抛出一个异常对象&#…

抖音开放平台代开发小程序,上传模板代码

大家好&#xff0c;我是小悟 抖音小程序第三方平台开发着力于解决抖音生态体系内的小程序管理问题&#xff0c;一套模板&#xff0c;随处部署。能尽可能地减少服务商的开发成本&#xff0c;服务商只用开发一套小程序代码作为模板就可以快速批量的孵化出大量的商家小程序。 第…

旋转式滚珠花键在自动装载机中的作用!

自动装载机是一种广泛用于公路、铁路、建筑、水电、港口、矿山等建设工程的土石方施工机械&#xff0c;是工程建设中土石方施工的主要机种之一。而旋转式滚珠花键作为自动装载机中重要的传动元件&#xff0c;在自动装载机的运用起着重要的作用。 自动装载机主要用于铲装土壤、砂…

Windows环境下使用VisualGDB进行Linux项目开发

1.新建项目-打开文件下的新建项目菜单 2.工程项目类型配置 3.Linux机器选择设置 4.设置代码位置 5.编译选项设置 6.调试环境设置

数据库精选题(二)(引言+关系代数)

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;数据库 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 前言 常见概念 一、什么是数据库&#xf…