本实验是通过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. 打印出最后执行的mysql 语句

    db.php 文件中添加 public function getlastsql(){ return $this->sql; } 入口文件中添加,公共方法 function getlastsql( ...

  2. HDU4310:Hero

    Problem Description When playing DotA with god-like rivals and pig-like team members, you have to fa ...

  3. mongo细节

    mongo创建表db.createCollection(name, {capped: <Boolean>, autoIndexId: <Boolean>, size: < ...

  4. python的历史与优劣

    历史 Python的创始人是Guido van Rossum,在发明Python语言之前Guido曾参与过一门称作ABC的语言的设计,ABC是专门为非专业程序员设计的:Guido在Python语言的设 ...

  5. qq客服问题

    angularJs会给ng-href的不正常跳转,会 添加unsafe的前缀.原因是angular对href是有安全检查的,只能生成它认为安全的链接.解决方法如下: 在config.js中注入 fun ...

  6. eclipse关联源码的方法

    1.在项目的libs目录下,新建一个android-support-v4.jar.properties文件 2.打开android-support-v4.jar.properties,编辑. 输入源码 ...

  7. 在Service服务中请求网络

    一.startservice方式启动 第一次startservice启动服务的时候,会走oncreate和onstart方法, 第二次startservice启动服务的时候,会走onstart方法, ...

  8. Failed to load c++ bson extension, using pure JS version

    Failed to load c++ bson extension, using pure JS version npm install mongodbnpm install bson npm ins ...

  9. setTranslucent

    在ios7中 如果setTranslucent=yes 默认的   则状态栏及导航栏底部为透明的,界面上的组件应该从屏幕顶部开始显示,因为是半透明的,可以看到,所以为了不和状态栏及导航栏重叠,第一个组 ...

  10. 3.1 cron表达式

    1.Cron在线生成网址:      http://cron.qqe2.com/   http://www.pdtools.net/tools/becron.jsp#cron 2.Cron 概要 3. ...