printf("ho_tari\n");
18일차 본문
2025.07.28
rotary sw 디지털 회로 설계


로터리 엔코더는 가전제품의 메뉴 선택이나 시간설정 등에 많이 사용되는 부품.
건조기나 냉장고에서도 많이 사용.

엔코더란 기계적인 위치의 변화나 방향·각도 등을 검출하여 전기적인 신호로 출력하는 센서.
엔코더의 명칭은 「encode= 코드화 한다」가 유래이며, 각도나 위치 변위의 코드화, 즉 펄스 신호로 부호화 하는것을 말한다.
엔코더 종류에는 회전의 각도나 방향을 검출하는 로터리 엔코더와 직선의 위치나 이동량을 검출하는 리니어 엔코더 등이 있다
회전할 때 정해진 패턴의 신호를 출력하기 때문에 이 신호를 바탕으로 회전부가 얼마나 회전했는지를 파악할 수 있다.
회전입력 하나로 다양한 입력을 받음으로써 부품의 수를 줄일 수 있기 때문에 로터리엔코더는 여러 제품의 입력장치로
광범위하게 활용되고 있음.

로터리 엔코더: 회전속도 회전량 및 회전 방향을 검출 하는 센서 장치
사용자가 스위치를 돌리면, 스위치 내부의 접점들이 회전하며 특정 패턴으로 연결되고, 이 패턴 변화를 통해 각도 변화를 감지
즉, 회전 방향과 각도 변화량을 펄스 형태로 출력하여 디지털 신호로 처리할 수 있게 함.

출력 펄스는 회전 위치의 절대치가 아닌 회전한 각도에 의해 비례하는 펄스 출력
2비트 상태 {A, B}의 이전 상태 → 현재 상태 변화에 따라 방향을 판단


동작 원리
(1) 회전 감지:
EC11 로터리 스위치는 회전축에 연결된 원판(디스크)에 규칙적인 패턴(구멍 또는 틈)이 있다
이 원판은 두 개의 광학 센서 또는 기계식 접점과 함께 작동
(2) 신호 생성:
회전축이 회전하면, 원판의 패턴이 광학 센서 또는 기계식 접점을 통과하면서 빛을 차단하거나 연결
이 차단/연결 변화가 디지털 펄스 신호로 변환
(3)펄스 신호 처리:
생성된 펄스 신호는 컨트롤러와 같은 장치에서 입력으로 받아 처리




일반적인 가변 저항처럼 특정 각도 범위가 있는 것이 아니라,
360도 계속 회전할 수 있으며 회전 방향과 회전량을 감지하여 디지털 펄스 신호로 출력.
또한, EC11 엔코더는 푸시 버튼 스위치가 내장되어 있어, 노브를 누르는 동작도 감지할 수 있다.
절대적인 위치를 알려주는 것이 아니라, 얼마나 움직였고 어느 방향으로 움직였는지 알려줌.
전원이 꺼지면 마지막 위치 정보는 유지되지 않음.
이 두 신호는 서로 약 ¼ 주기(90도)의 위상차를 가짐.
이 위상차를 분석하여 엔코더의 회전 방향을 감지할 수 있다.
이는 메뉴 선택, 음소거 등의 기능을 구현하는 데 유용하다.
block diagram

