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

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

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

ps2_control.v

 module ps2_control(
//input
sys_clk,
rst_n,
key_clk,
key_data, //output
data_buf,
);
input sys_clk; //50Mhz
input rst_n;
input key_clk; //键盘时钟
input key_data; //键盘数据 output [:] data_buf; //保存要显示的数据 //***********************************************
//检测key_clk的下降沿
//***********************************************
reg key_clk_1;
reg key_clk_2;
always @(posedge sys_clk or negedge rst_n)
if(!rst_n) begin
key_clk_1 <= 'b1;
key_clk_2 <= 'b1;
end
else begin
key_clk_1 <= key_clk;
key_clk_2 <= key_clk_1;
end wire key_clk_n;
assign key_clk_n = key_clk_2 & (~key_clk_1);
//***********************************************
//对key_data上的数据进行保存
//***********************************************
reg [:] i;
reg [:] data_temp;
always @(posedge sys_clk or negedge rst_n)
if(!rst_n) begin
i <= 'd0;
data_temp <= 'h00;
end
else if(key_clk_n) begin
case(i)
'd0: i <= i + 1'b1; //起始位不处理 'd1,4'd2,'d3,4'd4,'d5,4'd6,'d7,4'd8:
begin
i <= i + 'b1;
data_temp[i-] <= key_data;
end 'd9: i <= i + 1'b1; //奇校验位不处理 'd10: i <= 4'd0; //停止位不处理 default: ;
endcase
end reg key_f0; //松键标志位,置1表示接收到数据8'hf0,再接收到下一个数据后清零
reg[:] ps2_data;
always @(posedge sys_clk or negedge rst_n) //接收数据的相应处理,这里只对1byte的键值进行处理
if(!rst_n) begin
key_f0 <= 'b0;
ps2_data <= 'h00;
end
else if(i=='d10) //刚传送完一个字节数据
begin
if(data_temp == 'hf0)
key_f0 <= 'b1; //说明有键被释放
else if(!key_f0) //说明有键按下
ps2_data <= data_temp; //锁存当前键值
else
key_f0 <= 'b0;
end reg [:] data_buf;
always @ (ps2_data) begin
case (ps2_data)
'h15: data_buf = "Q";
'h1d: data_buf = "W";
'h24: data_buf = "E";
'h2d: data_buf = "R";
'h2c: data_buf = "T";
'h35: data_buf = "Y";
'h3c: data_buf = "U";
'h43: data_buf = "I";
'h44: data_buf = "O";
'h4d: data_buf = "P";
'h1c: data_buf = "A";
'h1b: data_buf = "S";
'h23: data_buf = "D";
'h2b: data_buf = "F";
'h34: data_buf = "G";
'h33: data_buf = "H";
'h3b: data_buf = "J";
'h42: data_buf = "K";
'h4b: data_buf = "L";
'h1a: data_buf = "Z";
'h22: data_buf = "X";
'h21: data_buf = "C";
'h2a: data_buf = "V";
'h32: data_buf = "B";
'h31: data_buf = "N";
'h3a: data_buf = "M";
default: data_buf = 'h00;
endcase
end endmodule

LCD12864.v

 module LCD12864(
//input
sys_clk,
rst_n,
data_buf, //output
lcd_rs,
lcd_rw,
lcd_en,
lcd_data,
lcd_psb
);
input sys_clk;// 50MHZ
input rst_n;
input [:] data_buf; output lcd_rs;//H:data L:command
output lcd_rw;//H:read module L:write module
output lcd_en;//H active
output [:] lcd_data;
output lcd_psb;//H:parallel module L:SPI module /***************************************************/
parameter T3MS = 'd149_999;
parameter IDLE = 'd0,
INIT_FUN_SET1 = 'd1,
INIT_FUN_SET2 = 'd2,
INIT_DISPLAY = 'd3,
INIT_CLEAR = 'd4,
INIT_DOT_SET = 'd5,
SET_DDRAM = 'd6,
WRITE_DATA1 = 'd7;
/* INIT_FUN_SET3 = 4'd8,
SET_CGRAM = 4'd9,
WRITE_DATA2 = 4'd10,
SET_DDRAM2 = 4'd11,
SET_CUSTOM_L = 4'd12,
SET_CUSTOM_H = 4'd13,
STOP = 4'd14;*/
/***************************************************/
//产生周期为6MS的lcd_clk给LCD
reg [:] cnt;
reg lcd_clk;
always @(posedge sys_clk or negedge rst_n)
if(!rst_n) begin
cnt <= 'd0;
lcd_clk <= 'b0;
end
else if(cnt == T3MS)begin
cnt <= 'd0;
lcd_clk <= ~lcd_clk;
end
else
cnt <= cnt + 'b1; /***************************************************/
reg lcd_rs;
always @(posedge lcd_clk or negedge rst_n)
if(!rst_n)
lcd_rs <= 'b0;
else if(state == WRITE_DATA1)
lcd_rs <= 'b1; //写数据模式
else
lcd_rs <= 'b0; //写命令模式
/***************************************************/
reg [:] state;
reg [:] lcd_data;
reg [:] num;
reg en;
always @(posedge lcd_clk or negedge rst_n)
if(!rst_n) begin
state <= IDLE;
lcd_data <= 'h00;
en <= 'b1;
num <= 'd0;
end
else
case(state)
IDLE:
begin
state <= INIT_FUN_SET1;
lcd_data <= 'hzz;
en <= 'b1;
end INIT_FUN_SET1:
begin
lcd_data <= 'h30; //功能设定
state <= INIT_FUN_SET2;
end INIT_FUN_SET2:
begin
lcd_data <= 'h30; //功能设定
state <= INIT_DISPLAY;
end INIT_DISPLAY:
begin
lcd_data <= 'h0c; //显示设定
state <= INIT_CLEAR;
end INIT_CLEAR:
begin
lcd_data <= 'h01; //清屏
state <= INIT_DOT_SET;
end INIT_DOT_SET:
begin
lcd_data <= 'h06; //进入点设定
state <= SET_DDRAM;
end SET_DDRAM:
begin
lcd_data <= 'h94;//2 line
state <= WRITE_DATA1;
end WRITE_DATA1:
begin
lcd_data <= data_buf;
state <= SET_DDRAM; //一直在同一个地方刷新显示
end /* STOP:
begin
en <= 1'b0;//显示完了,lcd_e就一直拉为低
state <= STOP;
end */ default: state <= IDLE;
endcase /***************************************************/
assign lcd_rw = 'b0;//只有写模式
assign lcd_psb = 'b1;//并口模式
assign lcd_en = en ? lcd_clk : 'b0;
/***************************************************/
endmodule

ps2_top.v

 module ps2_top(
//input
sys_clk,
rst_n,
key_clk,
key_data, //output
lcd_rs,
lcd_rw,
lcd_en,
lcd_data,
lcd_psb
);
input sys_clk;// 50MHZ
input rst_n;
input key_clk; //键盘时钟
input key_data; //键盘数据 output lcd_rs;//H:data L:command
output lcd_rw;//H:read module L:write module
output lcd_en;//H active
output [:] lcd_data;
output lcd_psb;//H:parallel module L:SPI module wire [:] data_buf; ps2_control u1(
//input
.sys_clk(sys_clk),
.rst_n(rst_n),
.key_clk(key_clk),
.key_data(key_data), //output
.data_buf(data_buf),
); LCD12864 u2(
//input
.sys_clk(sys_clk),
.rst_n(rst_n),
.data_buf(data_buf), //output
.lcd_rs(lcd_rs),
.lcd_rw(lcd_rw),
.lcd_en(lcd_en),
.lcd_data(lcd_data),
.lcd_psb(lcd_psb)
);
endmodule

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

                           

PS2键盘 + LCD12864 实验的更多相关文章

  1. PS2鼠标+LCD12864实验——终于OK 了

    抱着“不气馁.不放弃.誓不罢休.搞不定你我还能搞其他玩意吗”的心态,调试许久的PS2鼠标实验,终于在今天被我搞定了.发几张图显摆一下,嘿嘿...    左键按下+鼠标移动 右键按下+鼠标移动  中键按 ...

  2. PS2鼠标+LCD12864实验(调试未成功)

    此试验我一人调试许久都未成功,但发送ff时,读出来的数据确是对的,一开始让我窃喜,但发送f4时,读出来的数据确是错的,哎让苦恼啊,能力有限,只能先暂时就这样吧,那位什么还要贴出来呢,有两个原因: 1. ...

  3. 50元制作PS2键盘无线监控装置

    0×00    什么是Arduino  Arduino实际上就是一种开发板,将微控制器和必需的元件集成在一块电路板上,扩展出完善的接口和针脚,就可以接上各种各样的传感器,完成你心中的设计,你也可以把它 ...

  4. 基于VHDL利用PS2键盘控制的电子密码锁设计

    基于VHDL利用PS2键盘控制的密码锁设计 附件:下载地址 中文摘要 摘 要:现代社会,人们的安全意识正在不断提升.按键密码锁由于其具有方便性.低成本等特征,还是大有用武之地的.但是通常的按键密码锁开 ...

  5. 基于I2C EPPRPM(AT24C02B) + LCD12864实验

    本次实验目的:在指定的EPPROM地址中,写入一数据,延时100MS后,在从该地址中读取,并在LCD上显示. 该实验在前两天就开始做了,一开始并没有成功,读出的一直0x00,当时也调了一会,但跳回到P ...

  6. 8086键盘输入实验——《x86汇编语言:从实模式到保护模式》读书笔记07

    1.BIOS中断 我们可以为所有中断类型自定义中断处理过程,包括内部中断.硬件中断和软中断. BIOS中断,又称BIOS功能调用,主要是为了方便地使用最基本的硬件访问功能.通常,为了区分针对同一硬件的 ...

  7. PS2键盘扫描码:通码与断码

    键盘扫描码(实用于标准PC的101.102和104 键的键盘),按下发送通码,弹起发送断码. 说明: 第一类按键,通码为1字节,断码为 0xF0+通码 形式.如A键,其通码为 0x1C,断码为 0xF ...

  8. 基于Verilog HDL 各种实验

    菜鸟做的的小实验链接汇总:           1.基于Verilog HDL 的数字时钟设计 2.乘法器 3.触发器(基本的SR触发器.同步触发器.D触发器) 4.基于Verilog HDL的ADC ...

  9. 【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验八:PS/2模块② — 键盘与组合键

    实验八:PS/2模块② — 键盘与组合键 实验七之际,我们学习如何读取PS/2键盘发送过来的通码与断码,不过实验内容也是一键按下然后释放,简单按键行为而已.然而,实验八的实验内容却是学习组合键的按键行 ...

随机推荐

  1. Github建站全攻略

    本系列为原创,发表在我的github主页,详细介绍了如何在github上建立个人网站,还包括域名绑定.评论功能.站内搜索等辅助功能的介绍,欢迎交流.   一步步在GitHub上创建博客主页(6) 本篇 ...

  2. 中文输入法不触发onkeyup事件的解决办法

    当监听一个input的keyup的事件的时候,英文输入法的情况下可以实时的通过keyup事件检测到文本框value的变化,但是当输入法变成中文后,input的keyup事件就不会被正常触发. 方法:o ...

  3. git 使用总结

  4. window窗体程序意外崩溃,EventType clr20r3错误的解决方法

    EventType clr20r3, P1 ggreadcard.exe, P2 1.0.0.0, P3 51d3d283, P4 zljy.common, P5 1.0.0.0, P6 4fc6c2 ...

  5. 滚动视图UIScrollView

    int i; @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super ...

  6. nextSibling,previousSibling,childNodes常见错误

    在使用nextSibling与previousSibling时,常出现选不到预计对象的情况 eg: <div class="a">1</div> <d ...

  7. UVA - 437 The Tower of Babylon(dp-最长递增子序列)

    每一个长方形都有六种放置形态,其实可以是三种,但是判断有点麻烦直接用六种了,然后按照底面积给这些形态排序,排序后就完全变成了LIS的问题.代码如下: #include<iostream> ...

  8. URAL 2099 Space Invader题解 (计算几何)

    啥也不说了,直接看图吧…… 代码如下: #include<stdio.h> #include<iostream> #include<math.h> using na ...

  9. Lint Code——最多共线的点的个数

    题目链接:http://www.lintcode.com/zh-cn/problem/max-points-on-a-line/# 条件:给一个点数组 目标:求出共线的点的最多个数 实现:时间复杂度- ...

  10. 2015十大顶级开源ERP系统点评

    如今,企业资源规划(ERP)和客户关系管理(CRM)系统的必要性已经被各种组织和企业所认可:ERP和CRM能够直接为企业的业务效率和利润做出贡献. 但是随着今天企业商业形态的日趋多样化,互联网新经济的 ...