Button 如何通过按下按钮正确增加显示屏各部分的照明速率
我正在用行为VHDL编程xilinx basys 3板。我正在照亮4x七段显示器的各个部分,使其看起来好像显示器有两个旋转的“轮子”。我的整个项目包括许多组件,如解码器、多路复用器、去抖动器、计数器、显示刷新率时钟分频器等。所有这些都已被我的教授清除。 我目前正在工作的组成部分,在一个250赫兹时钟和一个向上和向下的按钮。向上和向下按钮将允许增加映射到11个不同预分频值的计数器。这些值将相应地改变时钟分频器的最大步长 目前我的重置按钮工作。但是,“向上”和“向下”按钮只是暂停线段的旋转,而不是增加线段的旋转速率。我认为这一部分是问题所在,但我无法找出在这三个过程中的位置Button 如何通过按下按钮正确增加显示屏各部分的照明速率,button,vhdl,fpga,clock,xilinx,Button,Vhdl,Fpga,Clock,Xilinx,我正在用行为VHDL编程xilinx basys 3板。我正在照亮4x七段显示器的各个部分,使其看起来好像显示器有两个旋转的“轮子”。我的整个项目包括许多组件,如解码器、多路复用器、去抖动器、计数器、显示刷新率时钟分频器等。所有这些都已被我的教授清除。 我目前正在工作的组成部分,在一个250赫兹时钟和一个向上和向下的按钮。向上和向下按钮将允许增加映射到11个不同预分频值的计数器。这些值将相应地改变时钟分频器的最大步长 目前我的重置按钮工作。但是,“向上”和“向下”按钮只是暂停线段的旋转,而不是增
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.std_logic_unsigned.all;
entity wheelClkDiv is
Port ( btnUp, btnDown, clk, reset : in STD_LOGIC;
--up/down/rst buttons and 250Hz clk initialized as inputs
clkout : out STD_LOGIC
-- newly divided clock initialized as output
);
end wheelClkDiv;
architecture Behavioral of wheelClkDiv is
signal count : STD_LOGIC_VECTOR(19 downto 0) := x"00000"; --20 bit count value for clk divider
signal temp : STD_LOGIC := '0'; --temp store value for clk divider
signal countDiv : STD_LOGIC_VECTOR(19 downto 0) := x"00000"; --value given to choose prescalar
signal btn_counter : STD_LOGIC_VECTOR(3 downto 0) := "0110"; --button press counter
begin
buttonChoose : process(btnUp, btnDown, reset)
begin
if(btnUp = '1') then
btn_counter <= btn_counter + 1; --add one to count if up button pushed
elsif(btnDown = '1') then
btn_counter <= btn_counter - 1; --subtract one from count if down button pushed
elsif(reset = '1') then
btn_counter <="0110"; --set back to middle speed if reset is pushed
end if;
end process;
setDivideCase : process(btn_counter)
begin
case btn_counter is --case statement to choose prescalar based on btn_counter value
when "0000" =>
countDiv <= b"00000000000110010000"; --3.2s cycle
when "0001" =>
countDiv <= b"00000000000100101100"; --2.4s cycle
when "0010" =>
countDiv <= b"00000000000011001000"; --1.6s cycle
when "0011" =>
countDiv <= b"00000000000010010110"; --1.2s cycle
when "0100" =>
countDiv <= b"00000000000001100100"; --0.8s cycle
when "0101" =>
countDiv <= b"00000000000001001011"; --0.6s cycle
when "0110" =>
countDiv <= b"00000000000000110010"; --0.4s cycle
when "0111" =>
countDiv <= b"00000000000000100110"; --0.3s cycle
when "1000" =>
countDiv <= b"00000000000000011001"; --0.2s cycle
when "1001" =>
countDiv <= b"00000000000000010011"; --0.15s cycle
when "1010" =>
countDiv <= b"00000000000000001101"; --0.1s cycle
when others =>
countDiv <= b"00000000000000001101";--not correct
end case;
end process;
wheelDivider : process(clk, reset)
begin
if(reset = '1') then --reset clock count if reset pushed
count <= x"00000";
temp <= '0';
elsif(rising_edge(clk)) then
if(count = countDiv) then --set clk counter value to prescalar
count <= x"00000";
temp <= not temp;
else
count <= count + 1; --keep incrementing clk count until it matches PS
temp <= temp;
end if;
end if;
end process;
clkout <= temp; --give temp value to output clk
end Behavioral;
IEEE库;
使用IEEE.STD_LOGIC_1164.ALL;
使用IEEE.std_logic_unsigned.all;
实体wheelckdiv是
端口(btnUp、btnDown、clk、复位:在标准逻辑中;
--向上/向下/重新设置按钮和250Hz时钟初始化为输入
clkout:输出标准逻辑
--新划分的时钟初始化为输出
);
端轮CLKDIV;
wheelClkDiv的体系结构是
信号计数:标准逻辑向量(19到0):=x“00000”--clk除法器的20位计数值
信号温度:标准逻辑:='0'--时钟分配器的温度存储值
信号计数div:STD_逻辑_向量(19到0):=x“00000”--给定值以选择预分频器
信号btn_计数器:标准逻辑_向量(3到0):=“0110”--按钮按下计数器
开始
按钮选择:进程(btnUp、btnDown、重置)
开始
如果(btnUp='1'),则
btn_counter我看到的第一件事是忽略了count
信号不断计数的事实。
当您点击重置时,您的计数回到'x“00000”,这是它工作的唯一原因
但是,当您按下向上/向下按钮时,您将更改countDiv的值,例如
countDiv <= b"00000000000000110010"; --0.4s cycle
我不确定这是否是目前唯一的问题。希望如此。我看到的第一件事是你忽略了计数信号不断计数的事实。
当您点击重置时,您的计数回到'x“00000”,这是它工作的唯一原因
但是,当您按下向上/向下按钮时,您将更改countDiv的值,例如
countDiv <= b"00000000000000110010"; --0.4s cycle
我不确定这是否是目前唯一的问题。希望如此。谢谢您的反馈。我有点理解你说的话,但不完全理解。你有没有办法给我提供更多的代码来说明要修改什么而不是如何修改?@DrewP我已经用代码示例更新了我的答案,希望能澄清。现在,如果在倒计时期间更新countDiv
,则不会发生任何情况,但当count
达到零时,新的倒计时将从更新的countDiv
值开始。您还可以通过使用count>=countDiv
检测何时将计数设置为0来解决此问题。倒计时更优越,零检测更简单。您还希望CountDiv上的转换是时钟同步的,否则您不知道会得到什么<代码>计数
将在合成中优化到9位。计数只能达到4.088秒。感谢您的反馈。我有点理解你说的话,但不完全理解。你有没有办法给我提供更多的代码来说明要修改什么而不是如何修改?@DrewP我已经用代码示例更新了我的答案,希望能澄清。现在,如果在倒计时期间更新countDiv
,则不会发生任何情况,但当count
达到零时,新的倒计时将从更新的countDiv
值开始。您还可以通过使用count>=countDiv
检测何时将计数设置为0来解决此问题。倒计时更优越,零检测更简单。您还希望CountDiv上的转换是时钟同步的,否则您不知道会得到什么<代码>计数
将在合成中优化到9位。计数只能达到4.088秒。过程按钮选择
不符合合成条件-模拟行为与合成不匹配。在电路板上,btn_计数器
将充当选通振荡器btn_计数器
锁存器,两个按钮启用,提供至少一位反向反馈的算术运算。以及由组合延迟控制的单个比特的振荡率。这似乎与您很少观察到的行为描述一致。解决这一问题的历史方法是为每个按钮按下产生一个时钟长的事件,并使btn_计数器
时钟边缘驱动,将一个时钟事件作为启用(使用250 Hz时钟的基于计数器的去抖动器可以修改为产生一个时钟长的事件)流程buttonChoose
合成不合格-模拟行为与合成不匹配。在电路板上,btn_计数器
将充当选通振荡器btn_计数器
锁存器,两个按钮启用,提供至少一位反向反馈的算术运算。以及由组合延迟控制的单个比特的振荡率。这似乎与您很少观察到的行为描述一致。解决这一问题的历史方法是为每个按钮按下产生一个时钟长的事件,并使btn_计数器
时钟边缘驱动,将一个时钟事件作为启用(使用250 Hz时钟的基于计数器的去抖动器可以修改为产生一个时钟长的事件)
wheelDivider : process(clk, reset)
begin
if(reset = '1') then --reset clock count if reset pushed
count <= b"00000000000001001011";
temp <= '0';
elsif(rising_edge(clk)) then
if(count = x"00000") then --set clk counter value to zero
count <= countDiv;
temp <= not temp;
else
count <= count - 1; --keep decrementing count until zero
temp <= temp;
end if;
end if;
end process;