原创 FPGA-Verilog学习(二)控制PS2数字小键盘并在数码管显示相应的数字

2009-4-5 00:18 7145 8 12 分类: FPGA/CPLD

https://static.assets-stash.eet-china.com/album/old-resources/2009/4/5/a5ba0864-47f7-40b2-90d4-4a5e2758f20e.rar//控制PS2数字小键盘并在数码管显示相应的数字


/*先后调试了LED,按键,数码管的verilog程序,并在实验板上面调试成功!学习FPGA是一个漫长的过程,但是我必须得坚持!前途光明,道路崎岖!


这次在垃圾堆(我工作台下面的抽屉和柜子,呵呵)里面搜索了一个以前用C8051F020作的一个单片机 最小系统,其中有一个PS2的数字小键盘,于是马上鼓捣了一下,复习了一下PS2传输数据的规则,其实还是比较简单的,所以很快就把程序搞定,并在电路板上运行正常!!!


注:程序参考了FPGA小组ilove314 的学习程序,再次表示感谢


*/


module ps2scan(clk,ps2k_clk,ps2k_data,ps2_state,led_cs,led_db);


input clk,ps2k_clk,ps2k_data;
output ps2_state;//键盘状态,1时表示有按键按下


output  led_cs;//数码管选择
output [7:0] led_db;  //数码管显示数据
wire [7:0] led_db;        //7段数码管寄存器


reg ps2k_clk_r0,ps2k_clk_r1,ps2k_clk_r2;//ps2_clk时钟信号的寄存器


assign led_cs=1'b1;  //led_cs为1时,数码管1选通
//------------------------------------------
wire neg_ps2k_clk;//ps2k_clk下降沿标志位


initial begin
 ps2k_clk_r0 = 1'b0;         //初始化,因为实验版复位键坏,所以直接初始化赋值
 ps2k_clk_r1 = 1'b0;
 ps2k_clk_r2 = 1'b0;
 end
always @ (posedge clk )
  
begin        //锁存状态,进行滤波
   ps2k_clk_r0 <= ps2k_clk;
   ps2k_clk_r1 <= ps2k_clk_r0;
   ps2k_clk_r2 <= ps2k_clk_r1;
end


assign neg_ps2k_clk = ~ps2k_clk_r1 & ps2k_clk_r2; //下降沿


//------------------------------------------
reg[7:0] ps2_byte_r;  //PC接收来自PS2的一个字节数据存储器
reg[7:0] temp_data;   //当前接收数据寄存器


reg[3:0] num;    //计数寄存器


initial begin temp_data=8'h00;num = 4'd0;end



always @ (posedge clk ) begin


  if(neg_ps2k_clk) begin //检测到ps2k_clk的下降沿
   case (num)
    4'd0: num <= num+1'b1;                            //接受PS2 key的数据,一共八位
    4'd1: begin
       num <= num+1'b1;
       temp_data[0] <= ps2k_data; //bit0
      end
    4'd2: begin
       num <= num+1'b1;
       temp_data[1] <= ps2k_data; //bit1
      end
    4'd3: begin
       num <= num+1'b1;
       temp_data[2] <= ps2k_data; //bit2
      end
    4'd4: begin
       num <= num+1'b1;
       temp_data[3] <= ps2k_data; //bit3
      end
    4'd5: begin
       num <= num+1'b1;
       temp_data[4] <= ps2k_data; //bit4
      end
    4'd6: begin
       num <= num+1'b1;
       temp_data[5] <= ps2k_data; //bit5
      end
    4'd7: begin
       num <= num+1'b1;
       temp_data[6] <= ps2k_data; //bit6
      end
    4'd8: begin
       num <= num+1'b1;
       temp_data[7] <= ps2k_data; //bit7
      end
    4'd9: begin
       num <= num+1'b1; //奇偶校验位,不做处理
      end
    4'd10: begin
       num <= 4'd0; // num清零
      end
    default: ;
    endcase
  end 
end



//------------------------------------------
reg key_f0;  //松键标志位,置1表示接收到数据8'hf0,再接收到下一个数据后清零
reg ps2_state_r; //键盘当前状态,ps2_state_r=1表示有键被按下


initial begin key_f0 = 1'b0;ps2_state_r = 1'b1;end   //初始化


always @ (posedge clk)  //接收数据的相应处理,这里只对1byte的键值进行处理
begin
 if(num==4'd10) begin //刚传送完一个字节数据
   if(temp_data== 8'hf0) key_f0 <= 1'b1;
   else
    begin
     if(!key_f0)
     begin //说明有键按下
      ps2_state_r <= 1'b0;
      ps2_byte_r<= temp_data; //锁存当前键值
     end
     else
     begin
      ps2_state_r <= 1'b1;   
      key_f0 <= 1'b0;
     end
    end
  end
end


//------------------------------------------


parameter   seg0    = 8'hc0,//数码管显示值
            seg1    = 8'hf9,
            seg2    = 8'ha4,
            seg3    = 8'hb0,
            seg4    = 8'h99,
            seg5    = 8'h92,
            seg6    = 8'h82,
            seg7    = 8'hf8,
            seg8    = 8'h80,
            seg9    = 8'h90;


reg [7:0] led_dbr;//led数据寄存器


always @(ps2_byte_r)   //根据不同的键码在数码管输出相应的数字,0~9
begin
 case (ps2_byte_r)
 8'h70: led_dbr<=seg0;
   8'h69: led_dbr<=seg1;
 8'h72: led_dbr<=seg2;   
 8'h7A: led_dbr<=seg3;     
 8'h6B: led_dbr<=seg4;      
 8'h73: led_dbr<=seg5;     
 8'h74: led_dbr<=seg6;      
 8'h6C: led_dbr<=seg7;        
 8'h75: led_dbr<=seg8;     
 8'h7D: led_dbr<=seg9;   
 default:led_dbr<=0'hff;
 endcase
end
/* 
//数字小键盘的键码 
 8'h70         //0
 8'h69         //1
 8'h72         //2
 8'h7A         //3
 8'h6B         //4
 8'h73         //5
 8'h74         //6
 8'h6C         //7
 8'h75         //8
 8'h7D         //9
 8'h71         //小数点
 8'h5A         //回车
 8'h79         //加
 8'h7B         //减
 8'h7C         //乘
 8'h4A         //除
 8'h77       //numlock键
 8'h66       //删除键
 
*/ 
assign led_db=led_dbr;



endmodule

PARTNER CONTENT

文章评论4条评论)

登录后参与讨论

用户153707 2009-12-7 16:37

学习学习

用户198286 2009-5-30 00:28

always @ (posedge clk) //接收数据的相应处理,这里只对1byte的键值进行处理 begin if(num==4'd10) begin //刚传送完一个字节数据 if(temp_data== 8'hf0) key_f0 <= 1'b1; else begin if(!key_f0) begin //说明有键按下 ps2_state_r <= 1'b0; ps2_byte_r<= temp_data; //锁存当前键值 end else begin ps2_state_r <= 1'b1; key_f0 <= 1'b0; end end end end 这段理解很费力,希望楼主能标注。

用户1615591 2009-4-6 21:44

学习了,呵呵

tengjingshu_112148725 2009-4-5 10:31

学习啦
相关推荐阅读
用户54562 2016-03-22 15:05
FPGA实现冒泡排序法(VHDL)
可能很多人会问,为什么用FPGA来实现冒泡排序?放CPU中用C语言只需短短几行代码即可实现的事情为啥用逻辑来实现,没办法我加入这个项目的时候系统方案已确定下来了。 通过一个小采集板实现一个窄脉...
用户54562 2010-09-09 13:20
32个最热CPLD-FPGA论坛(转)CPLD-FPGA论坛
1. OPENCORES.ORG 这里提供非常多,非常好的PLD了内核,8051内核就可以在里面找到。进入后,选择project或者由http//www.opencores.org/browse.cg...
用户54562 2010-04-21 18:49
电子工程师笔试题目收集1
一.Verilog如何消除毛刺?1.出现"毛刺"的原因  当信号在FPGA器件内部通过连线和逻辑门时,一般都有一定的延时。延时的大小与连线的长短和门单元的数目有关,同时还受器件的制造工艺、工作电压、温...
用户54562 2010-04-12 13:27
有关FPGA中.mif文件
在FPGA设计中ROM的应用时比较常见的,在调用ROM时经常要加载mif文件,对于初学者,无论mif还是hex都是很令人疑惑的东西,这里就对mif文件的格式及其创建做一点简单的说明。mif在fpga设...
用户54562 2010-03-24 15:38
Nios II系统外扩FLASH
这几天一直在调试外部存储器,也积累了一些经验和教训,养成良好的习惯,将这些记录下来。我用的FLASH是AM29LV160DB-90EC,主要管教功能:A:地址线DQ:数据线DQ15/A-1:如果是字(...
用户54562 2010-03-24 15:38
Nios II系统外扩FLASH
这几天一直在调试外部存储器,也积累了一些经验和教训,养成良好的习惯,将这些记录下来。我用的FLASH是AM29LV160DB-90EC,主要管教功能:A:地址线DQ:数据线DQ15/A-1:如果是字(...
EE直播间
更多
我要评论
4
8
关闭 站长推荐上一条 /3 下一条