Translate
Friday, December 21, 2012
Blinking a LED at different intervals
Hello and welcome to today's post. Now that we have some background in VHDL and different I/O ports of a FPGA I was thinking of doing a small circuit that might come in handy: I want to make a LED blink at a frequency and when I push a button I want that frequency to change and so on. 4 frequencies should suffice.
The 4 frequencies that I want to use are:
- 1 HZ (1 second)
- 2 HZ (0.5 seconds)
- 5 HZ (0.2 seconds)
- 10 HZ (0.1 seconds)
From this it is clear that we will need 4 clock dividers in order to generate the 4 frequencies. A circuit to distribute those frequencies is needed also. O course this will be a 4 to 1 multiplexer.
Now what should be used for the selections of the mux? I already said that I want the frequency to change when I push a button so how could a button generate a 2 bit value? Very simple: first we connect a debouncing circuit to the button. If you don't know what that is please visit my post: Debouncing push buttons where you will find the code for this circuit. Also the clock divider has been covered in: Synchronization in sequential circuits (clock dividers). Now that the button is debounced, we need a counter that counts from 0 to 3 (the 2 bit combinations needed to select the multiplexer's inputs). Theory about counter circuits can be found at: A simple counter. The code used for the counter is a little different in this example so I will give he code here, don't use the counter in the A simple counter post.
Ok. Now we only need a simple circuit that drives the LED. When a clk period has passed the value will be inverted.
The final circuit will look like this (click on the picture to see it at it's full size):
Now for the code. Most of the circuits you already have. I have covered multiplexers in one of my earlier posts: Concurrent statements. Implement a 4 to 1 mux using the with...select statement presented at the end of the post.
The code for the counter:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.std_logic_unsigned.ALL;
entity counter is
Port ( clk : in STD_LOGIC;
reset : in STD_LOGIC;
sel : out STD_LOGIC_VECTOR (1 downto 0));
end counter;
architecture Behavioral of counter is
signal cnt:std_logic_vector(1 downto 0);
begin
sel<=cnt;
process(clk,reset)
begin
if(reset='1') then
cnt<=(others=>'0');
elsif(clk'event and clk='1') then
if(cnt=3) then
cnt<=(others=>'0');
else
cnt<=cnt+1;
end if;
end if;
end process;
end Behavioral;
The code for the LED driver is:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity led_driver is
Port ( clk : in STD_LOGIC;
led : out STD_LOGIC;
reset : in STD_LOGIC);
end led_driver;
architecture Behavioral of led_driver is
signal ledsig:std_logic;
begin
led<=ledsig;
process(clk)
begin
if(clk'event and clk='1') then
if(reset='1') then
ledsig<='0';
else
ledsig<=not ledsig;
end if;
end if;
end process;
end Behavioral;
Now the primary circuit is just a structural description uniting these other circuits. I will leave you to make the code. Th entity should look like this:
entity blinking_led is
Port ( clk : in STD_LOGIC;
reset : in STD_LOGIC;
button : in STD_LOGIC;
led : out STD_LOGIC);
end blinking_led;
Thank you for reading. If you have any questions please email me at: fpgatutorials@gmail.com
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment