Я новичок в языке VHDL и сейчас пытаюсь создать управляемый шаговый двигатель. Это должно быть что-то вроде this (я на самом деле получил эту картинку из своего кода с Тиной)
И это мой код:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_signed.ALL;
ENTITY state_stepper_halfstep IS
PORT(clk, plus, minus, start: IN STD_LOGIC;
q0,q1,q2,q3: OUT STD_LOGIC;
a7,b7,c7,d7,e7,f7,g7,h7: OUT std_logic);
END state_stepper_halfstep;
ARCHITECTURE arc OF state_stepper_halfstep IS
TYPE state_type IS (s0, s1, s2, s3, s4, s5, s6, s7);
SIGNAL state: state_type;
SIGNAL q: STD_LOGIC_VECTOR(3 downto 0);
SIGNAL counter: integer range 0 to 21 :=11;
SIGNAL digit: std_logic_vector (7 downto 0);
BEGIN
PROCESS (plus, minus, start, clk)
BEGIN
IF rising_edge(plus) THEN -- + Rotation value
counter <= counter+1;
IF counter > 20 THEN
counter <= 20;
END IF;
ELSIF rising_edge(minus) THEN -- - Rotation Value
counter <= counter-1;
IF counter < 2 THEN
counter <= 2;
END IF;
END IF;
IF start = '1' THEN
IF counter > 11 THEN -- When value > 0
WHILE counter > 11 LOOP -- Clockwise looping
EXIT WHEN counter = 11;
IF rising_edge(clk) THEN -- Clockwise Steps
CASE state IS
WHEN s0 => state <= s1;
WHEN s1 => state <= s2;
WHEN s2 => state <= s3;
WHEN s3 => state <= s4;
WHEN s4 => state <= s5;
WHEN s5 => state <= s6;
WHEN s6 => state <= s7;
counter <= counter-1;
WHEN s7 => state <= s0;
END CASE;
END IF;
END LOOP;
ELSIF counter < 11 THEN -- When value < 0
WHILE counter < 11 LOOP -- Counter-clockwise looping
EXIT WHEN counter = 11;
IF rising_edge(clk) THEN -- Counter-clockwise Steps
CASE state IS
WHEN s0 => state <= s7;
WHEN s7 => state <= s6;
WHEN s6 => state <= s5;
WHEN s5 => state <= s4;
WHEN s4 => state <= s3;
WHEN s3 => state <= s2;
WHEN s2 => state <= s1;
counter <= counter+1;
WHEN s1 => state <= s0;
END CASE;
END IF;
END LOOP;
ELSIF counter = 11 THEN -- When value = 0
counter <= counter;
END IF;
ELSE state <= state;
END IF;
END PROCESS;
WITH state SELECT
q <= "0001" WHEN s0,
"0011" WHEN s1,
"0010" WHEN s2,
"0110" WHEN s3,
"0100" WHEN s4,
"1100" WHEN s5,
"1000" WHEN s6,
"1001" WHEN s7;
q0 <= q(0);
q1 <= q(1);
q2 <= q(2);
q3 <= q(3);
with counter select
digit<= "11000000" when 11,
"11111001" when 12,
"10100100" when 13,
"10110000" when 14,
"10011001" when 15,
"10010010" when 16,
"10000010" when 17,
"11111000" when 18,
"10000000" when 19,
"10010000" when 20,
"01111001" when 10,
"00100100" when 9,
"00110000" when 8,
"00011001" when 7,
"00010010" when 6,
"00000010" when 5,
"01111000" when 4,
"00000000" when 3,
"00010000" when 2;
a7 <= digit(0);
b7 <= digit(1);
c7 <= digit(2);
d7 <= digit(3);
e7 <= digit(4);
f7 <= digit(5);
g7 <= digit(6);
h7 <= digit(7);
END arc;
Вот как это на самом деле должно работать:
1. Я могу выбрать, сколько раз будет вращаться шаговый двигатель (обозначается светодиодами) с помощью переключателей «плюс» и «минус» (он может отсчитывать от -9 до 9)
2. Точка 7 сегмента является отрицательным знаком для числа, показанного на дисплее
3. Положительное значение заставит двигатель вращаться по часовой стрелке
4. Отрицательное значение (показано точкой в 7 сегментах) заставит двигатель вращаться против часовой стрелки
5. Каждый раз, когда двигатель выполняет 1 оборот, число 7 сегментов должно уменьшаться на 1 число
6. Шаговый двигатель начнет вращаться только в том случае, если я его запустил (с заданием высокой логики для входа «пуск»)
Проблема возникает всякий раз, когда я пытаюсь смоделировать цепь и нажимаю «старт». Тина просто повесится, а затем "Не отвечает". Честно говоря, я не уверен в том, какую ошибку я допустил в своем коде, потому что Тина не выдает ошибку, когда я пытаюсь «войти в новый макрос» с моим VHDL-кодом.
Мое лучшее предположение - я допустил ошибку в своей циклической команде
IF start = '1' THEN
IF counter > 11 THEN -- When value > 0
WHILE counter > 11 LOOP -- Clockwise looping
EXIT WHEN counter = 11;
IF rising_edge(clk) THEN -- Clockwise Steps
CASE state IS
WHEN s0 => state <= s1;
WHEN s1 => state <= s2;
WHEN s2 => state <= s3;
WHEN s3 => state <= s4;
WHEN s4 => state <= s5;
WHEN s5 => state <= s6;
WHEN s6 => state <= s7;
counter <= counter-1;
WHEN s7 => state <= s0;
END CASE;
END IF;
END LOOP;
ELSIF counter < 11 THEN -- When value < 0
WHILE counter < 11 LOOP -- Counter-clockwise looping
EXIT WHEN counter = 11;
IF rising_edge(clk) THEN -- Counter-clockwise Steps
CASE state IS
WHEN s0 => state <= s7;
WHEN s7 => state <= s6;
WHEN s6 => state <= s5;
WHEN s5 => state <= s4;
WHEN s4 => state <= s3;
WHEN s3 => state <= s2;
WHEN s2 => state <= s1;
counter <= counter+1;
WHEN s1 => state <= s0;
END CASE;
END IF;
END LOOP;
Я был бы очень рад, если бы кто-то мог указать на ошибку. Заранее спасибо и хорошего дня!