https://insoobaik.tistory.com/635
PWM에 대한 내용은 위 글을 통해 참고하면된다.
STM32를 가지고 PWM을 통해 모터를 동작시킨 것과 동일하게 FPGA, Verilog를 통해 DC 모터 제어를 해 볼 것이다.
Motor | Motor Status | IN1 | IN2 | IN3 | IN4 |
MOTOR_A | Foward Rotation | 1/PWM | 0 | ||
Reverse | 0 | 1/PWM | |||
STOP | 0 | 0 | |||
Break | 1 | 1 |
DC 모터의 경우 ARR값에 대한 CCR값을 통해 속도를 조절 할 수 있다.
DC 모터의 속도는 ARR에 의해 정해진 타이머 주기의 평균 전압에 의해 정해지며, 평균 전압은 duty cycle 비율에 따라 달라지게 된다.
verilog code
module moter(
input [3:0] sw,
input clk,
input rst,
output reg pwm_out,
output wire nsleep
);
reg [25:0] counter;
reg [3:0] pwm_counter;
assign nsleep = 1;
always @(posedge clk or posedge rst) begin
if(rst) begin
pwm_out <= 0;
counter <= 0;
pwm_counter <= 0;
end else begin
if(counter>=49999) begin
counter <= 0;
pwm_counter <= pwm_counter +1;
if(pwm_counter>=15) begin
pwm_counter <= 0;
end
end else begin
counter <= counter+1;
end
if(pwm_counter <sw)
pwm_out <= 1;
else
pwm_out <= 0;
end
end
ila_0 u12(.clk(clk), .probe0(pwm_out), .probe1(pwm_counter));
endmodule
위 코드는 4개의 스위치를 통해 총 duty cycle을 총 16단계로 나눈 코드다.
스위치를 통해 들어온 값을 비교하여 pwm_counter를 통해 sw 들어온 값보다 적은 숫자까지 1의 값을 전달하고, 나머지는 0의 값을 전달하도록 한다.
스위치와 pwm_counter 둘 전부 [3:0] 즉 0~15까지 카운트가 가능하며 만약 스위치의 값이 0100의 값이 들어오게 되면 pwm_counter는 3까지 1을 전달하고 나머지는 0을 전달하게 된다.
이는 duty cycle이 25%가 되는 것을 의미한다.
testbench
module tb_moter;
reg [3:0] sw1;
reg clk;
reg rst;
wire pwm_out1;
wire pwm_out2;
wire pwm_out3;
wire pwm_out4;
wire nsleep;
reg [3:0] sw2;
reg [3:0] sw3;
reg [3:0] sw4;
moter moter_dut1(.sw(sw1), .clk(clk), .rst(rst), .pwm_out(pwm_out1), .nsleep(nsleep));
moter moter_dut2(.sw(sw2), .clk(clk), .rst(rst), .pwm_out(pwm_out2), .nsleep(nsleep));
moter moter_dut3(.sw(sw3), .clk(clk), .rst(rst), .pwm_out(pwm_out3), .nsleep(nsleep));
moter moter_dut4(.sw(sw4), .clk(clk), .rst(rst), .pwm_out(pwm_out4), .nsleep(nsleep));
always #5 clk = ~clk;
initial begin
sw1 = 0;
clk = 0;
rst = 1;
#10
rst = 0;
sw1 = 4'b0001;
end
initial begin
sw2 = 0;
clk = 0;
rst = 1;
#10
rst = 0;
sw2 = 4'b0010;
end
initial begin
sw3 = 0;
clk = 0;
rst = 1;
#10
rst = 0;
sw3 = 4'b0100;
end
initial begin
sw4 = 0;
clk = 0;
rst = 1;
#10
rst = 0;
sw4 = 4'b1000;
end
endmodule
testbench를 통해 크게 4가지 경우에 신호를 시뮬레이션을 통해 확인해볼 것이다.
스위치 입력에 따른 4가지 상황에서 duty cycle이 다른 것을 확인할 수 있다. 1의 신호가 길수록 DC 모터의 속도는 빨라진다.
코드를 통해 생성된 논리 게이트들은 위와 같다.
위 논리 게이트를 통해 입력 신호를 받아 출력 신호로 DC 모터의 속도를 조절하게 된다.
이후 I/O Port를 FPGA 보드의 각 Port에 맞게 설정한 뒤 Bitstream을 통해 실행 파일을 FPGA 보드에 전달하면 아래와 같이 DC 모터가 제어되는 것을 확인할 수 있다.
수행 영상
'Semiconductor > 0. FPGA' 카테고리의 다른 글
FPGA - STM32 UART 이용한 DC Motor 제어 및 신호 확인 (0) | 2024.07.30 |
---|---|
FPGA - SPI 통신을 이용한 DC Motor 제어하기 (0) | 2024.07.15 |
FPGA - CHARACTER LCD에 문자 입력하기 (0) | 2024.06.18 |
FPGA - 7-Segment Count Up (0~9999) / FPGA (0) | 2024.06.02 |
FPGA - ILA(Integrated Logic Analyzer) 사용법 (0) | 2024.05.07 |