集成电路技术分享

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
查看: 1544|回复: 0

PS/2程序源码

[复制链接]
vvt 发表于 2011-1-28 08:17:10 | 显示全部楼层 |阅读模式
PS/2程序源码

entity mouse is

Port (clk : in std_logic; reset : in std_logic; ps2_clk : inout std_logic; ps2_data : inout std_logic; left_button : out std_logic; right_button : out std_logic; mousex: buffer std_logic_vector(9 downto 0); mousey: buffer std_logic_vector(9 downto 0); data_ready : out std_logic; error_no_ack : out std_logic);

end mouse;

architecture Behavioral of mouse is

--变量、信号定义(略)

begin

ps2_clk <= '0' when ps2_clk_hi_z='0' else 'Z';

ps2_data <= '0' when ps2_data_hi_z='0' else 'Z';

--检测ps2clk上升沿和下降沿(略)

m2statech: process (reset, clk) ------------------m2 状态

begin

if (reset='0') then

m2_state <= m2_reset;

elsif (clk'event and clk='1') then

m2_state <= m2_next_state;

end if;

end process;

--m2 状态传输逻辑

m2statetr: process (m2_state, q, fall,rise,watchdog_timer_done,bitcount,ps2_data,packet_good)

begin

ps2_clk_hi_z <= '1';

ps2_data_hi_z <= '1';

error_no_ack <= '0';

output_strobe <= '0';

case m2_state is

when m2_reset => -- 复位后向鼠标发送命令字

m2_next_state <= m2_hold_clk_l;

when m2_wait =>

if (fall='1') then

m2_next_state <= m2_gather;

else

m2_next_state <= m2_wait;

end if;

when m2_gather =>

if ((watchdog_timer_done='1') and (bitcount=TOTAL_BITS))then

m2_next_state <= m2_verify;

else

m2_next_state <= m2_gather;

end if;

when m2_verify =>

--if (bitcount < TOTAL_BITS) then

--m2_next_state <= m2_wait;

--else

m2_next_state <= m2_use;

--end if;

when m2_use =>

output_strobe <= '1';

m2_next_state <= m2_wait;

-- 用状态机的9个状态实现命令字传输,使鼠标进入"streaming"模式,并等待鼠标正确应答

when m2_hold_clk_l =>

ps2_clk_hi_z <= '0'; -- 启动看门狗!

if (watchdog_timer_done='1') then

m2_next_state <= m2_data_low_1;

else

m2_next_state <= m2_hold_clk_l;

end if;

when m2_data_low_1 =>

ps2_data_hi_z <= '0'; -- 数据位 开始位, d[0] and d[1]

if (fall='1' and (bitcount = 2)) then

m2_next_state <= m2_data_high_1;

else

m2_next_state <= m2_data_low_1;

end if;

when m2_data_high_1 =>

ps2_data_hi_z <= '1'; -- 数据位 d[2]

if (fall='1' and (bitcount = 3)) then

m2_next_state <= m2_data_low_2;

else

m2_next_state <= m2_data_high_1;

end if;

when m2_data_low_2 =>

ps2_data_hi_z <= '0'; -- 数据位 d[3]

if (fall='1' and (bitcount = 4)) then

m2_next_state <= m2_data_high_2;

else

m2_next_state <= m2_data_low_2;

end if;

when m2_data_high_2 =>

ps2_data_hi_z <= '1'; -- 数据位 d[4],d[5],d[6],d[7]

if (fall='1' and (bitcount = 8)) then

m2_next_state <= m2_data_low_3;

else

m2_next_state <= m2_data_high_2;

end if;

when m2_data_low_3 =>

ps2_data_hi_z <= '0'; -- 奇偶校验位

if (fall='1') then

m2_next_state <= m2_data_high_3;

else

m2_next_state <= m2_data_low_3;

end if;

when m2_data_high_3 =>

ps2_data_hi_z <= '1'; -- 允许鼠标拉成低电平(ACK脉冲)

if (fall='1' and (ps2_data='1')) then

m2_next_state <= m2_error_no_ack;

elsif (fall='1' and (ps2_data='0')) then

m2_next_state <= m2_await_response;

else

m2_next_state <= m2_data_high_3;

end if;

when m2_error_no_ack =>

error_no_ack <= '1';

m2_next_state <= m2_error_no_ack;


-- 为了鼠标正确进入"streaming"模式,状态极必须等待足够长的时间,确保鼠标正确应答0xFA。


when m2_await_response =>

--if (bitcount = 22) then

m2_next_state <= m2_verify;

--else

-- m2_next_state <= m2_await_response;

--end if;

when others => m2_next_state <= m2_wait;

end case;

end process;-----------------------------m2 状态结束

-- 位计数器 (略)

-- 数据移位寄存器(略)

-- 看门狗时间计数器(略)

watchdog_timer_done <= '1' when (watchdog_timer_count=WATCHDOG-1) else '0';

packet_good <= '1'; -- 接收数据包有效标志

outdata: process (reset, clk) -- 输出数据

begin

if (reset='0') then

left_button <= '0';

right_button <= '0';

elsif (clk'event and clk='1') then

if (output_strobe='1') then

left_button <= q(1);

right_button <= q(2);

mouseyy <= not (q(6) & q(6) & q(30 downto 23)) + "1";

end if;

end if;

end process;

cordinatex: process (reset, clk)

begin

if (reset='0') then

mousex <= "0110010000"; -- 400

elsif (clk'event and clk='1') then

if (output_strobe='1') then

if ((mousex >= 797 and q(5)='0') or (mousex <= 2 and

q(5)='1')) then

mousex <= mousex;

else

mousex <= mousex + (q(5) & q(5) & q(19 downto

12));--q(5):xsign q(6):ysign

end if;

end if;

end if;

end process;

cordinatey: process (reset, clk)

begin

if (reset='0') then

mousey <= "0100101100"; -- 300

elsif (clk'event and clk='1') then

if (output_strobe='1') then

if ((mousey >= 597 and q(6)='1') or (mousey <= 2

and q(6)='0')) then

mousey <= mousey;

else

m ousey <= mousey + mouseyy; --(q(6) & q(6) & q(30

downto 23));

end if;

end if;

end if;

end process;

data_ready <= output_strobe;

end Behavioral;


结束语

  该设计采用了清华大学THCII-1创新SoPC实验套件进行综合、仿真和下载,测试得到了满意的效果,完整地实现了对PS/2和VGA的时序驱动。


  该设计可以被应用到各种需要鼠标操作、以VGA作为显示的嵌入式系统中,从而大大提高人机交互能力,降低了开发成本,提高了开发效率,使系统的稳定性也得到了可靠的保障。
您需要登录后才可以回帖 登录 | 我要注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

QQ|小黑屋|手机版|Archiver|fpga论坛|fpga设计论坛 ( 京ICP备20003123号-1 )

GMT+8, 2024-12-29 00:09 , Processed in 0.057143 second(s), 20 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表