관리 메뉴

드럼치는 프로그래머

[시스템분석및설계] 14, 15장 7 세그먼트 제어기 설계, 스텝 모터 제어기 설계 예비레포트 본문

★─Multi Media/☆─2학년 2학기

[시스템분석및설계] 14, 15장 7 세그먼트 제어기 설계, 스텝 모터 제어기 설계 예비레포트

드럼치는한동이 2008. 3. 11. 01:04

◎ 실험 목적

7 세그먼트 제어기스텝 모터 제어기의 동작을 VHDL로 기술하고, 시뮬레이션을 통해 동작을 검증한다.

◎ 이론 설명

▶ 7 세그먼트 제어기 설계

사용자 삽입 이미지

① 7 세그먼트 LED는 이름 그대로 7개의 조각으로 되어 있는 LED이다. 그 7개의 LED 조각은 우리에게 친숙한 10진 숫자를 표시해 줄 수 있는 형 태 및 위치를 갖고 있다.

② 각 세그먼트마다 A ~ F 까지의 이름이 붙여져 있다. 어떤 것은 소수점 H까지 있다.

③ 7 세그먼트 LED 중에서 특정한 LED만을 켜면 우리가 보기에 숫자가 표시되는 것이다.

④ BCD 코드에서는 9 이상의 숫자에 대한 표현은 없다는 점도 잊지 말길 바란다.

⑤ BCD 코드의 숫자를 7 세그먼트에 표현해 주기 위해서는 BCD 코드를 입력으로 받아 들 여 7 세그먼트 중에 불이 켜져야만 하는 세그먼트들만을 적절하게 출력해주는 디코더가 필요하다. 이를 7 세그먼트 디코더라고 부른다.

⑥ 진리표

 

▶ 스텝 모터 제어기 설계

① 스텝 모터(Step-motor)는 일정한 각도씩 회전 또는 직선 운동을 하는 모터의 한 종류

-> 회전 운동 → 스텝 모터, 직선 운동 → 리니어 스텝 모터

② 산업용 로봇의 관절 기구와 같은 부분에 스텝 모터가 주로 채택

③ 이는 외부로부터 주어지는 하나의 입력 펄스당 일정 각도만큼 모터가 회전하여 자동 제 어에 적합한 형태이기 때문이다.

④ 펄스 신호 수에 비례한 만큼만 출력축이 회전하므로, DC 모터와는 달리 위치의 피드백 이 불필요하여, 자기지지 토크가 형성되기 때문에 브레이크 기구가 없어도 자체의 위치 결정 능력을 가지고 있는 점이 특징이다.

⑤ 모터에 부여되는 펄스 수에 따라 모터의 회전각이 제어되어진다.

⑥ 펄스 주파수(디지털 신호)에 의해 회전 속도가 제어되며, 구동 회로도 디지털 방식으로 동작하므로, 마이크로프로세서나 FPGA와 결합하기 쉬운 모터라고 할 수 있다.

⑦ 스텝 모터(step motor), 스텝핑 모터(stepping motor), 스텝퍼 모터(stepper motor), 펄 스 모터(pulse motor)는 다 같은 의미로 사용된다.

 

-> 스텝 모터의 특징

① 회전 각도는 입력 펄스 신호 수에 비례하여 정해진다.

② 회전 속도는 입력 펄스 rate(펄스 주파수)에 비례한다.

③ 회전자에 영구 자석을 사용하면 무자력 상태에서도, 자기유지력(self-holding torque, detent torque)이 발생한다.

④ 고토크, 고속 응답, 소형 경량이다.

⑤ 미세각, 고정밀도, 저가격이다.

⑥ DC 모터의 브러쉬에 의한 기계적인 마찰로 인한 파손이 없기 때문에, 보수가 필요없다.

⑦ 회전각 오차는 스텝(step)마다 누적 되지 않는다.

⑧ 특정 주파수에서 진동·공진이 발생하기 쉽고 관성이 있는 부하에 약하다.

