搜索
bottom↓
回复: 1

有关ps2鼠标的问题,谁能帮解决啊,非常感谢~

[复制链接]

出0入0汤圆

发表于 2011-5-29 12:11:01 | 显示全部楼层 |阅读模式
我想用做一个模拟的ps2鼠标控制芯片。
给控制芯片输入X,Y位移量,控制芯片的串行(data,clk)输出连到电脑的ps2接口上,希望计算机的显示器上鼠标的位置能按照我给出的X,Y位移量移动。我按照在这个网站上找到的一份ps2协议,用VHDL写了一份代码。结果是连到电脑ps2接口后,主机箱开始一直滴滴的响,鼠标的位置一点改变也没有。
代码如下
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use IEEE.STD_LOGIC_ARITH.ALL;

entity mouse3 is
        port
        (distance_x,distance_y : in std_logic_vector(9 downto 4);--补码表示
        rb,mb,lb :in std_logic;                                                                --right button,middle,left button
        clk_mouse :in std_logic;                                                        --mouse clk,1us,1Mhz
        clk_ps2,data:inout std_logic;
        power:in std_logic;                                                                        --应该就用ps/2的那个就行
        send:in std_logic);                                                                        --在变化的上升沿 发送三个字结
end mouse3;

architecture behaves of mouse3 is
        signal reg1:std_logic:='0';                        --power
        signal reg2:std_logic:='0';                        --send

        signal trig1:bit;
        signal reg_trig1:bit;
        signal trig2:bit;
        signal reg_trig2:bit;
        signal trig3:bit;
        signal reg_trig3:bit;
        signal clk:bit;                                                                                --与分频有关
        signal reg_fromto:std_logic_vector( 9 downto 0);
        signal reg_send: std_logic_vector(10 downto 0);
        signal reg_recieve:std_logic_vector(7 downto 0);
        signal recieve_bit_over:std_logic;
        signal send_bit_over:std_logic;
        signal response_bit_over:std_logic;
        type fromto_type is(state_fromto_a,state_fromto_b,state_fromto_c,state_fromto_d);
        signal reg3:fromto_type:=state_fromto_a;                        --        fromto
        signal fromto_now:fromto_type:=state_fromto_a;
        signal fromto_next:fromto_type;
       
        type substate_type is(idle,sendbit_a,sendbit_b,sendbit_c,sendbit_d,sendbit_begin,sendbit_end,
                                        recievebit_a,recievebit_b,recievebit_c,recievebit_begin,recievebit_end,
                                        responsebit_a,responsebit_b,responsebit_c,responsebit_d);
        signal substate_now:substate_type:=idle;
        signal substate_next:substate_type;
       
        type state_type is(power_begin,power_a1,power_a2,power_b1,power_b2,power_c1,power_c2,
                                                power_d1,power_d2,power_stream,stream_a1,stream_a2,
                                                stream_a3,stream_b1,stream_b2,stream_b3,stream_c1,stream_c2,
                                                stream_d1,stream_d2,stream_d3,stream_d4);                                         
       
        signal state_now:state_type:=power_stream;
        signal state_next:state_type;
       
        begin
       
        process(clk_mouse)                                                                        --这就算个分频吧
        begin
        if clk_mouse'event and clk_mouse='0' then clk<=not clk;         
        end if;
        end process;
       
        process(clk_mouse)
        begin
        if clk_mouse'event and clk_mouse='1' then
                if clk='1' then
                if (reg1/=power and power='1') then
                trig1<=not trig1;
                elsif reg2/=send and send='1'then
                trig2<=not trig2;
                elsif reg3/=fromto_now and fromto_now=state_fromto_d then
                trig3<=not trig3;
                end if;
                elsif clk='0' then
                reg1<=power;
                reg2<=send;
                reg3<=fromto_now;
               
                end if;
        end if;
        end process;
               
        process(clk_mouse)                                                                        --这个过程应该在15ms以外,不做检查,由计算机保证
                variable n:integer range 0 to 10;                               
               
                begin
                if clk_mouse'event and clk_mouse='1' then
                if clk='1' then
                        n:=n+1;reg_fromto(n)<=clk_ps2;
                        fromto_now<=fromto_next;
                case fromto_now is       
                        when state_fromto_a=>
                       
                        if reg_fromto="0000000000" then fromto_next<=state_fromto_b;                       
                        end if;
               
                        when state_fromto_b=>
                                if data='0' then fromto_next<=state_fromto_c;
                                elsif clk_ps2='1' then fromto_next<=state_fromto_a;
                                end if;
                        when state_fromto_c=>
                                if data='1' and clk_ps2='1' then fromto_next<=state_fromto_d;
                                end if;                
                        when state_fromto_d=>
                                if recieve_bit_over='1' then fromto_next<=state_fromto_a;                  --state_fromto_a表示又空闲了;
                                end if;
                       
                        end case;
                end if;
                end if;
        end process;
       
        --上个进程还可以用wait语句做触发,但是不如这个好(毛刺)
       
        process(clk_mouse)
                variable n:integer;       
                variable i:integer;
                begin                                                                                        --计数器80下的 --什么时候倒入到这个进程的敏感表
                if clk_mouse'event and clk_mouse='1'  then
                if clk='0' then       
                        if state_next/=state_now then
                                if state_next=power_a2 or state_next=power_b2 or state_next=power_d2 or state_next=stream_a2
                                        or state_next=stream_b2 or state_next=stream_c2 or state_next=stream_d3 then substate_next<=sendbit_begin;n:=0;                        --这里还要添加状态
                                elsif state_next=power_c2 or state_next=stream_d1 then substate_next<=recievebit_begin;n:=0;
                                end if;
                        end if;
                elsif clk='1' then
                        substate_now<=substate_next;
                        if n=40 then n:=0;
                        else n:=n+1;
                        end if;       
                                       
                       
                                        case substate_now is
                                        when sendbit_begin=>
                                                if n=10 then i:=0;send_bit_over<='0';
                                                elsif n=20 then substate_next<=sendbit_a;
                                                end if;
                                        when sendbit_a=>
                                                if n=2 then data<=reg_send(i);substate_next<= sendbit_b;
                                                end if;
                                        when sendbit_b =>
                                                if n=20 then clk_ps2<='0';substate_next<=sendbit_c;
                                                end if;
                                        when sendbit_c=>
                                                if n=40 then clk_ps2<='Z';substate_next<=sendbit_d;
                                                end if;
                                        when sendbit_d =>
                                                if n=10 then i:=i+1;
                                                elsif n=20 then
                                                        if i<=9 then substate_next<=sendbit_a;
                                                        elsif i=10 then substate_next<=sendbit_end;
                                                        end if;
                                                end if;
                                        when sendbit_end=>
                                                if n=30 then substate_next<=idle;send_bit_over<='1';       
                                                end if;
                                       
                                        when recievebit_begin=>
                                                if n=2 then i:=0;substate_next<=recievebit_a;recieve_bit_over<='0';
                                                end if;
                                        when recievebit_a=>
                                                if n=20 then clk_ps2<='0';substate_next<=recievebit_b;
                                                end if;
                                        when recievebit_b=>
                                                if n=40 then clk_ps2<='Z';
                                                       
                                                substate_next<=recievebit_c;
                                                end if;
                                        when recievebit_c=>
                                                if n=20 then
                                                        if i<=7 then reg_recieve(i)<=data;
                                                        end if;
                                                        if i<=8 then substate_next<=recievebit_a;
                                                        elsif i=9 then substate_next<=responsebit_a;
                                                        end if;
                                                        i:=i+1;
                                                end if;
                                        when responsebit_a=>
                                                if n=15 then
                                                        data<='0';
                                                        substate_next<=responsebit_b;
                                                end if;
                                        when responsebit_b=>
                                                if n=5 then
                                                        clk_ps2<='0';
                                                        substate_next<=responsebit_c;
                                                end if;
                                        when responsebit_c=>
                                                if n=40 then
                                                        clk_ps2<='Z';
                                                        substate_next<=responsebit_d;
                                                end if;
                                        when responsebit_d=>
                                                if n=5 then
                                                        data<='Z';       
                                                        substate_next<=recievebit_end;
                                                end if;
                                        when recievebit_end=>
                                                if n=2        then                                         --这里本来少个延迟45ms的条件
                                                substate_next<=idle;recieve_bit_over<='1';
                                                end if;
                                        when others=>
                                                null;
                                        end case;
                end if;                       
                end if;

        end process;
               
        process(clk_mouse)                        --进程敏感表
                variable m : integer range 0 to 500001;
                variable parity : std_logic;
                variable j : integer;
        begin
                --if power'event and power='1' then state_next<=power_begin;
                --end if;
                --if send'event and send='1' then state_next<=stream_a1;
                --end if;
                --if fromto_now'event and fromto_now=state_fromto_d then state_next<=stream_d1;                --不知道状态变量改变能否用event
                --end if;
                if clk_mouse'event and clk_mouse='1'  then                --这就是说substate的变化一定能在半个时钟周期内变化
                        if clk='0' then
                                if state_now/=state_next then m:=0;
                                end if;
                                if reg_trig1/=trig1 then state_next<=power_begin;
                                elsif reg_trig2/=trig2 then state_next<=stream_a1;       
                                elsif reg_trig3/=trig3 then state_next<=stream_d1;
                                end if;
                       
                       
                        elsif  clk='1' then                 --开机为sleep?
                        reg_trig1<=trig1;
                        reg_trig2<=trig2;
                        reg_trig3<=trig3;
                        m:=m+1;
                       
                        state_now<=state_next;
                        case state_now is
                        when power_begin=>
                                if m=500000 then state_next<=power_a1;j:=0;
                                end if;
                        when power_a1=>
                                if (j=0 and m=2) or (j>0 and send_bit_over='1' and reg_fromto/="0000000000") then
                                reg_send(8 downto 1)<="10101010";
                                reg_send(0)<='0';
                                parity:='0';
                                for k in 1 to 8 loop         --这个计算是要用时间的吗?可能计算parity应该另外求
                                        parity:= parity xor reg_send(k);
                                end loop;
                                reg_send(9)<=parity;
                                reg_send(10)<='1';
                                state_next<=power_a2;
                                end if;
                        when power_a2=>
                                if m=2 then state_next<=power_b1;
                                end if;
                        when power_b1=>
                                if send_bit_over='1' and reg_fromto/="0000000000" then                 --虽然没有用send_bit_over触发,但是应该也能用
                                reg_send(8 downto 1)<="00000000";
                                reg_send(0)<='0';
                                parity:='0';
                                for k in 1 to 8 loop        
                                        parity:=parity xor reg_send(k);
                                end loop;
                                reg_send(9)<=parity;
                                reg_send(10)<='1';
                                state_next<=power_b2;
                                end if;
                        when power_b2=>
                                if m=2 then state_next<=power_c1;
                                end if;
                        when power_c1=>
                                if send_bit_over='1' and reg_fromto/="0000000000" then state_next<=power_c2;
                                end if;
                        when power_c2=>
                                if m>45000 then
                                if recieve_bit_over='1' then state_next<=power_d1;
                                end if;
                                end if;
                        when power_d1=>
                                if m=2 then
                                reg_send(8 downto 1)<="11111010";
                                reg_send(0)<='0';
                       
                                for k in 1 to 8 loop        
                                        parity:=parity xor reg_send(k);
                                end loop;
                                reg_send(9)<=parity;
                                reg_send(10)<='1';
                                j:=j+1;
                                state_next<=power_d2;
                                end if;
                        when  power_d2=>
                                if m=2 then
                                        if j<=2 then state_next<=power_a1;
                                        elsif j>2 then state_next<=power_stream;
                                        end if;
                                end if;       
                       
                        when stream_a1=>
                                if m=2 then
                                        reg_send(0)<='0';
                                        reg_send(8)<=distance_y(9);
                                        reg_send(7)<=distance_x(9);
                                        reg_send(6)<=distance_y(8);
                                        reg_send(5)<=distance_x(8);
                                        reg_send(4)<='1';
                                        reg_send(3)<=mb;
                                        reg_send(2)<=rb;
                                        reg_send(1)<=lb;
                                        parity:='0';
                                        for k in 1 to 8 loop        
                                                parity:=parity xor reg_send(k);
                                        end loop;
                                        reg_send(9)<=parity;
                                        reg_send(10)<='1';
                                        state_next<=stream_a2;
                                end if;
                        when stream_a2=>
                                if m=2 then state_next<=stream_a3;
                                end if;
                        when stream_a3=>
                                if m=60000 and reg_fromto/="0000000000" then state_next<=stream_b1;
                                end if;       
                        when stream_b1=>       
                                if m=2 then
                                reg_send(0)<='0';
                                reg_send(8 downto 5)<=distance_x(7 downto 4);
                                reg_send(4 downto 1)<="1111";
                                parity:='0';
                                for k in 1 to 8 loop        
                                        parity:=parity xor reg_send(k);
                                end loop;
                                reg_send(9)<=parity;
                                reg_send(10)<='1';
                                state_next<=stream_b2;       
                                end if;
                        when stream_b2=>                                       
                                if m=2 then
                                state_next<=stream_b3;
                                end if;
                        when stream_b3=>
                                if m=60000 and reg_fromto/="0000000000"then
                                state_next<=stream_c1;       
                                end if;                                       
                        when stream_c1=>
                                if m=2 then
                                reg_send(0)<='0';
                                reg_send(8 downto 5)<=distance_y(7 downto 4);
                                reg_send(4 downto 1)<="1111";
                                parity:='0';
                                for k in 1 to 8 loop        
                                        parity:=parity xor reg_send(k);
                                end loop;
                                reg_send(9)<=parity;
                                reg_send(10)<='1';
                                state_next<=stream_c2;
                                end if;
                        when stream_c2=>
                                if m=2 then
                                state_next<=power_stream;
                                end if;
                       
                        when stream_d1=>
                                if m=2 then
                                state_next<=stream_d2;
                                end if;
                        when stream_d2=>
                                if m>45000 then
                                        if recieve_bit_over='1' then
                                        reg_send(0)<='0';
                                        reg_send(8 downto 1)<="11111010";
                                        parity:='0';
                                        for k in 1 to 8 loop        
                                                parity:=parity xor reg_send(k);
                                        end loop;
                                        reg_send(9)<=parity;
                                        reg_send(10)<='1';
                                        state_next<=stream_d3;
                                        end if;
                                end if;
                        when stream_d3=>
                                if m=2 then
                                state_next<=stream_d4;
                                end if;
                        when stream_d4=>
                                if send_bit_over='1' then
                                        if reg_recieve="11101011" then state_next<=stream_a1;
                                        else state_next<=power_stream;
                                        end if;
                                end if;
                        when others=>
                                 null;
                        end case;
                end if;
                end if;
                end process;
        end behaves;       
                               
请谁能帮我改下,非常感谢啊

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2011-5-29 12:26:13 | 显示全部楼层
编译只有两个warning。问题应该是我对ps2协议的理解不清楚导致的。
一共五个进程,分别用来表示
1。分频
2。检测外部鼠标连上电源,检测发送字节使能(我来操控的),检测主机发送信号命令;
3。检测主机的抑制发送情况;
4。发送或者接受一个字节;
5。接受主机的命令后返回FA,并判断并发送发送三个字节的数据包;
开机启动信号发送和接受AA,00;(我把采样率等都省略了,主机发送的信息除了EB时会返回FA和三个数据包,其他的都只返回FA,目的是简化过程,只要显示器上有显示光标的移动)
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 13:31

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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