PS2键盘 + LCD12864 实验

本实验是通过LCD12864来显示键盘上被按下的按键,实验比较简单,在LCD12864固定的DDRAM地址上显示,缺点就是不能保存上一次被按的内容,后者会覆盖掉前面,所以屏上仅有一个字符显示。保存上一次内容不被覆盖掉方法还待改进。目前将就这样吧。

关于LCD12864显示可以参考“LCD12864 液晶显示-汉字及自定义显示(并口)”,代码稍微改了一下,可以参考代码。

PS2键盘解码实验也比较简单,可以参考特权的或是“verilog HDL的那些事儿”也可以在网上找到相关的资料。

ps2_control.v

  1 module ps2_control(
  2                     //input 
  3                     sys_clk,
  4                     rst_n,
  5                     key_clk,
  6                     key_data,
  7                     
  8                     //output
  9                     data_buf,
 10                    );
 11 input sys_clk;    //50Mhz
 12 input rst_n;
 13 input key_clk;      //键盘时钟
 14 input key_data;   //键盘数据
 15 
 16 output [7:0] data_buf;    //保存要显示的数据
 17 
 18 //***********************************************
 19 //检测key_clk的下降沿
 20 //***********************************************
 21 reg key_clk_1;
 22 reg key_clk_2;
 23 always @(posedge sys_clk or negedge rst_n)
 24 if(!rst_n) begin
 25    key_clk_1 <= 1'b1;
 26    key_clk_2 <= 1'b1;
 27 end
 28 else begin
 29     key_clk_1 <= key_clk;
 30     key_clk_2 <= key_clk_1;
 31 end
 32 
 33 wire key_clk_n;
 34 assign key_clk_n = key_clk_2 & (~key_clk_1);
 35 //***********************************************
 36 //对key_data上的数据进行保存
 37 //***********************************************
 38 reg [3:0] i;
 39 reg [7:0] data_temp;
 40 always @(posedge sys_clk or negedge rst_n)
 41 if(!rst_n) begin
 42     i <= 4'd0;
 43     data_temp <= 8'h00;
 44 end
 45 else if(key_clk_n) begin
 46     case(i)
 47     4'd0: i <= i + 1'b1;  //起始位不处理
 48     
 49     4'd1,4'd2,4'd3,4'd4,4'd5,4'd6,4'd7,4'd8: 
 50     begin
 51         i <= i + 1'b1;
 52         data_temp[i-1] <= key_data;
 53     end
 54 
 55     4'd9: i <= i + 1'b1;  //奇校验位不处理
 56     
 57     4'd10: i <= 4'd0;    //停止位不处理
 58     
 59     default:    ;
 60     endcase
 61 end
 62 
 63 reg key_f0;        //松键标志位,置1表示接收到数据8'hf0,再接收到下一个数据后清零
 64 reg[7:0] ps2_data;
 65 always @(posedge sys_clk or negedge rst_n)    //接收数据的相应处理,这里只对1byte的键值进行处理
 66 if(!rst_n) begin
 67     key_f0 <= 1'b0;
 68     ps2_data <= 8'h00;
 69 end
 70 else if(i==4'd10) //刚传送完一个字节数据
 71 begin    
 72     if(data_temp == 8'hf0)  
 73         key_f0 <= 1'b1;  //说明有键被释放
 74     else if(!key_f0)    //说明有键按下
 75         ps2_data <= data_temp;    //锁存当前键值
 76     else
 77         key_f0 <= 1'b0;
 78 end
 79 
 80 reg [7:0] data_buf;
 81 always @ (ps2_data) begin
 82     case (ps2_data)
 83         8'h15: data_buf = "Q";
 84         8'h1d: data_buf = "W";
 85         8'h24: data_buf = "E";
 86         8'h2d: data_buf = "R";
 87         8'h2c: data_buf = "T";
 88         8'h35: data_buf = "Y";
 89         8'h3c: data_buf = "U";
 90         8'h43: data_buf = "I";
 91         8'h44: data_buf = "O";
 92         8'h4d: data_buf = "P";                      
 93         8'h1c: data_buf = "A";
 94         8'h1b: data_buf = "S";
 95         8'h23: data_buf = "D";
 96         8'h2b: data_buf = "F";
 97         8'h34: data_buf = "G";
 98         8'h33: data_buf = "H";
 99         8'h3b: data_buf = "J";
100         8'h42: data_buf = "K";
101         8'h4b: data_buf = "L";
102         8'h1a: data_buf = "Z";
103         8'h22: data_buf = "X";
104         8'h21: data_buf = "C";
105         8'h2a: data_buf = "V";
106         8'h32: data_buf = "B";
107         8'h31: data_buf = "N";
108         8'h3a: data_buf = "M";
109         default: data_buf = 8'h00;
110     endcase
111 end
112 
113 endmodule
114 
115     
116     
View Code

LCD12864.v

  1 module LCD12864(
  2                     //input 
  3                     sys_clk,
  4                     rst_n,
  5                     data_buf,
  6                     
  7                     //output 
  8                     lcd_rs,
  9                     lcd_rw,
 10                     lcd_en,
 11                     lcd_data,
 12                     lcd_psb
 13                 );
 14 input sys_clk;// 50MHZ
 15 input rst_n;
 16 input [7:0] data_buf;
 17 
 18 output lcd_rs;//H:data    L:command
 19 output lcd_rw;//H:read module    L:write module
 20 output lcd_en;//H active
 21 output [7:0] lcd_data;
 22 output lcd_psb;//H:parallel    module    L:SPI module
 23 
 24 /***************************************************/
 25 parameter T3MS = 18'd149_999;
 26 parameter    IDLE           = 4'd0,
 27             INIT_FUN_SET1 = 4'd1,
 28             INIT_FUN_SET2 = 4'd2,
 29             INIT_DISPLAY  = 4'd3,
 30             INIT_CLEAR       = 4'd4,
 31             INIT_DOT_SET  = 4'd5,
 32             SET_DDRAM      = 4'd6,
 33             WRITE_DATA1      = 4'd7;
 34 /*            INIT_FUN_SET3 = 4'd8,
 35             SET_CGRAM     = 4'd9,
 36             WRITE_DATA2   = 4'd10,
 37             SET_DDRAM2    = 4'd11,
 38             SET_CUSTOM_L  = 4'd12,
 39             SET_CUSTOM_H  = 4'd13,
 40             STOP          = 4'd14;*/
 41 /***************************************************/
 42 //产生周期为6MS的lcd_clk给LCD
 43 reg [17:0] cnt;
 44 reg lcd_clk;
 45 always @(posedge sys_clk or negedge rst_n)
 46 if(!rst_n) begin
 47     cnt <= 18'd0;
 48     lcd_clk <= 1'b0;
 49 end
 50 else if(cnt == T3MS)begin
 51     cnt <= 18'd0;
 52     lcd_clk <= ~lcd_clk;
 53 end
 54 else
 55     cnt <= cnt + 1'b1;
 56 
 57 /***************************************************/
 58 reg lcd_rs;
 59 always @(posedge lcd_clk or negedge rst_n)
 60 if(!rst_n)
 61     lcd_rs <= 1'b0;
 62 else if(state == WRITE_DATA1)
 63     lcd_rs <= 1'b1;        //写数据模式
 64 else
 65     lcd_rs <= 1'b0;        //写命令模式
 66 /***************************************************/
 67 reg [3:0] state;
 68 reg [7:0] lcd_data;
 69 reg [6:0] num;
 70 reg en;
 71 always @(posedge lcd_clk or negedge rst_n)
 72 if(!rst_n) begin
 73     state <= IDLE;
 74     lcd_data <= 8'h00;
 75     en <= 1'b1;
 76     num <= 6'd0;
 77 end    
 78 else 
 79     case(state)
 80         IDLE: 
 81         begin
 82             state <= INIT_FUN_SET1;
 83             lcd_data <= 8'hzz;
 84             en <= 1'b1;
 85         end
 86         
 87         INIT_FUN_SET1: 
 88         begin
 89             lcd_data <= 8'h30;    //功能设定
 90             state <= INIT_FUN_SET2;
 91         end 
 92         
 93         INIT_FUN_SET2:
 94         begin
 95             lcd_data <= 8'h30;    //功能设定
 96             state <= INIT_DISPLAY;
 97         end
 98             
 99         INIT_DISPLAY:
100         begin
101             lcd_data <= 8'h0c;    //显示设定
102             state <= INIT_CLEAR;
103         end
104             
105         INIT_CLEAR:
106         begin
107             lcd_data <= 8'h01;    //清屏
108             state <= INIT_DOT_SET;
109         end
110         
111         INIT_DOT_SET:
112         begin
113             lcd_data <= 8'h06;    //进入点设定
114             state <= SET_DDRAM;
115         end
116         
117         SET_DDRAM:
118         begin
119             lcd_data <= 8'h94;//2 line            
120             state <= WRITE_DATA1;
121         end
122         
123         WRITE_DATA1:
124         begin
125             lcd_data <= data_buf;
126             state <= SET_DDRAM;  //一直在同一个地方刷新显示
127         end
128             
129 /*        STOP: 
130         begin
131             en <= 1'b0;//显示完了,lcd_e就一直拉为低
132             state <= STOP;
133         end   */
134         
135         default: state <= IDLE;
136     endcase
137 
138 /***************************************************/
139 assign lcd_rw = 1'b0;//只有写模式
140 assign lcd_psb = 1'b1;//并口模式
141 assign lcd_en = en ?  lcd_clk : 1'b0;
142 /***************************************************/
143 endmodule
View Code

ps2_top.v

 1 module ps2_top(
 2                 //input
 3                 sys_clk,
 4                 rst_n,
 5                 key_clk,
 6                 key_data,
 7                 
 8                 //output
 9                 lcd_rs,
10                 lcd_rw,
11                 lcd_en,
12                 lcd_data,
13                 lcd_psb
14                );
15 input sys_clk;// 50MHZ
16 input rst_n;
17 input key_clk;      //键盘时钟
18 input key_data;   //键盘数据
19 
20 output lcd_rs;//H:data    L:command
21 output lcd_rw;//H:read module    L:write module
22 output lcd_en;//H active
23 output [7:0] lcd_data;
24 output lcd_psb;//H:parallel    module    L:SPI module
25 
26 wire [7:0] data_buf;
27 
28 ps2_control   u1(
29                     //input 
30                     .sys_clk(sys_clk),
31                     .rst_n(rst_n),
32                     .key_clk(key_clk),
33                     .key_data(key_data),
34                     
35                     //output
36                     .data_buf(data_buf),
37                    );
38                    
39 LCD12864    u2(
40                     //input 
41                     .sys_clk(sys_clk),
42                     .rst_n(rst_n),
43                     .data_buf(data_buf),
44                     
45                     //output 
46                     .lcd_rs(lcd_rs),
47                     .lcd_rw(lcd_rw),
48                     .lcd_en(lcd_en),
49                     .lcd_data(lcd_data),
50                     .lcd_psb(lcd_psb)
51                 );
52 endmodule
View Code


PS2接口和LCD12864采用的是飞线连接的,显示效果图:

                                   

 

转载于:https://www.cnblogs.com/wen2376/p/3364324.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值