EE 552
Application Notes
By
Shaun Luong
Clifton Yeung
J.P. Kansky
Patrick Asiedu-Ampem
Here are a few web-sites that you might find useful:
ELECTRONICS FOR U:
www.electronicsforu.com/efyhome/index2.html
This site contains links to hundreds of sites related
to electronics and electronic design. It contains a large number of free
downloadable circuits that might help speed up the design of projects.
Here is a list of some of the circuits available for download:
- Automatic Temperature Controller
- Programmable Musical Bell
- Ultrasonic Switch
- Sound Controlled Flip-Flop
- Simple IF
- Single IC Based Optical Toggle Switch
- Digital Speedometer
- Sensitive Temperature Switch
All circuits have detailed schematics with all the necessary
information required to build the circuit. In most cases, there is also
a detailed description explaining the circuit as well.
Acroname Inc. Robotics:
www.arconame.com/robotics/robotics.html
This site contains information mainly about robotics.
It has lists of sensors used in robotics along with their uses and limitations.
Other interesting things include a list of information
on Robotic Competitions and Articles relating to interfacing sensors, robotics
in general, robotic related topics.
Jameco Electronic Components:
http://www.jameco.com/
Jameco is a leading supplier of electronic parts. We were
able to purchase parts from Jameco that we weren't able to find anywhere
else. If you have trouble getting the parts you need, you might want to
give these guys a try.
VHDL Modules
The following source codes are modules that may be of
use to you. All were compiled and simulated using the FLEX10K EPF10K20RC240-4
device. The timing analyses are based on this chip and MAX+plus II Version
8.1 9/12/97. All signals are active high.
I. Bi-directional Integer Counter: "bi_count.vhd"
This is a synchronous bi-directional (up/down) integer
counter. The present count is not actually visible to other modules, but
it does set a "done" signal high when it is finished counting
up to "count_number" from zero or down to zero from "count_number".
The "count_direction" and "count_number" (integer value)
are set by generic parameters; '1' for counting up, '2' for counting down.
This counter can be useful when you need to stop/reset your system after
it has performed a calculation or operation a specified number of times.
The count is incremented/decremented via a "count_enable" input.
-- file "bi_count.vhd"
---------------------------------------------------------------------
-- a synchronous up/down decimal
counter;
-- cannot read the actual count,
but counter sets 'done' high
-- when it finishes counting
up to 'count_number' or downto 0
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
entity bi_count is
- generic(count_number: positive:=
35;
- count_direction: positive:=
1);
- port
- (
- clock, reset, count_enable:
in std_logic;
- done: out std_logic
- );
- -- if count_direction = '1'
, count up
- -- if count_direciton = '2'
, count down
end bi_count;
architecture behavioural of
bi_count is
- begin
- counting: process(clock, reset,
count_enable)
- variable count: integer := 0;
- begin
- if rising_edge(clock) then
- -- count up
- if count_direction = 1 then
- if reset = '1' then
- elsif count = count_number then
- elsif count_enable = '1' then
- end if;
- -- count down
- elsif count_direction = 2 then
- if reset = '1' then
- count := count_number;
- done <= '0';
- elsif count = 0 then
- elsif count_enable = '1' then
- end if;
- end if;
- end if;
- end process counting;
- end behavioural;
Timing Considerations:
The minimum clock period to count up to 35 is 93.2 ns.
The "count_enable" input must start after the falling edge of
the "reset", and be 1 clock period wide to increment/decrement
the count by only 1. The "count_enable" pulses must be at least
half a clock period apart for incrementing/decrementing the count by only
1; any wider or more frequent would result in an increment/decrement of
more than 1.
II. Pulse Counter: "timer.vhd"
This pulse counter outputs the number of clock pulses
between two triggers, "latch_on" and "latch_off". More
specifically, it ouputs the number of clock rising edges (excluding the
last one if it occurs at the same time as the "latch_off" rising
edge) in between the rising edges of "latch_on" and "latch_off".
The maximum decimal output is set by the generic parameter "counter_width"
N, and is equal to 2N.
-- file "timer.vhd"
-- Counts the number of clock
pulses between two triggers
-----------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity timer is
- generic(counter_width: positive:=
18);
- port
- (
- clock, reset: in std_logic;
- latch_on, latch_off: in std_logic;
- output: out std_logic_vector(counter_width-1
downto 0)
- );
end timer;
architecture counting of timer
is
- signal stepper: std_logic_vector(counter_width-1
downto 0);
begin
- process(clock, reset,
latch_on, latch_off)
- begin
- if rising_edge(clock) then
- if reset = '1' then
- elsif latch_on = '1' then
- if latch_off = '0' then
- else
- end if;
- elsif latch_off = '1' then
- end if;
- if count = true then
- else
- end if;
- end if;
- end process;
- output <= stepper;
end counting;
Timing Considerations
The minimum clock period for N=18 is 21.9 ns. Both latches
have to be set after the falling edge of the "reset". Each latch
signal must be at least 1 clock period wide, and the rising edge of "latch_off"
must occur at least 1 clock period after the rising edge of "latch_on".
III. Bi-directional Shift Register: "shift_rg.vhd"
This is a bi-directional (left or right), loadable, N-bit
shift register. The width and direction are set by generic parameters;
when "direction" is '1'- left shifting, '2'- right shifting.
The default shift-in bit is '0', but this can be changed to '1' using the
"shift_in_bit" input. The shifting occurs via a "shift_enable"
input. A "shift_out_bit" is an output, as well as the actual
shifted binary number.
-- file "shift_rg.vhd"
----------------------------------------------------------------------------
-- N-bit bi-directional shift
register
library ieee;
use ieee.std_logic_1164.all;
entity shift_rg is
- generic(register_width: positive:=
8;
- shift_direction: positive:=
2);
- port
- (
- clock, clear, load: in std_logic;
- shift_enable, shift_in_bit:
in std_logic;
- shift_out_bit: out std_logic;
- input: in std_logic_vector(register_width-1
downto 0);
- output: buffer std_logic_vector(register_width-1
downto 0)
- );
- -- if shift_direction = '1'
then shift left
- -- if shift_dirceciton = '2'
then shift right
end shift_rg;
architecture behavioural of
shift_rg is
- signal number: std_logic_vector(register_width-1
downto 0);
begin
- shift: process(clock, clear,
load, shift_enable)
- begin
- if rising_edge(clock) then
- if clear = '1' then
- number <= (others => '0');
- elsif load = '1' then
- elsif load = '0' then
- if shift_enable = '1' then
- -- shifting right
- if shift_direction = 2 then
- move_right: for i in 0 to register_width-2
loop
- output(i) <= number(i+1);
- end loop move_right;
- output(register_width-1) <=
shift_in_bit;
- shift_out_bit <= number(0);
- -- shifting left
- elsif shift_direction = 1 then
- move_left: for j in 1 to register_width-1
loop
- output(j) <= number(j-1);
- end loop move_left;
- output(0) <= shift_in_bit;
- shift_out_bit <= number(register_width-1);
- end if;
- elsif shift_enable = '0' then
- end if;
- end if;
- end if;
- end process shift;
end behavioural;
Timing Considerations
The minimum clock period for an 8-bit shift register is
10.5 ns. The "load" signal must extend at least half a clock
period after the "clear". The "shift_enable" signal
must be at least 1 clock period wide, and 1 clock period after the previous
pulse for the register to shift only once. However, the signal can be as
wide as you like, but one pulse (regardless of pulse width) corresponds
to 1 shift.
Controlling a Stepper Motor
Here is code for the stepper motor control circuit (figure
3) that is posted by Phillip Jacobsen, Shane Pilsworth, and Nancy Huntingford.
Thanks guys.
Figure 3
Here is the code for the XOR Gates,JK Flip-Flops and the
complete circuit.
-- D Flip-Flop with clock
library ieee;
use ieee.std_logic_1164.all;
ENTITY kjflip IS
- PORT (J,K : IN std_logic;
- clk, reset, set : IN STD_LOGIC;
- QA, QB : buffer STD_LOGIC
- );
END kjflip;
ARCHITECTURE A OF kjflip IS
BEGIN
PROCESS (clk, J, K)
BEGIN
IF (clk'EVENT AND clk = '1') THEN
- IF (set = '1') then
- QA <= '1';
- QB <= '0';
- end if;
- IF (reset = '1') then
- end if;
- if (J='0' AND K='0' AND QA='0') then
- end if;
- if (J='0' AND K='0' AND QA='1') then
- END IF;
- if (J='0' AND K='1' AND QA='0') then
- END IF;
- if (J='0' AND K='1' AND QA='1') then
- END IF;
- if (J='1' AND K='0' AND QA='0') then
- END IF;
- if (J='1' AND K='0' AND QA='1') then
- END IF;
- if (J='1' AND K='1' AND QA='0') then
- END IF;
- if (J='1' AND K='1' AND QA='1') then
- END IF;
- END IF;
END PROCESS;
END A;
-- XOR GATE
library ieee;
use ieee.std_logic_1164.all;
ENTITY xorc IS
PORT
- (A : IN std_logic;
- B : IN STD_LOGIC;
- C : buffer STD_LOGIC);
END xorc;
ARCHITECTURE A OF xorc IS
BEGIN
PROCESS (A, B)
BEGIN
- if (A ='0' and B ='0') then
- end if;
- if (A ='0' and B ='1') then
- end if;
- if (A ='1' and B ='0') then
- end if;
- if (A ='1' and B ='1') then
- end if;
END PROCESS;
END A;
-- Motor control Circuit
library ieee;
use ieee.std_logic_1164.all;
entity motorcir is
port (Phase1, Phase2, Phase3, Phase4: out std_logic;
switch,set1,set2 : in std_logic;
clk, reset1, reset2 : in std_logic);
end entity motorcir;
architecture structural of motorcir is
component xorc
PORT
(A : IN std_logic;
B : IN STD_LOGIC;
C : buffer STD_LOGIC
);
end component;
component kjflip
PORT
(J,K : IN std_logic;
clk, set, reset : IN STD_LOGIC;
QA, QB : buffer STD_LOGIC
);
end component;
signal node1, node2, node3, node4, node5, node6,
node7: std_logic;
signal nodea,vcc, phb, phc: std_logic;
begin
XOR1: xorc
port map(A => vcc, B => node1, c => nodea);
XOR2: xorc
port map(A => node7, B => node6, c => node2);
XOR3: xorc
port map(A => nodea, B => node2, c => node4);
XOR4: xorc
port map(A => node2, B => node1, c => node5);
jk1: kjflip
port map (clk => clk, J => node4, K => node4,
QA => node7,
QB => phb, set => set1, reset => reset1);
jk2: kjflip
port map (clk => clk, J => node5, K => node5,
QA => phc,
QB => node6, set => set2, reset => reset2);
node1 <= switch;
Phase1 <= node7;
Phase2 <= phb;
Phase3 <= phc;
Phase4 <= node6;
vcc <= '1';
end architecture structural;