8/12 ADC

정유석·2024년 8월 12일

교육 - 베릴로그

목록 보기
22/28

ADC 변환

디지털값인 0과 1사이의 값을 디지털비트로 나눠서 아날로그와 유사하게 만듬

좌측 IP Catalog 클릭 -> 우측 페이지가 나오는데 검색창에 adc 검색 -> 아래 XADC Wizard 클릭

싱글 채널(Single Channel)을 사용할 것인지 여러 채널(Channel Sequencer)을 사용할 것인지 선택

https://digilent.com/reference/programmable-logic/basys-3/start?srsltid=AfmBOooLEPn9FuOy_QoF8d983F4T6YREOedUx8rCZtaqKN9moAtcaMNe
Basys 3 schematic 파일에 있는 내부 회로도 이다
XA1~4p, XA1~4n 포트로서 ADC변환, 채널6, 7, 14, 15가 사용가능 채널

주의! VP/VN 체크 해제해야함!
사용 채널 체크(채널6, 채널15 사용)

글로벌 선택

디자인 소스페이지에 있음, 클릭하여 ADC를 위한 모듈 접근

조이스틱 조절


x축과 y축을 계속해서 한번에 보드에 보내주고
XDC파일에 설정해놓은 채널6과 채널15가 연결된 포트에서 아날로그 신호를 모두 입력받고, xadc_wizard에 의해 채널6과 채널15를 순차적으로 매우 빠르게 반복해서 디지털로 변환해주고, 변환이 완료 될때마다 eoc_out을 통해 완료 신호를 보내고 den_in에 의해 enable되면 do_out을 출력한다