⑨ 고속 운전시 탈조(출력이 입력 속도를 따라가지 못해 중강중간 펄스가 빠지며 심한 경우 정지해 버리는 현상)가 발생하기 쉽다.

 

-> 스텝 모터 구동 시스템

사용자 삽입 이미지

① 제어회로 - 스텝 모터를 운전하기 위해 필요한 제어 신호를 만들어 주는 곳이다.

② 구동회로 - 이 제어 신호를 받아 들여 스텝 모터의 권선으로, 전류를 공급하는 역할을 한다.

 

-> 스텝 모터의 구동 방식

① 유니폴라(unipolar) 구동 방식 - 권선의 한쪽 방향으로만 전류가 흐르도록 한다.

② 바이폴라(bipolar) 구동 방식 - 권선의 양쪽 방향으로 모두 전류가 흐르도록 한다.

 

-> 유니폴라 구동 방식

① 권선의 중앙에 공통(common) 전원 단자가 있는 스텝 모터의 구동에 사용된다.

트랜지스터가 ON이 될 때 공통(common) 단자로부터 A상이나, A상, 또 B상이나 B상으로 전류가 흐른다.

트랜지스터가 OFF일 때에는 전류가 흐르지 않는다.

전류가 흐를 때에는 항상 그 방향이 일정

⑤ A, A, B, B에 HIGH를 인가하여, 해당하는 트랜지스터를 ON 시키면 트랜지스터의 콜렉 터에 연결되어 있는 코일에 전류가 흐르게 되는데 이와 같은 과정의 코일을 여자 시킨다 고 말한다.

⑥ 유니폴라 구동의 여자 방식에는 1상 여자, 2상 여자, 1-2상 여자의 3가지 방식이 있다.

※ 유니폴라 구동에서의 여자 방식

-> A, A, B, B는 인가 되는 신호 순서, 1은 HIGH 전압, 0은 LOW 전압

(a) 1상 여자

 

스텝 1

스텝 2

스텝 3

스텝 4

A

1

0

0

0

B

0

1

0

0

A

0

0

1

0

B

0

0

0

1

 

(b) 2상 여자

 

스텝 1

스텝 2

스텝 3

스텝 4

A

1

0

0

1

B

1

1

0

0

A

0

1

1

0

B

0

0

1

1

 

(c) 1-2상 여자

 

스텝 1

스텝 2

스텝 3

스텝 4

스텝 5

스텝 6

스텝 7

스텝 8

A

1

1

0

0

0

0

0

1

B

0

1

1

1

0

0

0

0

A

0

0

0

1

1

1

0

0

B

0

0

0

1

0

1

1

1

 

◎ 실험 장비

▶ Xilinx ISE

▶ ModelSIM

▶ Rov-Lab 트레이닝 키트

 

◎ 실험 순서

▶ 7 세그먼트 제어기 설계

① 7 세그먼트 제어기의 동작을 VHDL로 기술

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity seg7 is

Port ( RSTB : in std_logic;

 

CLK_4M : in std_logic;

DIGIT : inout std_logic_vector(5 downto 0);

SEG : out std_logic_vector(6 downto 0));

end seg7;

achitecture Behavioral of seg7 is

signal clk_5000 : std_logic;

begin

--============ 자리 선택 Clock(500Hz) Generator ================

process(RSTB, CLK_4M)

variable cnt : integer range 0 to 4000;

begin

if RSTB = '0' then

cnt := 0;

clk_500 <= '0';

elsif rising_edge (CLK_4M) then

--

if cnt >= 3999 then -- 정상 동작시

if cnt >= 1 then

-- 시뮬레이션시

cnt := 0;

clk_500 <= not clk_500;

else

cnt := cnt + 1;

end if;

end process;

--================== Digit selection =========================

process(RSTB, clk_500)

begin

if RSTB = '0' then

DIGIT <= "100000";

elsif rising_edge (clk_500) then

DIGIT <= DIGIT(0) & DIGIT (5 downto 1);--선택자리 이동

