• 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采用的是飞线连接的,显示效果图:

                                       

  • 相关阅读:
    20155305 2016-2017-2 《Java程序设计》实验二 Java面向对象程序设计
    20155305乔磊2016-2017-2《Java程序设计》第八周学习总结
    20155305 2016-2017-2 《Java程序设计》实验一 Java开发环境的熟悉(macOS + IDEA)
    20155305乔磊2016-2017-2《Java程序设计》第七周学习总结
    20155305乔磊2016-2017-2《Java程序设计》第六周学习总结
    2017-2018-1 20155302 《信息安全系统设计基础》第3周学习总结
    20155302 第二周课堂实践
    2017-2018-1 20155302 《信息安全系统设计基础》第1周学习总结
    20155302杨效宸《Java程序设计》课程总结
    20155302实验五 网络编程与安全
  • 原文地址:https://www.cnblogs.com/wen2376/p/3364324.html
Copyright © 2020-2023  润新知