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의 밝기가 커지는 것을 확인할 수 있다.
'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 |