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

posted @ 2021-12-14 23:15  KittySmith  阅读(1134)  评论(0编辑  收藏  举报