采用EP2C5T144C8 FPGA实现PS/2接口的设计方法

网友投稿 237 2022-11-02

采用EP2C5T144C8 FPGA实现PS/2接口的设计方法

引言

PS/2接口和协议

接口的物理特性

接口协议原理

如果主机要发送数据,就必须控制鼠标产生时钟信号,方法如下:主机首先下拉时钟线至少100μS抑制通信,然后再下拉数据线,最后释放时钟线。鼠标检测到这个时序状态后,会在10mS内产生时钟信号。如图3中(A)时序段。主机和鼠标之间,传输数据帧的时序如图2、图3所示。

PS/2鼠标的工作模式和协议数据包格式

PS/2鼠标的四种工作模式

数据包结构

PS/2鼠标在工作过程中,会及时把它的状态数据发送给主机。发送的数据包格式如表1所示。

Byte1中的Bit0、Bit1、Bit2分别表示左、右、中键的状态,状态值0表示释放,1表示按下;Byte2和Byte3分别表示X轴和Y轴方向的移动计量值,是二进制补码值;Byte4的低四位表示滚轮的移动计量值,也是二进制补码值,高四位作为扩展符号位。这种数据包由带滚轮的三键三维鼠标产生,若是不带滚轮的三键鼠标,产生的数据包没有Byte4,其余的相同。

VGA信号时序

设计实现

实现功能

1、 用FPGA实现PS/2鼠标接口。

2、鼠标左键按下时十字形鼠标图象的中间方块改变颜色,右键按下时箭头改变颜色。

3、 Reset按键:总复位。

设计原理

主机复位后,首先向鼠标发送初始化命令(0xf4)。当鼠标收到命令字后会给出一个应答字节(0xfa),主机根据应答字节来判断鼠标是否正确应答。如果应答正确则接收鼠标数据包,然后从接收到的数据包中获得鼠标位置及状态数据,并输出给显示模块。显示模块在CRT上显示出当前鼠标的状态和位置,否则,停止处理。如图5。

PS/2程序源码

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

m2_state 《= m2_reset;

elsif (clk‘event and clk=’1‘) then

m2_state 《= m2_next_state;

end if;

end procESS;

--m2 状态传输逻辑

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 =》

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”模式,并等待鼠标正确应答 [page]

when m2_hold_clk_l =》

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;

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;

结束语

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

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:云原生之 Ansible 篇(二)
下一篇:开箱——Amazon Lightsail(远程云桌面)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~