完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
写了一个小程序,仿真可以通过但烧到板子上运行不正常,看了一下编译过程发现CW和NCW两个信号产生了LATCH,请问有知道是为什么的吗?如何解决呢?
代码如下: --***************************************************** -- Filename : -- Author : -- Description : -- Callde by : -- Revision : R1.0 -- Date : --***************************************************** library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all ; use IEEE.std_logic_unsigned.all ; entity encoder is port ( --------------ROTARY INPUT -------------- PI_A : in std_logic; PI_B : in std_logic; RESET : in std_logic; CLK : in std_logic; --------------SWITCH CONTROL-------------- PO_CW : out std_logic :='0'; --CW FOR CLOCKWISE; PO_NCW : out std_logic :='0' --nCW FOR ANTICLOCKWISE; ); end encoder; architecture behav of encoder is --------------SIGNAL DEFINE-------------- type state_type is (s00,s01,s10,s11); signal PR_STATE, NT_STATE :state_type; signal CW,NCW :std_logic; signal CLK_CNT1 : std_logic_vector(15 downto 0) :="0000000000000001"; signal CLK_CNT2 : std_logic_vector(15 downto 0) :="0000000000000001"; begin process(CLK,RESET) begin if(RESET = '1') then PR_STATE <= s00; else if(CLK'event and CLK='1') then PR_STATE <= NT_STATE; end if; end if; end process; process(PI_A,PI_B,PR_STATE) begin case PR_STATE is when s00 => if(PI_A='1' and PI_B='0') then NT_STATE <= s10; CW <='1'; elsif(PI_A='0' and PI_B='1') then NT_STATE <= s01; NCW <= '1'; else NT_STATE <= s00; CW <= '0'; NCW <= '0'; end if; when s10 => if(PI_A='0' and PI_B='0') then NT_STATE <= s00; NCW <='1'; elsif(PI_A='1' and PI_B='1') then NT_STATE <= s11; CW <= '1'; else NT_STATE <= s10; CW <= '0'; NCW <= '0'; end if; when s11 => if(PI_A='1' and PI_B='0') then NT_STATE <= s10; NCW <='1'; elsif(PI_A='0' and PI_B='1') then NT_STATE <= s01; CW <= '1'; else NT_STATE <= s11; CW <= '0'; NCW <= '0'; end if; when s01 => if(PI_A='0' and PI_B='0') then NT_STATE <= s00; CW <='1'; elsif(PI_A='1' and PI_B='1') then NT_STATE <= s11; NCW <= '1'; else NT_STATE <= s01; CW <= '0'; NCW <= '0'; end if; end case; end process; process(CLK,CW,NCW) begin if (CLK'event and CLK ='1') then if (CLK_CNT1 = "1111111111111111") then CLK_CNT1 <= (others => '0'); PO_CW <= '0'; else CLK_CNT1 <= CLK_CNT1+1; end if; end if; if ( CW = '1') then CLK_CNT1 <= "0000000000000000"; PO_CW <= '1'; end if; if (CLK'event and CLK ='1') then if (CLK_CNT2 = "1111111111111111") then CLK_CNT2 <= (others => '0'); PO_NCW <= '0'; else CLK_CNT2 <= CLK_CNT2+1; end if; end if; if (NCW = '1') then CLK_CNT2 <= "0000000000000000"; PO_NCW <= '1'; end if; end process; end behav; |
|
相关推荐
7个回答
|
|
|
|
你的最后一个进程里if(cw=1)和if(ncw=1)两个if没有在时钟里,我感觉这个进程可以更改。还有你应该对你的功能稍微描述下,没有太搞懂你的基本功能。
|
|
|
|
将你的case语句中cw和ncw的语句补全。
-- LATCH.vhd library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all ; use IEEE.std_logic_unsigned.all ; entity encoder is port ( --------------ROTARY INPUT -------------- PI_A : in std_logic; PI_B : in std_logic; RESET : in std_logic; CLK : in std_logic; --------------SWITCH CONTROL-------------- PO_CW : out std_logic :='0'; --CW FOR CLOCKWISE; PO_NCW : out std_logic :='0' --nCW FOR ANTICLOCKWISE; ); end encoder; architecture behav of encoder is --------------SIGNAL DEFINE-------------- type state_type is (s00,s01,s10,s11); signal PR_STATE, NT_STATE :state_type; signal CW,NCW :std_logic; signal CLK_CNT1 : std_logic_vector(15 downto 0) :="0000000000000001"; signal CLK_CNT2 : std_logic_vector(15 downto 0) :="0000000000000001"; begin process(CLK,RESET) begin if(RESET = '1') then PR_STATE <= s00; else if(CLK'event and CLK='1') then PR_STATE <= NT_STATE; end if; end if; end process; process(PI_A,PI_B,PR_STATE) begin case PR_STATE is when s00 => if(PI_A='1' and PI_B='0') then NT_STATE <= s10; CW <='1'; ncw<='0'; elsif(PI_A='0' and PI_B='1') then NT_STATE <= s01; cw<='0'; NCW <= '1'; else NT_STATE <= s00; CW <= '0'; NCW <= '0'; end if; when s10 => if(PI_A='0' and PI_B='0') then NT_STATE <= s00; cw<='0'; NCW <='1'; elsif(PI_A='1' and PI_B='1') then NT_STATE <= s11; CW <= '1'; ncw<='0'; else NT_STATE <= s10; CW <= '0'; NCW <= '0'; end if; when s11 => if(PI_A='1' and PI_B='0') then NT_STATE <= s10; NCW <='1'; cw<='0'; elsif(PI_A='0' and PI_B='1') then NT_STATE <= s01; CW <= '1'; ncw<='0'; else NT_STATE <= s11; CW <= '0'; NCW <= '0'; end if; when s01 => if(PI_A='0' and PI_B='0') then NT_STATE <= s00; CW <='1'; ncw<='0'; elsif(PI_A='1' and PI_B='1') then NT_STATE <= s11; NCW <= '1'; cw<='0'; else NT_STATE <= s01; CW <= '0'; NCW <= '0'; end if; end case; end process; process(CLK,CW,NCW) begin if (CLK'event and CLK ='1') then if (CLK_CNT1 = "1111111111111111") then CLK_CNT1 <= (others => '0'); PO_CW <= '0'; else CLK_CNT1 <= CLK_CNT1+1; end if; end if; if ( CW = '1') then CLK_CNT1 <= "0000000000000000"; PO_CW <= '1'; end if; if (CLK'event and CLK ='1') then if (CLK_CNT2 = "1111111111111111") then CLK_CNT2 <= (others => '0'); PO_NCW <= '0'; else CLK_CNT2 <= CLK_CNT2+1; end if; end if; if (NCW = '1') then CLK_CNT2 <= "0000000000000000"; PO_NCW <= '1'; end if; end process; end behav; 就可以了。 |
|
|
|
学习了很多,谢谢 |
|
|
|
发完帖子就找到了解决办法,在case语句之前分别给cw和ncw赋值为0就可以了,
|
|
|
|
caojianxun 发表于 2015-11-6 14:04 基本功能就是解码光电编码器的输出,来产生正转和反转两个脉冲,问题已经解决,是cw和ncw没有赋初值造成的 |
|
|
|
怎么把这1积分给你? |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
1693 浏览 1 评论
1447 浏览 0 评论
矩阵4x4个按键,如何把识别结果按编号01-16(十进制)显示在两个七段数码管上?
1661 浏览 0 评论
943 浏览 0 评论
2451 浏览 0 评论
1507 浏览 38 评论
5706 浏览 113 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-29 20:04 , Processed in 0.633166 second(s), Total 51, Slave 44 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号