module adc_sequence2_top(
    input clk, reset_p,   
    input vauxp6, vauxn6, vauxp15, vauxn15,
    output led_r, led_g,
    output [3:0] com,
    output [7:0] seg_7); 

    wire [4:0] channel_out;
    wire [15:0] do_out;
    wire eoc_out;
    
    xadc_wiz_1 adc_seq2
          ( 
          .daddr_in({2'b0, channel_out}), // 채널 주소 넘겨받음 //주소 버스  //addr은 7비트 channel_out은 5비트 // Address bus for the dynamic reconfiguration port
          .dclk_in(clk),          //클럭 입력 // Clock input for the dynamic reconfiguration port
          .den_in(eoc_out),       //활성화 신호 // Enable Signal for the dynamic reconfiguration port
//          di_in,               //입력 데이터 버스// Input data bus for the dynamic reconfiguration port
//          dwe_in,              //쓰기 활성화 // Write Enable for the dynamic reconfiguration port
          .reset_in(reset_p),    //리셋 신호// Reset signal for the System Monitor control logic
          .vauxp6(vauxp6),       //JXADC포트로 아날로그 신호 입력받음, XDC 변경 필요 //채널6 양극// Auxiliary channel 6
          .vauxn6(vauxn6),       //JXADC포트로 아날로그 신호 입력받음, XDC 변경 필요 //채널6 음극
          .vauxp15(vauxp15),       
          .vauxn15(vauxn15),
//          busy_out,            //adc작동 중 신호 // ADC Busy signal
//          drdy_out,            //데이터 준비 신호 // Data ready signal for the dynamic reconfiguration port
          .channel_out(channel_out), //채널6, 현재 단일 채널로서 하나만 있음 //채널 선택 출력 // Channel Selection Outputs
          .do_out(do_out),           //아날로그가 디지털로 변환된 값을 출력 //출력 데이터 버스 //adc값 들어있음 // Output data bus for dynamic reconfiguration port
          .eoc_out(eoc_out)          //변환 완료 신호 //adc변환이 끝나면 1나옴 // End of Conversion Signal
//          eos_out,             //시퀀스 완료 신호 // End of Sequence Signal
//          alarm_out,           //모든 알람의 출력// OR'ed output of all the Alarms
          );

    wire eoc_out_pedge;           
    edge_detector_n ed(
        .clk(clk),
        .reset_p(reset_p),
        .cp(eoc_out),
        .p_edge(eoc_out_pedge)   
    );
    
    reg [11:0] adc_value_x, adc_value_y; //do_out의 상위 12비트만 사용
    always @(posedge clk or posedge reset_p)begin
        if(reset_p) begin
            adc_value_x = 0;
            adc_value_y = 0;
        end
        else if(eoc_out_pedge)begin
            case(channel_out[3:0]) //원래 5비트지만 최상위 1비트는 모드 설정(비교 또는 기준에의한 설정)이므로 버림
                6: adc_value_x = do_out[15:4]; //상위 12비트가 adc 변환된 값
                15: adc_value_y = do_out[15:4];
            endcase
        end
    end     
    
    wire [15:0] bcd_x, bcd_y, value;
    bin_to_dec bcd_adc_x(
        .bin({2'b0, adc_value_x[11:6]}),
        .bcd(bcd_x)
    );
    
    bin_to_dec bcd_adc_y(
        .bin({2'b0, adc_value_y[11:6]}),
        .bcd(bcd_y)
    );
          
    assign value = {bcd_x[7:0], bcd_y[7:0]};         
    fnd_cntr fnd_cntr_inst(
        .clk(clk),
        .reset_p(reset_p),
        .value(value),
        .com(com),
        .seg_7(seg_7)
        );          

endmodule

led 조절

module adc_sequence2_top(
    input clk, reset_p,   
    input vauxp6, vauxn6, vauxp15, vauxn15,
    output led_r, led_g,
    output [3:0] com,
    output [7:0] seg_7); 

    wire [4:0] channel_out;
    wire [15:0] do_out;
    wire eoc_out;
    
    xadc_wiz_1 adc_seq2
          ( 
          .daddr_in({2'b0, channel_out}), // 채널 주소 넘겨받음 //주소 버스  //addr은 7비트 channel_out은 5비트 // Address bus for the dynamic reconfiguration port
          .dclk_in(clk),          //클럭 입력 // Clock input for the dynamic reconfiguration port
          .den_in(eoc_out),       //활성화 신호 // Enable Signal for the dynamic reconfiguration port
//          di_in,               //입력 데이터 버스// Input data bus for the dynamic reconfiguration port
//          dwe_in,              //쓰기 활성화 // Write Enable for the dynamic reconfiguration port
          .reset_in(reset_p),    //리셋 신호// Reset signal for the System Monitor control logic
          .vauxp6(vauxp6),       //JXADC포트로 아날로그 신호 입력받음, XDC 변경 필요 //채널6 양극// Auxiliary channel 6
          .vauxn6(vauxn6),       //JXADC포트로 아날로그 신호 입력받음, XDC 변경 필요 //채널6 음극
          .vauxp15(vauxp15),       
          .vauxn15(vauxn15),
//          busy_out,            //adc작동 중 신호 // ADC Busy signal
//          drdy_out,            //데이터 준비 신호 // Data ready signal for the dynamic reconfiguration port
          .channel_out(channel_out), //채널6, 현재 단일 채널로서 하나만 있음 //채널 선택 출력 // Channel Selection Outputs
          .do_out(do_out),           //아날로그가 디지털로 변환된 값을 출력 //출력 데이터 버스 //adc값 들어있음 // Output data bus for dynamic reconfiguration port
          .eoc_out(eoc_out)          //변환 완료 신호 //adc변환이 끝나면 1나옴 // End of Conversion Signal
//          eos_out,             //시퀀스 완료 신호 // End of Sequence Signal
//          alarm_out,           //모든 알람의 출력// OR'ed output of all the Alarms
          );

    wire eoc_out_pedge;           
    edge_detector_n ed(
        .clk(clk),
        .reset_p(reset_p),
        .cp(eoc_out),
        .p_edge(eoc_out_pedge)   
    );
    
    reg [11:0] adc_value_x, adc_value_y; //basys3의 ADC변환값이 12비트로만 나옴
    always @(posedge clk or posedge reset_p)begin
        if(reset_p) begin
            adc_value_x = 0;
            adc_value_y = 0;
        end
        else if(eoc_out_pedge)begin
            case(channel_out[3:0]) //원래 5비트지만 최상위 1비트는 모드 설정(비교 또는 기준에의한 설정)이므로 버림
                6: adc_value_x = do_out[15:4]; //상위 12비트가 adc 변환된 값
                15: adc_value_y = do_out[15:4];
            endcase
        end
    end     
    
    pwm_Nstep_freq #(
        .duty_step(256),  // 100단계로 나눔
        .pwm_freq(10000)     // PWM 주파수 50Hz
    ) pwm_red(
        .clk(clk),
        .reset_p(reset_p),
        .duty(adc_value_x[11:4]), //led밝기 256단계 8비트
        .pwm(led_r)
    );
    
    pwm_Nstep_freq #(
        .duty_step(256),  // 100단계로 나눔
        .pwm_freq(10000)     // PWM 주파수 50Hz
    ) pwm_green(
        .clk(clk),
        .reset_p(reset_p),
        .duty(adc_value_y[11:4]),
        .pwm(led_g)
    );
    
    wire [15:0] bcd_x, bcd_y, value;
    bin_to_dec bcd_adc_x(
        .bin({2'b0, adc_value_x[11:6]}), //fnd에 x축 y축에 각각 2자리밖에 표시안됨, 64까지만 표현 따라서 6비트 사용
        .bcd(bcd_x)
    );
    
    bin_to_dec bcd_adc_y(
        .bin({2'b0, adc_value_y[11:6]}),
        .bcd(bcd_y)
    );
          
    assign value = {bcd_x[7:0], bcd_y[7:0]};         
    fnd_cntr fnd_cntr_inst(
        .clk(clk),
        .reset_p(reset_p),
        .value(value),
        .com(com),
        .seg_7(seg_7)
        );          

endmodule
profile
개인 기록공간

0개의 댓글