end if;

end process;

--============== 각 자리마다 숫자 표시 =======================

process(DIGIT)

 

begin

case DIGIT is

when "100000" => SEG <= "0110000"; --첫 번째 1표시

when "010000" => SEG <= "1101101“; --두 번째 2표시

when "001000" => SEG <= "1111001"; --세 번째 3표시

when "000100" => SEG <= "0110011"; --네 번째 4표시

when "000010" => SEG <= "1011011"; --다섯 번째 5표시

when "000001" => SEG <= "1011111"; --여섯 번째 6표시

when others => SEG <= "0000000"; --표시 없음

end case;

end process;

--========================================================

end Behavioral;

 

  ② TestBenchWaveform으로 시뮬레이션

주어진 입력(RSTB, CLK_4M, DIGIT)에 따라 출력(SEG)이

진리표대로 정확하게 출력되는지를 검증

 

③ 트레이닝 키트로 동작 검증

주어진 입력(RSTB, CLK_4M, DIGIT)에 따라 출력(SEG)이

진리표대로 정확하게 출력되는지를 검증

 

▶ 스텝 모터 제어기 설계

(a) 모터 1바퀴 회전

① 모터 1바퀴 회전의 동작을 VHDL로 기술

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity motor1_rot is

Port ( CLK_4M : IN std_logic;

RSTB : IN std_logic; --Active 'L'

MTL_A : OUT std_logic;

MTL_B : OUT std_logic;

MTL_nA : OUT std_logic;

MTL_nB : OUT std_logic );

end motor1_rot;

 

archicture RoV_Lab of motor1_rot is

signal cnt : std_logic_vector (15 downto 0);

signal clk 40 : std_logic;

signal mot_cnt : std_logic_vector (1 downto 0);

signal phase_out : std_logic_vector (3 downto 0);

signal stop : std_logic;

signal step_cnt : integer range 0 to 200;

begin

--============= Motor Clock(40 Hz) Generator ==================

process(RSTB, CLK_4M, cnt)

begin

if RSTB = '0' then

cnt <= (others => '0');

clk_40 <= '0';

elsif rising_edge (CLK_4M) then

-- if cnt = X"C350" then -- 정상작동시

if cnt = X"0002" then -- 시뮬레이션시

cnt <= (others => '0');

clk_40 <= not clk_40;

else

cnt <= cnt + 1;

end if;

end if;

end process;

--================== Pharse OutPut (1상 여자 방식) ====================

process(clk_40, RSTB, mot_cnt)

begin

if RSTB = '0' then

mot_cnt <= (others => '0');

elsif rising_edge (clk_40) then

mot_cnt <= mot_cnt + 1;

end if;

end process;

process(mot_cnt, RSTB)

begin

if RSTB = '0' then

 

phase_out <= (others => '0');

else

case mot_cnt is

when "00" => phase_out <= "1000";

when "01" => phase_out <= "0100";

when "10" => phase_out <= "0010";

when "11" => phase_out <= "0001";

when others => phase_out <= "0000";

end case;

end if;

end process;

--======================== 1바퀴만 회전 후, 정지 =========================

process(RSTB, clk_40, step_cnt, stop)

begin

if RSTB = '0' then

stop <= '0'; step_cnt <= 0;

elsif rising_edge (clk_40) then

if step_cnt >= 200 then

stop <= '1';

else

step_cnt <= step_cnt + 1;

end if;

end if;

end process;

MTL_A <= phase_out(3) when stop = '0' else '0';

MTL_B <= phase_out(2) when stop = '0' else '0';

MTL_nA <= phase_out(1) when stop = '0' else '0';

MTL_nB <= phase_out(0) when stop = '0' else '0';

--========================================================

end RoV_Lab;

 

< 모터 1바퀴 회전 VHDL 코드>

신호 이름

입출력

설 명

CLK_4M

입력

트레이닝 키트에 있는 클럭 신호, 4MHz pin 79번으로 연결되어 있음

RSTB

입력

시스템 Reset 신호

MTL_A

출력

스텝 모터로 출력되는 신호, A상

MTL_B

출력

스텝 모터로 출력되는 신호, B상

MTL_nA

출력

스텝 모터로 출력되는 신호, A

MTL_nB

출력

스텝 모터로 출력되는 신호, B

신호 이름

설 명

cnt(15:0)

4MHz의 클럭을 40Hz으로 분주할 때 사용되는 보조 신호. 이 값이 어느 특정 값에 이르면 clk_40의 값을 반전 시킨다.

clk_40

40Hz 짜리 신호

mot_cnt(1:0)

1상 여자 방식의 4개의 스텝을 구분해 주기 위한 신호 그 값에 따라 순서대로 B, A, B, A를 구동케 한다.

phase_cnt(3:0)

스텝 모터로 연결되는 출력 신호의 묶음

MSG로부터 LSB로 순서대로 B, A, B, A에 연결됨.

(이 순서를 거꾸로 하면 모터의 회전 방향이 바뀜)

stop

정해진 스텝 수만큼만 회전하게 한 후 스텝 모터를 정지시키기 위한 신호

stop이 1이 되면 모터는 회전을 멈춘다

step_cnt

(0~200정수)

정해진 스텝 수만큼만 회전하게 한 후 스텝 모터를 정지시키고자 할 때 사용되는 보조 신호

이 값이 특정 값에 이르면 stop 신호를 1로 만든다.

 

< 모터 1바퀴 회전 코드 구조문 내부 신호 >

 

② TestBenchWaveform으로 시뮬레이션

주어진 입력(CLK_4M, RSTB)에 따라 출력 (MTL_A, MTL_B, MTL_nA, MTL_nB)이 진리표대로 정확하게 출력되는지를 검증

 

③ 트레이닝 키트로 동작 검증

주어진 입력(CLK_4M, RSTB)에 따라 출력 (MTL_A, MTL_B, MTL_nA, MTL_nB)이 진리표대로 정확하게 출력되는지를 검증

 

(b) 양쪽 모터 차등 속도 회전

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

 

entity motor2_rot is

Port ( CLK-4M : IN std_logic;

RSTB : IN std_logic; --Active 'L'

MTP_SW1: IN std_logic;

MTP_SW2: IN std_logic;

MTP_SW3: IN std_logic;

MTP_SWF: IN std_logic;

MTR_A : OUT std_logic;

MTR_B : OUT std_logic;

MTR_nA : OUT std_logic;

MTR_nB : OUT std_logic;

MTL_A : OUT std_logic;

MTL_B : OUT std_logic;

MTL_nA : OUT std_logic;

MTL_nB : OUT std_logic;

);

end motor2_rot;

 

architecture RoV_Lab of motor2_rot is

 

signal key_in_l : std_logic_vector( 1 downto 0 );

signal key_in_r : std_logic_vector( 1 downto 0 );

 

signal speed_l : integer range 0 to 25000;

signal speed_r : integer range 0 to 25000;

signal motor_lcnt : integer range 0 to 25000;

signal phase_lclk : std_logic;

signal motor_rcnt : integer range 0 to 25000;

signal phase_rclk : std_logic;

 

signal phase_lcnt : std_logic_vector ( 1 downto 0 );

signal phase_lout : std_logic_vector ( 3 downto 0 );

signal phase_rcnt : std_logic_vector ( 1 downto 0 );

signal phase_rout : std_logic_vector ( 3 downto 0 );

 

begin

--========= 스위치에 따른 좌,우 모터 속도 결정 ======================

 

key_in_l <= (MTP_SW1 & MTP_SW2);

key_in_R <= (MTP_SW3 & MTP_SWF);

process( key_in_l )

variable for_sim : std_logic;

begin

for_sim := '1'; -- 1: 시뮬레이션시 0:정상동작시

if for_sim = '0' then

case ket_in_l is

when "00" => speed_l <= 0; --0 Hz

