81 lines
2.0 KiB
VHDL
81 lines
2.0 KiB
VHDL
|
|
-- Test crude algorithm for a simple motor controller.
|
||
|
|
|
||
|
|
library ieee;
|
||
|
|
use ieee.std_logic_1164.all;
|
||
|
|
|
||
|
|
entity mc is
|
||
|
|
-- Control values that may be overrriden by the "sim_args" option
|
||
|
|
-- in a netlist's .model line. Intgers are used as GHDL does not
|
||
|
|
-- support overriding Real values.
|
||
|
|
generic (
|
||
|
|
Target : Integer := 4000; -- notional RPM
|
||
|
|
Dead_Band : Integer := 200;
|
||
|
|
Full_Band : Integer := 600
|
||
|
|
);
|
||
|
|
port (
|
||
|
|
Zero : in std_logic;
|
||
|
|
Tach : in std_logic;
|
||
|
|
Trigger : out std_logic
|
||
|
|
);
|
||
|
|
end mc;
|
||
|
|
|
||
|
|
architecture mc_arch of mc is
|
||
|
|
shared variable Speed : Real := 0.0;
|
||
|
|
begin
|
||
|
|
Tachometer : process (Tach) is
|
||
|
|
variable Time : Real := 0.0;
|
||
|
|
variable Last_pulse : Real := 0.0;
|
||
|
|
begin
|
||
|
|
if rising_edge(Tach) or falling_edge(Tach) then
|
||
|
|
Time := real(now / 1 ns) * 1.0e-9;
|
||
|
|
Speed := 30.0 / (Time - Last_pulse);
|
||
|
|
Last_pulse := Time;
|
||
|
|
end if;
|
||
|
|
end process Tachometer;
|
||
|
|
|
||
|
|
Controller : process (Zero) is
|
||
|
|
variable Skip : Integer := 0;
|
||
|
|
variable Count : Integer := 0;
|
||
|
|
variable Even : Boolean := True;
|
||
|
|
variable Was_even : Boolean := True;
|
||
|
|
variable Error : Integer;
|
||
|
|
begin
|
||
|
|
-- Trigger triac on zero crossings, preventing DC current.
|
||
|
|
|
||
|
|
if rising_edge(Zero) then
|
||
|
|
Even := not Even;
|
||
|
|
if (Count >= Skip) and (Even /= Was_even) then
|
||
|
|
Trigger <= '1';
|
||
|
|
Was_even := Even;
|
||
|
|
if Count > Skip then
|
||
|
|
Count := 0;
|
||
|
|
else
|
||
|
|
Count := -1;
|
||
|
|
end if;
|
||
|
|
else
|
||
|
|
Trigger <= '0';
|
||
|
|
end if;
|
||
|
|
Count := Count + 1;
|
||
|
|
|
||
|
|
-- A very crude feedback mechanism.
|
||
|
|
|
||
|
|
Error := integer(Speed) - Target;
|
||
|
|
if Error > Full_Band then
|
||
|
|
-- No drive
|
||
|
|
Skip := 1;
|
||
|
|
Count := 0;
|
||
|
|
elsif Error < -Full_Band then
|
||
|
|
-- Full Drive
|
||
|
|
Skip := 0;
|
||
|
|
elsif Error > Dead_Band then
|
||
|
|
Skip := Skip + 1;
|
||
|
|
elsif Error < -Dead_Band then
|
||
|
|
if Skip > 0 then
|
||
|
|
Skip := Skip - 1;
|
||
|
|
end if;
|
||
|
|
end if;
|
||
|
|
|
||
|
|
end if;
|
||
|
|
end process Controller;
|
||
|
|
end mc_arch;
|