Language/Verilog

Vivado : Basys3 Servo motor, Analog 제어, 가변 저항, 포토 센서(조도 센서)

짱도르딘 2024. 8. 2. 16:55
728x90

Servo Motor

이번에는 서보모터를 제어할 예정이다.

 

서보모터 관련 내용은 아래의 사진의 내용과 같다.

서보모터 데이터시트



서보모터를 동작시킬 탑모듈의 코드는 아래의 내용과 같다.

 

코드를 살펴보면, 0도, 90도, 180도 그리고 일정 각도마다 움직일 수 있도록 선언을 한 것을 확인할 수 있다.

 

module servo_motor_pwm_top(
    input clk, reset_p,
    input [3:0] btn,
    output motor_pwm,
    output [3:0] com,
    output [7:0] seg_7);
    
    reg [31:0] clk_div;
    always @(posedge clk or posedge reset_p)begin
        if(reset_p)clk_div = 0;
        else clk_div = clk_div + 1;
    end
    
    wire angle_0, angle_90, angle_180, angle;
    button_cntr btn0(.clk(clk), .reset_p(reset_p), .btn(btn[0]), .btn_pedge(angle_0));
    button_cntr btn1(.clk(clk), .reset_p(reset_p), .btn(btn[1]), .btn_pedge(angle_90));
    button_cntr btn2(.clk(clk), .reset_p(reset_p), .btn(btn[2]), .btn_pedge(angle_180));
    button_cntr btn3(.clk(clk), .reset_p(reset_p), .btn(btn[3]), .btn_pedge(angle));
    
    wire clk_div_nedge;
    edge_detector_n ed(.clk(clk), .reset_p(reset_p), .cp(clk_div[25]), .n_edge(clk_div_nedge));
    
    reg [5:0] duty;
    always @(posedge clk or posedge reset_p) begin
        if (reset_p) duty = 2;
        else if (angle_0) duty = 2;    // 0도 버튼 눌렸을 때
        else if (angle_90) duty = 6;   // 90도 버튼 눌렸을 때
        else if (angle_180) duty = 11; // 180도 버튼 눌렸을 때
        else if(angle) begin
            duty = duty + 2;
            if(duty >= 12) duty = 2;
        end
    end
    
    pwm_Nstep_freq #(
        .duty_step(100),
        .pwm_freq(50))
    pwm_motor(
    .clk(clk), 
    .reset_p(reset_p), 
    .duty(duty),
    .pwm(motor_pwm));
    
    wire [15:0] duty_bcd;
    bin_to_dec bcd_humi(.bin({6'b0, duty}), .bcd(duty_bcd));    
    fnd_cntr fnd(.clk(clk), .reset_p(reset_p), .value(duty_bcd), .com(com), .seg_7(seg_7));   

endmodule

 

동작 내용은 아래의 영상과 같다.

 

지정 버튼을 누를 때마다 서보모터가 0도, 90도, 180도로 변하는 것을 확인할 수 있다.


아날로그 제어

 

아날로그로 변환하려면 IP Catalog를 클릭해야 한다. 

 

IP Catalog 클릭 후 XADC Wizard를 더블클릭한다.

 

더블클릭하면 다음과 같은 창이 뜨는 것을 확인할 수 있다.

 

ADC 셋업 창에 들어간 후 아래와 같이 설정한다.

 

알람창에서는 아래와 같이 설정한다.

Single Channel에서는 6번 채널을 사용하기 위하여 아래와 같이 설정한다.

 

OK를 누르고 Global 설정 후 Generate를 누른다.


가변 저항

가변 저항을 활용하여 아날로그 신호를 다뤄보려고 한다.

 

가변 저항을 사용하기 위해서 아래와 같은 코드를 구현하였다.

module adc_ch6_top(
    input clk, reset_p,
    input vauxp6, vauxn6,
    output [3:0] com,
    output [7:0] seg_7);
    
    wire [4:0] channel_out;
    wire [15:0] do_out;
    wire eoc_out;
    xadc_wiz_0 adc_6
              (
              .daddr_in({2'b0, channel_out}),            // 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
              .reset_in(reset_p),            // Reset signal for the System Monitor control logic
              .vauxp6(vauxp6),              // Auxiliary channel 6
              .vauxn6(vauxn6),
              .channel_out(channel_out),         // Channel Selection Outputs
              .do_out(do_out),              // Output data bus for dynamic reconfiguration port
              .eoc_out(eoc_out)             // End of Conversion Signal
              );

    wire [15:0] adc_value;
    bin_to_dec bcd_adc(.bin(do_out[15:4]), .bcd(adc_value));    
    fnd_cntr fnd(.clk(clk), .reset_p(reset_p), .value(adc_value), .com(com), .seg_7(seg_7));              
              
endmodule

 

 

아래의 영상은 동작 결과를 나타낸다.

 

가변 저항을 돌릴 시 FND의 수치가 변하는 것을 확인할 수 있다. 저항값이 커질수록 FND의 값은 줄어들며, 작아질수록 FND의 값이 커지는 것을 확인할 수 있다.


포토 센서(조도 센서)

ADC를 활용하여 조도센서 또한 동작할 수 있다.

 

조도센서의 값에 따라 밝기 변화하는 LED를 구현하려고 한다.

 

코드는 아래와 같다.

 

duty값을 조절하여 LED의 밝기를 조절하고자 이전에 사용하였던 PWM 코드를 가져왔다.

 

그 외의 코드는 위의 코드와 동일하다.

module adc_ch6_top(
    input clk, reset_p,
    input vauxp6, vauxn6,
    output [3:0] com,
    output [7:0] seg_7,
    output led_pwm);
    
    wire [4:0] channel_out;
    wire [15:0] do_out;
    wire eoc_out;
    xadc_wiz_0 adc_6
              (
              .daddr_in({2'b0, channel_out}),            // 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
              .reset_in(reset_p),            // Reset signal for the System Monitor control logic
              .vauxp6(vauxp6),              // Auxiliary channel 6
              .vauxn6(vauxn6),
              .channel_out(channel_out),         // Channel Selection Outputs
              .do_out(do_out),              // Output data bus for dynamic reconfiguration port
              .eoc_out(eoc_out)             // End of Conversion Signal
              );

    pwm_Nstep_freq #(
        .duty_step(256),
        .pwm_freq(10000)) // LED니까 Freq는 10000
    pwm_backlight(
    .clk(clk), 
    .reset_p(reset_p), 
    .duty(do_out[15:8]),
    .pwm(led_pwm));

    wire [15:0] adc_value;
    bin_to_dec bcd_adc(.bin({2'b0, do_out[15:6]}), .bcd(adc_value));    
    fnd_cntr fnd(.clk(clk), .reset_p(reset_p), .value(adc_value), .com(com), .seg_7(seg_7));              
              
endmodule

 

조도 센서 코드를 동작시키면 다음과 같은 결과가 나오는 것을 확인할 수 있다.

 

조도 센서 부분을 손가락으로 가리면 FND 상으로 값이 내려가는 것을 확인할 수 있고, 값이 내려가면 LED의 밝기는 줄어들며, 값이 커질수록 LED의 밝기가 커지는 것을 확인할 수 있다.

 

 

 

 

728x90

'Language > Verilog' 카테고리의 다른 글

SoC : 기초  (0) 2024.09.09
Vivado : RGB LED, DC motor  (0) 2024.08.01
Vivado : PWM 제어  (0) 2024.07.31
Vivado : Basys3 종합 시계 프로젝트 (타이머, 스톱워치, 시계)  (2) 2024.07.30
Vivado : 온도 습도 센서  (0) 2024.07.25