when "01" => speed_l <= 19999;-- 100Hz

when "10" => speed_l <= 9999; -- 200Hz

when "11" => speed_l <= 6249; -- 320Hz

when others =>speed_l <= 6249;

end case;

else

case key_in_l is

when "00" => speed_l <= 0;

when "01" => speed_l <= 8;

when "10" => speed_l <= 4;

when "11" => speed_l <= 2;

when others =>speed_l <= 2;

end case;

end if;

end process;

process( key_in_r )

variable for_sim : std_logic;

begin

for_sim := '1'; -- 1: 시뮬레이션시 0:정상동작시

if for_sim = '0' then

case ket_in_r is

when "00" => speed_r <= 0; --0 Hz

when "01" => speed_r <= 19999;-- 100Hz

when "10" => speed_r <= 9999; -- 200Hz

when "11" => speed_r <= 6249; -- 320Hz

when others => speed_r <= 6249;

end case;

else

case key_in_r is

when "00" => speed_r <= 0;

when "01" => speed_r <= 8;

when "10" => speed_r <= 4;

when "11" => speed_r <= 2;

when others =>speed_r <=2;

end case;

end if;

end process;

 

process( RSTB , speed_l , CLK_4M , motor_lcnt )

begin

if RSTB = '0' or speed_l = 0 then

motor_lcnt <= 0;

phase_lclk <= '0';

elsif rising_edge (CLK_4M) then

if ( motor_lcnt >= speed_l ) then

motor_lcnt <= 0;

phase_lclk <= not phase_lclk;

else

motor_lcnt <= motor_lcnt +1;

end if;

end if;

end process;

 

process( RSTB , speed_r , CLK_4M , motor_rcnt )

begin

if RSTB = '0' or speed_r = 0 then

motor_rcnt <= 0;

phase_rclk <= '0';

elsif rising_edge (CLK_4M) then

if ( motor_rcnt >= speed_r ) then

motor_rcnt <= 0;

phase_rclk <= not phase_rclk;

else

motor_rcnt <= motor_rcnt +1;

end if;

end if;

end process;

 

--===========================================================

 

--======== 왼쪽 모터 phase Output ( 1상 여자방식 ) =================

process( RSTB , phase_lclk , phase_lcnt )

begin

if RSTB ='0' then

phase_lcnt <= ( others => '0' );

elsif rising_edge ( phase_lclk) then

phase_lcnt <= phase_lcnt +1;

end if;

end process;

process( RSTB , phase_lcnt )

begin

if RSTB ='0' then

phase_lout <= ( others => '0' );

else

case phase_lcnt is

when "00" => phase_lout <= "1000";

when "01" => phase_lout <= "0100";

when "10" => phase_lout <= "0010";

when "11" => phase_lout <= "0001";

when others => phase_lout <= "0000";

end case;

end if;

end process;

 

--===========================================================

 

--===========오른쪽 Phase Output ( 1상 여자방식 ) ==================

process( RSTB , phase_rclk , phase_rcnt )

begin

if RSTB = '0' then

phase_rcnt <= ( others => '0');

elsif rising_edge (phase_rclk) then

phase_rcnt <= phase_rcnt +1;

end if;

end process;

 

process( RSTB , phase_lcnt )

begin

if RSTB ='0' then

phase_rout <= ( others => '0' );

else

case phase_rcnt is

when "00" => phase_rout <= "1000";

when "01" => phase_rout <= "0100";

when "10" => phase_rout <= "0010";

when "11" => phase_rout <= "0001";

when others => phase_rout <= "0000";

end case;

end if;

end process;

--===========================================================

MTL_A <= phase_lout(0);

MTL_B <= phase_lout(1);

MTL_nA <= phase_lout(2);

MTL_nB <= phase_lout(3);

 

MTL_A <= phase_rout(0);

MTL_B <= phase_rout(1);

MTL_nA <= phase_rout(2);

MTL_nB <= phase_rout(3);

 

end RoV_Lab;


