URL
https://opencores.org/ocsvn/steppermotordrive/steppermotordrive/trunk
Subversion Repositories steppermotordrive
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 15 to Rev 16
- ↔ Reverse comparison
Rev 15 → Rev 16
/trunk/StepperMotorDrive.vhd
10,7 → 10,19
-- Please see the file "StepperMotorWiring.bmp" for info on connecting 4 & 6 |
-- wire motors to your device. This source should drive either type, though connection |
-- to 4-wire motors requires significantly more FET's to buffer outputs. The |
-- circuitry for 6-wire motors is more straightforward. |
-- circuitry for 6-wire motors is more straightforward. The colors specified are |
-- standard to many brands of stepper motors. If you get 1-2-3-4 on the FET's connected |
-- to 4-3-2-1 on your logic device (backwards), the motor will simply rotate backwards. |
-- if out of order, the motor won't rotate at all. Motors come in many dirrerent ratings |
-- of degrees rotation per step; some offer exceptional resolution very inexpensively. |
-- |
-- It is important to note that most logic operates at multiple megahertz. Given |
-- a steper motor at 100 steps per revolution, and a clock of 10MHz, running the |
-- motor at the full clock rate would equal 100,000 rps or 6 million revolutions per minute |
-- obviously, motors don't do this. Most steppers are designed for fine resolution at low |
-- speeds. Thus we employ a really big clock divider to get things operating at speeds |
-- of which the motor is capable. Check your motor ratings for a usefull value. |
-- in lieu of ratings, 100 rpm is usually achieveable, so plan accordingly. |
-- |
-- Another practical consideration is the threshold voltage of the FET's used to |
-- buffer the logic outputs & provide current drive to the motor. Most power |
31,23 → 43,29
-- One of the most advantageous abilities of stepper motors is the ability to |
-- provide static holding force in any position. Of course this consumes power |
-- and heats the motor up significantly (though steppers are rated to handle this) |
-- use of the "static holding" input port will specify this behavior. |
-- use of the "static holding" input port will specify this behavior. Be aware, |
-- however, that the motor will dissipate power if left energized for long periods |
-- without (or without for that matter) rotating. This will make them hot! They are |
-- usually designed for it, but it is a consideration, especially if in a small, |
-- sealed, enclosure, excess heat may make your logic cease functioning correctly at |
-- some point. |
|
entity StepperMotorPorts is |
Port ( |
StepDrive : out std_logic_vector(3 downto 0); |
clock : in std_logic; |
Direction : in std_logic; |
StepEnable : in std_logic; |
ProvideStaticHolding : in std_logic |
StepDrive : out std_logic_vector(3 downto 0); -- the 4 output to drive the MOSFETS driving the coils in the motor. |
clock : in std_logic; -- clock input to logic device |
Direction : in std_logic; -- spin clockwise or counter-clockwise? (actual direction depends on correct hookup/pin assignements) |
StepEnable : in std_logic; -- move a single step on next clock divider rollover. leave high for a single clock to get a single step. If high across rollover, may get two steps |
ProvideStaticHolding : in std_logic -- leave motor coils energized when not rotating, so that counter-torque is applied if attempt to move shaft |
); |
end StepperMotorPorts; |
|
architecture StepDrive of StepperMotorPorts is |
|
signal state : std_logic_vector(1 downto 0); |
signal StepCounter : std_logic_vector(31 downto 0); |
constant StepLockOut : std_logic_vector(31 downto 0) := "00000000000000110000110101000000"; |
signal state : std_logic_vector(1 downto 0); -- simple state machine, 4 states |
signal StepCounter : std_logic_vector(31 downto 0); -- most motors won't spin extrordinarially fast, so this slows the clock input way down |
constant StepLockOut : std_logic_vector(31 downto 0) := "00000000000000110000110101000000"; --rollover for the counter, to get a non-binary delay time divider |
signal InternalStepEnable : std_logic; -- used to capture a step enable even when we are in the wait loop for the clock divider. |
|
begin |
|
54,15 → 72,21
process(clock) |
begin |
|
if ( (clock'Event) and (clock = '1') ) then |
if ( (clock'Event) and (clock = '1') ) then --on clock |
|
StepCounter <= StepCounter + "0000000000000000000000000000001"; |
StepCounter <= StepCounter + "0000000000000000000000000000001"; --move the delay counter |
|
if (StepEnable = '1') then |
|
InternalStepEnable <= '1'; -- capture any requests for a step, even while we are waiting... |
|
end if; |
|
if (StepCounter >= StepLockOut) then |
|
StepCounter <= "00000000000000000000000000000000"; |
StepCounter <= "00000000000000000000000000000000"; -- if we just roll-ed over, then it's time to do something |
|
if (ProvideStaticHolding = '1') then |
if (ProvideStaticHolding = '1') then --should we leave coils in energized state by defaul or not? |
|
StepDrive <= "0000"; |
|
72,16 → 96,21
|
end if; |
|
if (StepEnable = '1') then |
|
if (Direction = '1') then state <= state + "01"; end if; |
if (Direction = '0') then state <= state - "01"; end if; |
if (InternalStepEnable = '1') then -- are we supposed to step on this clock? |
|
InternalStepEnable <= StepEnable; -- InternalStepEnable togles at the speed of the clock divider rollover, trailing the |
-- external StepEnable by less than or equal to one rollover. |
-- Putting this inside the "if internal=1" makes us wait until after move to turn off, |
-- so we move at least once for each pulse of external step enable line. |
|
if (Direction = '1') then state <= state + "01"; end if; -- to change the direction of a stepper motor, you energize |
if (Direction = '0') then state <= state - "01"; end if; -- the coils in the opposite pattern, so just run states backwards |
-- this also allows a change of direction at any arbitrary point |
case state is |
|
when "00" => |
|
StepDrive <= "1010"; |
StepDrive <= "1010"; -- these states follow proper pattern of coil energizing for turning steppers |
|
when "01" => |
|