我正在为 FPGA 编写 LCD 控制器,但遇到了一个非常奇怪的问题(至少对我而言)。应该将所需位输出到屏幕的状态机行为不端,并使输出引脚“卡”在旧状态,而它显然已经转移到后来的状态。
下面是状态机的相关部分:
PROCESS (clk)
VARIABLE count: INTEGER RANGE 0 TO clk_divider; -- clk_divider is a generic positive.
BEGIN
IF (clk'EVENT AND clk = '1') THEN
count := count + 1;
IF (count = clk_divider) THEN
EAUX <= NOT EAUX;
count := 0;
END IF;
END IF;
END PROCESS;
……
PROCESS (EAUX)
BEGIN
IF (EAUX'EVENT AND EAUX = '1') THEN
pr_state <= nx_state;
END IF;
END PROCESS;
……
PROCESS (pr_state)
BEGIN
CASE pr_state IS
WHEN EntryMode => --6=1,7=Cursor increment/decrement, 8=Display shift on/off
RSs <='0';
DB(7 DOWNTO 0) := "00000110";
nx_state <= WriteData;
WHEN WriteData => --Write data to LCD:
RSs <='1';
YLED <= '1';
DB(7 DOWNTO 0) := "01011111";
i := i + 1;
IF (i < chars) THEN
nx_state <= WriteData;
ELSE
i := 0;
nx_state <= ReturnHome;
END IF;
WHEN ReturnHome => --Return cursor
RSs <='0';
YLED <= '1';
DB(7 DOWNTO 0) := "01011111";
nx_state <= WriteData;
END CASE;
END PROCESS;
其中变量 DB 中的位分配给信号 DBOUT:
DBOUT : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) -- In entity
SHARED VARIABLE DB : STD_LOGIC_VECTOR(7 DOWNTO 0) := "00000000"; -- In Architecture
DBOUT <= DB;
DBOUT 输出(在 .ucf 文件中)为:
NET "DBOUT(0)" LOC = P10;
NET "DBOUT(1)" LOC = P11;
NET "DBOUT(2)" LOC = P12;
NET "DBOUT(3)" LOC = P13;
NET "DBOUT(4)" LOC = P15;
NET "DBOUT(5)" LOC = P16;
NET "DBOUT(6)" LOC = P18;
NET "DBOUT(7)" LOC = P19;
在引脚上使用示波器,我可以看到它明显卡在输出“EntryMode”位并且“RSs”设置为低,而 YLED(FPGA 上的内部 LED)打开(它在所有其他状态下都关闭)。真正奇怪的是(这需要很长时间才能找到)如果我将 EntryMode 位从
"00000110"
至
"00000100"
它成功通过状态并输出正确的位。其他更改也可能如此,但我真的不想进行太多测试。任何帮助或提示将不胜感激!
更新:在受欢迎的请求之后,我在所有早期状态中明确地将 YLED 设置为低电平,并切换(返回)DB 作为信号。结果是我根本无法达到后面的状态,或者至少停留在它们中(即使在摆弄魔法位时,我认为这是一件好事),因为 YLED 在启动后只停留一瞬间FPGA。