rotary.v
`timescale 1ns / 1ps
module rotary(
input clk,
input reset,
input clean_s1,
input clean_s2,
input clean_key,
output [15:0] led
);
reg [1:0] r_prev_state = 2'b00;
reg [1:0] r_curr_state = 2'b00;
reg [1:0] r_direction = 2'b00;
reg [7:0] r_count = 8'h00;
reg [15:0] r_led = 16'b0;
always @(posedge clk or posedge reset) begin
if (reset) begin
r_prev_state <= 2'b00;
r_curr_state <= 2'b00;
r_direction <= 2'b00;
r_count <= 8'h00;
r_led <= 16'b0;
end else begin
r_prev_state <= r_curr_state;
r_curr_state <= {clean_s1, clean_s2};
case ({r_prev_state, r_curr_state})
4'b0010, 4'b1011, 4'b1101, 4'b0100: begin // CW 00 -> 10 -> 11 -> 01 -> 00
if (r_count < 8'hFF) // overflow 방지
r_count <= r_count + 1;
r_direction <= 2'b01;
end
4'b0001, 4'b0111, 4'b1110, 4'b1000: begin // CCW 00 -> 01 -> 11 -> 10 -> 00
if (r_count > 8'h00) // underflow 방지
r_count <= r_count - 1;
r_direction <= 2'b10;
end
endcase
// clean_key ON/OFF 제어
r_led[13] <= ~clean_key;
// LED 출력 구성
r_led[15:14] <= r_direction;
r_led[12:8] <= 5'b0;
r_led[7:0] <= r_count;
end
end
assign led = r_led;
endmodule
top.v
`timescale 1ns / 1ps
module top(
input clk,
input reset, // btnU
input [2:0] btn,
input [7:0] sw,
input RsRx,
input s1, // JC1
input s2, // JC2
input key, // JC3
output RsTx,
output [7:0] seg,
output [3:0] an,
output [15:0] led
);
wire [2:0] w_btn_debounce;
wire [13:0] w_seg_data;
wire w_tick;
wire [7:0] w_rx_data;
wire w_rx_done;
// 디바운싱 된 입력
wire w_clean_s1, w_clean_s2, w_clean_key;
button_debounce u_button_debounce(
.i_clk(clk),
.i_reset(reset),
.i_btn(btn[0]),
.o_btn_clean(w_btn_debounce)
);
button_debounce #(.DEBOUNCE_LIMIT(200_000))u_s1_debounce( // debounce 2ms
.i_clk(clk),
.i_reset(reset),
.i_btn(s1),
.o_btn_clean(w_clean_s1)
);
button_debounce #(.DEBOUNCE_LIMIT(200_000))u_s2_debounce( // debounce 2ms
.i_clk(clk),
.i_reset(reset),
.i_btn(s2),
.o_btn_clean(w_clean_s2)
);
button_debounce #(.DEBOUNCE_LIMIT(200_000))u_key_debounce( // debounce 2ms
.i_clk(clk),
.i_reset(reset),
.i_btn(key),
.o_btn_clean(w_clean_key)
);
rotary u_rotary(
.clk(clk),
.reset(reset),
.clean_s1(w_clean_s1),
.clean_s2(w_clean_s2),
.clean_key(w_clean_key),
.led(led)
);
endmodule
Basys3-Master_original.xdc
## This file is a general .xdc for the Basys3 rev B board
## To use it in a project:
## - uncomment the lines corresponding to used pins
## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project
## Clock signal
set_property -dict { PACKAGE_PIN W5 IOSTANDARD LVCMOS33 } [get_ports clk]
create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports clk]
## Switches
set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 } [get_ports {sw[0]}]
set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports {sw[1]}]
set_property -dict { PACKAGE_PIN W16 IOSTANDARD LVCMOS33 } [get_ports {sw[2]}]
set_property -dict { PACKAGE_PIN W17 IOSTANDARD LVCMOS33 } [get_ports {sw[3]}]
set_property -dict { PACKAGE_PIN W15 IOSTANDARD LVCMOS33 } [get_ports {sw[4]}]
set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 } [get_ports {sw[5]}]
set_property -dict { PACKAGE_PIN W14 IOSTANDARD LVCMOS33 } [get_ports {sw[6]}]
set_property -dict { PACKAGE_PIN W13 IOSTANDARD LVCMOS33 } [get_ports {sw[7]}]
#set_property -dict { PACKAGE_PIN V2 IOSTANDARD LVCMOS33 } [get_ports {sw[8]}]
#set_property -dict { PACKAGE_PIN T3 IOSTANDARD LVCMOS33 } [get_ports {sw[9]}]
#set_property -dict { PACKAGE_PIN T2 IOSTANDARD LVCMOS33 } [get_ports {sw[10]}]
#set_property -dict { PACKAGE_PIN R3 IOSTANDARD LVCMOS33 } [get_ports {sw[11]}]
#set_property -dict { PACKAGE_PIN W2 IOSTANDARD LVCMOS33 } [get_ports {sw[12]}]
#set_property -dict { PACKAGE_PIN U1 IOSTANDARD LVCMOS33 } [get_ports {sw[13]}]
#set_property -dict { PACKAGE_PIN T1 IOSTANDARD LVCMOS33 } [get_ports {sw[14]}]
#set_property -dict { PACKAGE_PIN R2 IOSTANDARD LVCMOS33 } [get_ports { cin }]
## LEDs
set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports {led[0]}]
set_property -dict { PACKAGE_PIN E19 IOSTANDARD LVCMOS33 } [get_ports {led[1]}]
set_property -dict { PACKAGE_PIN U19 IOSTANDARD LVCMOS33 } [get_ports {led[2]}]
set_property -dict { PACKAGE_PIN V19 IOSTANDARD LVCMOS33 } [get_ports {led[3]}]
set_property -dict { PACKAGE_PIN W18 IOSTANDARD LVCMOS33 } [get_ports {led[4]}]
set_property -dict { PACKAGE_PIN U15 IOSTANDARD LVCMOS33 } [get_ports {led[5]}]
set_property -dict { PACKAGE_PIN U14 IOSTANDARD LVCMOS33 } [get_ports {led[6]}]
set_property -dict { PACKAGE_PIN V14 IOSTANDARD LVCMOS33 } [get_ports {led[7]}]
set_property -dict { PACKAGE_PIN V13 IOSTANDARD LVCMOS33 } [get_ports {led[8]}]
set_property -dict { PACKAGE_PIN V3 IOSTANDARD LVCMOS33 } [get_ports {led[9]}]
set_property -dict { PACKAGE_PIN W3 IOSTANDARD LVCMOS33 } [get_ports {led[10]}]
set_property -dict { PACKAGE_PIN U3 IOSTANDARD LVCMOS33 } [get_ports {led[11]}]
set_property -dict { PACKAGE_PIN P3 IOSTANDARD LVCMOS33 } [get_ports {led[12]}]
set_property -dict { PACKAGE_PIN N3 IOSTANDARD LVCMOS33 } [get_ports {led[13]}]
set_property -dict { PACKAGE_PIN P1 IOSTANDARD LVCMOS33 } [get_ports {led[14]}]
set_property -dict { PACKAGE_PIN L1 IOSTANDARD LVCMOS33 } [get_ports {led[15]}]
##7 Segment Display
set_property -dict { PACKAGE_PIN W7 IOSTANDARD LVCMOS33 } [get_ports {seg[0]}]
set_property -dict { PACKAGE_PIN W6 IOSTANDARD LVCMOS33 } [get_ports {seg[1]}]
set_property -dict { PACKAGE_PIN U8 IOSTANDARD LVCMOS33 } [get_ports {seg[2]}]
set_property -dict { PACKAGE_PIN V8 IOSTANDARD LVCMOS33 } [get_ports {seg[3]}]
set_property -dict { PACKAGE_PIN U5 IOSTANDARD LVCMOS33 } [get_ports {seg[4]}]
set_property -dict { PACKAGE_PIN V5 IOSTANDARD LVCMOS33 } [get_ports {seg[5]}]
set_property -dict { PACKAGE_PIN U7 IOSTANDARD LVCMOS33 } [get_ports {seg[6]}]
set_property -dict { PACKAGE_PIN V7 IOSTANDARD LVCMOS33 } [get_ports {seg[7]}]
# seg[7] : dp
set_property -dict { PACKAGE_PIN U2 IOSTANDARD LVCMOS33 } [get_ports {an[0]}]
set_property -dict { PACKAGE_PIN U4 IOSTANDARD LVCMOS33 } [get_ports {an[1]}]
set_property -dict { PACKAGE_PIN V4 IOSTANDARD LVCMOS33 } [get_ports {an[2]}]
set_property -dict { PACKAGE_PIN W4 IOSTANDARD LVCMOS33 } [get_ports {an[3]}]
##Buttons
set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 } [get_ports reset]
set_property -dict { PACKAGE_PIN W19 IOSTANDARD LVCMOS33 } [get_ports {btn[0]}]
set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 } [get_ports {btn[1]}]
set_property -dict { PACKAGE_PIN T17 IOSTANDARD LVCMOS33 } [get_ports {btn[2]}]
#set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 } [get_ports btnD]
##Pmod Header JA
#set_property -dict { PACKAGE_PIN J1 IOSTANDARD LVCMOS33 } [get_ports {JA[0]}];#Sch name = JA1
#set_property -dict { PACKAGE_PIN L2 IOSTANDARD LVCMOS33 } [get_ports {JA[1]}];#Sch name = JA2
#set_property -dict { PACKAGE_PIN J2 IOSTANDARD LVCMOS33 } [get_ports {JA[2]}];#Sch name = JA3
#set_property -dict { PACKAGE_PIN G2 IOSTANDARD LVCMOS33 } [get_ports {JA[3]}];#Sch name = JA4
#set_property -dict { PACKAGE_PIN H1 IOSTANDARD LVCMOS33 } [get_ports {JA[4]}];#Sch name = JA7
#set_property -dict { PACKAGE_PIN K2 IOSTANDARD LVCMOS33 } [get_ports {JA[5]}];#Sch name = JA8
#set_property -dict { PACKAGE_PIN H2 IOSTANDARD LVCMOS33 } [get_ports {JA[6]}];#Sch name = JA9
#set_property -dict { PACKAGE_PIN G3 IOSTANDARD LVCMOS33 } [get_ports {JA[7]}];#Sch name = JA10
##Pmod Header JB
#set_property -dict { PACKAGE_PIN A14 IOSTANDARD LVCMOS33 } [get_ports {JB[0]}];#Sch name = JB1
#set_property -dict { PACKAGE_PIN A16 IOSTANDARD LVCMOS33 } [get_ports {JB[1]}];#Sch name = JB2
#set_property -dict { PACKAGE_PIN B15 IOSTANDARD LVCMOS33 } [get_ports {JB[2]}];#Sch name = JB3
#set_property -dict { PACKAGE_PIN B16 IOSTANDARD LVCMOS33 } [get_ports {JB[3]}];#Sch name = JB4
#set_property -dict { PACKAGE_PIN A15 IOSTANDARD LVCMOS33 } [get_ports {JB[4]}];#Sch name = JB7
#set_property -dict { PACKAGE_PIN A17 IOSTANDARD LVCMOS33 } [get_ports {JB[5]}];#Sch name = JB8
#set_property -dict { PACKAGE_PIN C15 IOSTANDARD LVCMOS33 } [get_ports {JB[6]}];#Sch name = JB9
#set_property -dict { PACKAGE_PIN C16 IOSTANDARD LVCMOS33 } [get_ports {JB[7]}];#Sch name = JB10
##Pmod Header JC
set_property -dict { PACKAGE_PIN K17 IOSTANDARD LVCMOS33 } [get_ports { s1 }];#Sch name = JC1
set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 } [get_ports { s2 }];#Sch name = JC2
set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 } [get_ports { key }];#Sch name = JC3
#set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports {JC[3]}];#Sch name = JC4
#set_property -dict { PACKAGE_PIN L17 IOSTANDARD LVCMOS33 } [get_ports {JC[4]}];#Sch name = JC7
#set_property -dict { PACKAGE_PIN M19 IOSTANDARD LVCMOS33 } [get_ports {JC[5]}];#Sch name = JC8
#set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 } [get_ports {JC[6]}];#Sch name = JC9
#set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 } [get_ports {JC[7]}];#Sch name = JC10
##Pmod Header JXADC
#set_property -dict { PACKAGE_PIN J3 IOSTANDARD LVCMOS33 } [get_ports {JXADC[0]}];#Sch name = XA1_P
#set_property -dict { PACKAGE_PIN L3 IOSTANDARD LVCMOS33 } [get_ports {JXADC[1]}];#Sch name = XA2_P
#set_property -dict { PACKAGE_PIN M2 IOSTANDARD LVCMOS33 } [get_ports {JXADC[2]}];#Sch name = XA3_P
#set_property -dict { PACKAGE_PIN N2 IOSTANDARD LVCMOS33 } [get_ports {JXADC[3]}];#Sch name = XA4_P
#set_property -dict { PACKAGE_PIN K3 IOSTANDARD LVCMOS33 } [get_ports {JXADC[4]}];#Sch name = XA1_N
#set_property -dict { PACKAGE_PIN M3 IOSTANDARD LVCMOS33 } [get_ports {JXADC[5]}];#Sch name = XA2_N
#set_property -dict { PACKAGE_PIN M1 IOSTANDARD LVCMOS33 } [get_ports {JXADC[6]}];#Sch name = XA3_N
#set_property -dict { PACKAGE_PIN N1 IOSTANDARD LVCMOS33 } [get_ports {JXADC[7]}];#Sch name = XA4_N
##VGA Connector
#set_property -dict { PACKAGE_PIN G19 IOSTANDARD LVCMOS33 } [get_ports {vgaRed[0]}]
#set_property -dict { PACKAGE_PIN H19 IOSTANDARD LVCMOS33 } [get_ports {vgaRed[1]}]
#set_property -dict { PACKAGE_PIN J19 IOSTANDARD LVCMOS33 } [get_ports {vgaRed[2]}]
#set_property -dict { PACKAGE_PIN N19 IOSTANDARD LVCMOS33 } [get_ports {vgaRed[3]}]
#set_property -dict { PACKAGE_PIN N18 IOSTANDARD LVCMOS33 } [get_ports {vgaBlue[0]}]
#set_property -dict { PACKAGE_PIN L18 IOSTANDARD LVCMOS33 } [get_ports {vgaBlue[1]}]
#set_property -dict { PACKAGE_PIN K18 IOSTANDARD LVCMOS33 } [get_ports {vgaBlue[2]}]
#set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVCMOS33 } [get_ports {vgaBlue[3]}]
#set_property -dict { PACKAGE_PIN J17 IOSTANDARD LVCMOS33 } [get_ports {vgaGreen[0]}]
#set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports {vgaGreen[1]}]
#set_property -dict { PACKAGE_PIN G17 IOSTANDARD LVCMOS33 } [get_ports {vgaGreen[2]}]
#set_property -dict { PACKAGE_PIN D17 IOSTANDARD LVCMOS33 } [get_ports {vgaGreen[3]}]
#set_property -dict { PACKAGE_PIN P19 IOSTANDARD LVCMOS33 } [get_ports Hsync]
#set_property -dict { PACKAGE_PIN R19 IOSTANDARD LVCMOS33 } [get_ports Vsync]
##USB-RS232 Interface
set_property -dict { PACKAGE_PIN B18 IOSTANDARD LVCMOS33 } [get_ports RsRx]
set_property -dict { PACKAGE_PIN A18 IOSTANDARD LVCMOS33 } [get_ports RsTx]
##USB HID (PS/2)
#set_property -dict { PACKAGE_PIN C17 IOSTANDARD LVCMOS33 PULLUP true } [get_ports PS2Clk]
#set_property -dict { PACKAGE_PIN B17 IOSTANDARD LVCMOS33 PULLUP true } [get_ports PS2Data]
##Quad SPI Flash
##Note that CCLK_0 cannot be placed in 7 series devices. You can access it using the
##STARTUPE2 primitive.
#set_property -dict { PACKAGE_PIN D18 IOSTANDARD LVCMOS33 } [get_ports {QspiDB[0]}]
#set_property -dict { PACKAGE_PIN D19 IOSTANDARD LVCMOS33 } [get_ports {QspiDB[1]}]
#set_property -dict { PACKAGE_PIN G18 IOSTANDARD LVCMOS33 } [get_ports {QspiDB[2]}]
#set_property -dict { PACKAGE_PIN F18 IOSTANDARD LVCMOS33 } [get_ports {QspiDB[3]}]
#set_property -dict { PACKAGE_PIN K19 IOSTANDARD LVCMOS33 } [get_ports QspiCSn]
## Configuration options, can be used for all designs
set_property CONFIG_VOLTAGE 3.3 [current_design]
set_property CFGBVS VCCO [current_design]
## SPI configuration mode options for QSPI boot, can be used for all designs
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
set_property BITSTREAM.CONFIG.CONFIGRATE 33 [current_design]
set_property CONFIG_MODE SPIx4 [current_design]
'(Telechips) AI 시스템 반도체 SW 개발자 교육 > Verilog HDL' 카테고리의 다른 글
| 19일차 (0) | 2025.07.30 |
|---|---|
| 13일차 (0) | 2025.07.16 |
| 12일차 (0) | 2025.07.16 |
| 10일차 (0) | 2025.07.14 |
| 9일차 (0) | 2025.07.10 |