① 양쪽 모터 차등 속도 회전의 동작을 VHDL로 기술

< 양쪽 모터 차등 속도 회전 VHDL 코드>

스위치 1

스위치 2

왼쪽 모터

스위치 3

스위치 F

오른쪽 모터

누름(0)

누름(0)

0Hz(정지)

누름(0)

누름(0)

0Hz(정지)

누름(0)

유지(1)

100Hz

누름(0)

유지(1)

100Hz

유지(1)

누름(0)

200Hz

유지(1)

누름(0)

200Hz

유지(1)

유지(1)

320Hz

유지(1)

유지(1)

320Hz

(최고 속도)

< 스위치와 모터 속도 사이의 관계>

신호 이름

입출력

설 명

CLK_4M

입력

트레이닝 키트에 있는 클럭 신호, 4MHz pin 79번으로 연결되어 있음

RSTB

입력

시스템 Reset 신호

MTL_A

출력

왼쪽 스텝 모터로 출력되는 신호, A상

MTL_B

출력

왼쪽 스텝 모터로 출력되는 신호, B상

MTL_nA

출력

왼쪽 스텝 모터로 출력되는 신호, A

MTL_nB

출력

왼쪽 스텝 모터로 출력되는 신호, B

MTR_A

출력

오른쪽 스텝 모터로 출력되는 신호, A상

MTR_B

출력

오른쪽 스텝 모터로 출력되는 신호, B상

MTR_nA

출력

오른쪽 스텝 모터로 출력되는 신호, A

MTR_nB

출력

오른쪽 스텝 모터로 출력되는 신호, B

신호 이름

설 명

key_in_l (1:0)

왼쪽 모터 속도를 결정해 주기 위해 사용되는

키패트 스위치 1과 2의 상태 값.

스위치 1이 MSG, 스위치 2가 LSB

그 값이 11일 때 최대 속도, 00일 때 정지.

speed_l

왼쪽 모터의 속도를 결정해 주기 위해 사용되는 보조 값

왼쪽 모터에 인가해 주는 스텝의 주파스 =

4MHz / (speed_l + 1) * 2

즉, speed = 9999일 때, 모터 스텝 주파수는 200Hz

motor_lcnt

speed_l에 의해 결정된 왼쪽 모터 스텝 주파수를

만들어 주기 위해 사용되는 신호.

매 4MHz 클럭의 에지에서 1씩 증가하며, 그 값이 speed_l 값과 같아 지면 phase_lclk의 값을 반전시키며, 자신은 0으로 reset된다.

phase_lclk

왼쪽 모터의 스텝을 진행시키기 위해 사용되는 클록이 클록의 주파수가 왼쪽 모터의 속도를 결정한다.

phase_lcnt (1:0)

1상 여자 방식의 4개의 스텝을 구분해 주기 위한 신호

그 값에 따라 순서대로 A, A, B, B를 구통케 한다.

phase_lclk의 에지마다 1씩 증가한다.

phase_lout (1:0)

스텝 모터로 연결되는 출력 신호의 묶음.

MSB로부터 LSB로 순서대로 B, A, B, A에 연결됨.

이 순서를 반대로 하면 모터의 회전 방향이 바뀜.

 

② TestBenchWaveform으로 시뮬레이션

주어진 입력(CLK_4M, RSTB, MTP_SW1, MTP_SW2, MTP_SW3, MTP_SWF)에 따라

출력 (MTR_A, MTR_B, MTR_nA, MTR_nB, MTL_A, MTL_B, MTL_nA, MTL_nB)이

진리표대로 정확하게 출력되는지를 검증

 

③ 트레이닝 키트로 동작 검증

주어진 입력(CLK_4M, RSTB, MTP_SW1, MTP_SW2, MTP_SW3, MTP_SWF)에 따라

출력 (MTR_A, MTR_B, MTR_nA, MTR_nB, MTL_A, MTL_B, MTL_nA, MTL_nB)이

진리표대로 정확하게 출력되는지를 검증

Comments