EDA通过VHDL代码设计一个跑马灯
EDA实验要求
只是参考,实验报告请自行完成,电路图,时序图请自行操作
〇、Quartus软件的安装
https://blog.csdn.net/weixin_43862765/article/details/99305902
一、LED显示
(1)按键K1作输入,LED1作输出;按下K1时,LED1亮,松开时灭。
(2)用文本输入法,编写VHDL文件,完成设计。
LIBRARY ieee;
USE ieee.std_logic_1164.all;
LIBRARY work;
ENTITY demo011 IS
PORT
(
k1 : IN STD_LOGIC;
led01 : OUT STD_LOGIC
);
END demo011;
ARCHITECTURE bdf_type OF demo011 IS
BEGIN
led01 <= k1;
END bdf_type;
(3)用图形输入法,完成设计。
二、译码器设计
按键K3、K2、K1用作三位编码地址输入(A2、A1、A0),LED8---LED1用作8位译码输出Y7--Y0;完成3—8译码器设计;按键按下时,输入为逻辑‘0’,松开时,为逻辑‘1’,LED亮时,对应有效的译码输出。完成设计。
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity decoder3to8 is
port (
A: in std_logic_vector (2 downto 0);
Y: out bit_vector(7 downto 0)
);
end decoder3to8;
architecture behave of decoder3to8 is
begin
Y<="00000001" sll conv_integer(A);
end behave;
三、分频器、计数器设计
SYS_CLK0用作时钟源(40MHZ),分频后,作1HZ方波信号。
思路:
SYS_CLK0用作时钟源(40MHZ), 可以理解为每秒钟按动40 000 000次按钮。
因此要达到1秒闪一次的话,就是指定一个范围让其交替亮暗。
例如0 - 40 000 000让 led1 输出 0 ,开发板的led灯是低电平有效, 因此为0时会亮
40 000 000 - 80 000 000 输出 1 , 就是不亮
当达到80 000 000时重置为0,形成了一个循环。
(1)驱动LED1闪烁。闪烁频率为1HZ。
LIBRARY ieee;
USE ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
ENTITY twinkle IS
PORT
(
clk : IN STD_LOGIC;
led01 : OUT STD_LOGIC
);
END twinkle;
ARCHITECTURE bdf_type OF twinkle IS
signal count :integer range 0 to 80000001;
BEGIN
process(clk)
begin
--if num=40000000 then num:=0;
--end if;
if (clk'event and clk='0') then
if count=80000000 then
count <=0;
else
count <=count+1;
end if;
if count>40000000 then
led01 <='1';
else
led01 <='0';
end if;
end if;
end process;
END bdf_type;
(2)跑马灯显示:LED1 - LED8循环显示。
LIBRARY ieee;
USE ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
ENTITY gall_led IS
PORT
(
clk : IN STD_LOGIC;
led : OUT STD_LOGIC_vector(7 downto 0)
);
END gall_led;
ARCHITECTURE bdf_type OF gall_led IS
signal count :integer range 0 to 160000000;
signal tmp :STD_LOGIC_vector(7 downto 0);
BEGIN
process(clk)
begin
if (clk'event and clk='0') then
if count=160000000 then
count <=0;
else
count <=count+1;
end if;
if count>=140000000 then
tmp <="01111111";
elsif count>=120000000 then
tmp <="10111111";
elsif count>=100000000 then
tmp <="11011111";
elsif count>=80000000 then
tmp <="11101111";
elsif count>=60000000 then
tmp <="11110111";
elsif count>=40000000 then
tmp <="11111011";
elsif count>=20000000 then
tmp <="11111101";
else
tmp <="11111110";
end if;
end if;
led<=tmp;
end process;
END bdf_type;
(3)十进制显示,LED1闪烁十次,LED2闪烁一次,实现LED1对 LED1十分频。
// 这个漏掉了,思路应该和之前的差不多, 大家自己尝试尝试。
LIBRARY ieee;
USE ieee.std_logic_1164.all;
LIBRARY work;
ENTITY demo01 IS
PORT
(
clk : IN STD_LOGIC;
led : OUT STD_LOGIC_VECTOR(0 to 1)
);
END demo01;
ARCHITECTURE bdf_type OF demo01 IS
BEGIN
process(clk)
variable count1: integer :=0 ;
variable count2: integer :=0 ;
begin
if (clk'event and clk='0') then
if count1 = 80000000 then
count1 := 0;
count2 := count2 + 1;
if count2 = 10 then
count2 := 0;
end if;
else
count1 :=count1+1;
end if;
end if;
if count1 >=40000000 then led(0)<='1';
else led(0)<='0';
end if;
if count2 = 9 and count1 <= 40000000 then led(1) <='0';
else led(1)<='1';
end if;
end process;
END bdf_type;
四、步进电机驱动
按下K1,步进电机正转;松开,步进电机静止,按下K2,步进电机反转,松开,步进电机静止。
先确认5V和其相邻的引脚的跳线有没有链接
MA (步进电机端) ---> 46 (FPGA端)
MB (步进电机端) ---> 45 (FPGA端)
MC (步进电机端) ---> 44 (FPGA端)
MD (步进电机端) ---> 43 (FPGA端)
FPGA端只要接到数字引脚就可以,在软件PIN中配置对应的就可以了,
但最好和上面一致, 方便操作
代码思路:
ABCD轮流高电平(例如A为'1' ,其它为'0'), 便能驱动电机
原理:
磁铁同性相斥, 当A通电时和电机中心磁铁相斥, 或者说产生了切向的安培力(我乱说的,大概是这样。。。)
因此轮流高电平,就一直有切向的力!!!
LIBRARY ieee;
USE ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
ENTITY stepper_motor2 IS
PORT
(
k1,k2: IN STD_LOGIC;
clk : IN STD_LOGIC;
led : OUT STD_LOGIC_vector(3 downto 0)
);
END stepper_motor2;
ARCHITECTURE bdf_type OF stepper_motor2 IS
-- 40 000 000 40000
signal count :integer range 0 to 4000000;
signal tmp :STD_LOGIC_vector(3 downto 0);
BEGIN
-- 注意每个if间是并行的, 但if里面的elsif是顺序执行的(描述用的是软件的想法)
process(clk,k1,k2)
-- 40 000 000 --> 4 000 000 10hz频率
begin
if ( clk'event and clk='0' ) then
if count=4000000 then
count <=0;
else
count <=count+1;
end if;
if count>=3000000 then
if (k1='0' and k2 = '1') then tmp <="0001"; --正转
elsif (k1='1' and k2 = '0') then tmp <="1000"; --反转
end if;
elsif count>=2000000 then
if (k1='0' and k2 = '1') then tmp <="0010";
elsif (k1='1' and k2 = '0') then tmp <="0100";
end if;
elsif count>=1000000 then
if (k1='0' and k2 = '1') then tmp <="0100";
elsif (k1='1' and k2 = '0') then tmp <="0010";
end if;
else
if (k1='0' and k2 = '1') then tmp <="1000";
elsif (k1='1' and k2 = '0') then tmp <="0001";
end if;
end if;
end if;
led<=tmp;
end process;
END bdf_type;
五、EDA实验课程设计
(1)学校统一模板。
(2)自主选题。
自己尝试
FPGA芯片型号:Cyclone EP1C12Q240(6Q240兼容)
LED1 PIN_50 K1 PIN_121
LED2 PIN_53 K2 PIN_122
LED3 PIN_54 K3 PIN_123
LED4 PIN_55 K4 PIN_124
LED5 PIN_176 SYS_CLK0 PIN_28
LED6 PIN_47
LED7 PIN_48
LED8 PIN_49