利用键盘开关控制液晶显示器进行十六进制数字显示.docx
- 文档编号:6193097
- 上传时间:2023-01-04
- 格式:DOCX
- 页数:24
- 大小:312.89KB
利用键盘开关控制液晶显示器进行十六进制数字显示.docx
《利用键盘开关控制液晶显示器进行十六进制数字显示.docx》由会员分享,可在线阅读,更多相关《利用键盘开关控制液晶显示器进行十六进制数字显示.docx(24页珍藏版)》请在冰豆网上搜索。
利用键盘开关控制液晶显示器进行十六进制数字显示
中北大学
课程设计说明书
学生姓名:
张彪
学号:
0706024146
学院:
电子计算机科学与技术学院
专业:
微电子学
题目:
利用键盘开关控制液晶显示器进行十六进制数字显示
指导教师:
王红亮职称:
讲师
2010年6月25日
目录
1、课程设计的目的………………………………………………………2
2、课程设计内容和要求……………………………………………………2
2.1、课程设计内容………………………………………………………2
2.2、课程设计要求………………………………………………………2
3、设计方案及实现情况………………………………………………2
3.1、设计思路……………………………………………………………2
3.2、工作原理及框图……………………………………………………3
3.3、各模块功能描述……………………………………………………3
3.4、程序VHDL语言源代码………………………………………………………4
3.5、仿真结果…………………………………………………………………12
3.6、实验箱验证情况……………………………………………………13
4、课程设计总结………………………………………………………16
5、参考文献……………………………………………………………17
6、附录:
液晶显示器简介……………………………………………17
1、课程设计的目的
(1)学习操作数字电路设计实验开发系统,掌握液晶显示模块的工作原理及应用。
(2)掌握组合逻辑电路、时序逻辑电路的设计方法。
(3)学习掌握可编程器件设计的全过程。
2、课程设计的内容和要求
2.1、课程设计内容
(1)学习掌握键盘开关控制模块、液晶显示模块的工作原理及应用;
(2)熟练掌握VHDL编程语言,编写键盘开关控制模块的控制逻辑;
(3)仿真所编写的程序,模拟验证所编写的模块功能;
(4)下载程序到芯片中,硬件验证所设置的功能,能够实现十六进制数字的显示;
(5)整理设计内容,编写设计说明书。
2.2、课程设计要求
(1)本课程设计说明书。
(2)VHDL源程序及内部原理图。
(3)该设计可以在实验箱上正常工作并演示。
3、设计方案及实现情况
3.1、设计思路
本次设计要求利用VHDL语言编写源程序,利用键盘控制液晶显示十六进制数。
因此,本次设计的程序利用矩阵键盘模块产生的按键信号来控制OCMJ模块显示0~F十六进制数。
当程序被下载到FPGA中,首先进行上电自复位,接着检测是否有按键按下,并判读是否是一个干扰,如果确定是0~F中的某一按键按下,则程序将检测OCMJ的BUSY信号是否为高,若为高,则继续等待,否则将按键对应的地址送入OCMJ模块的存储单元中,而液晶模块也会置REQ信号为高电平,完成一次握手,同时FPGA向OCMJ发送一个四字的命令,分别是显示8*8ASCII码命令F1、显示坐标值XX\YY,以及按键的键值QQ。
(注:
第一次传送前会先发送一个清零命令F4)若再有按键按下则重复上述过程。
3.2、工作原理及框图
本实验采用的是OCMJ中文模块系列液晶显示器,内含GB231216*16点阵国标一级简体汉字和ASCII8*8(半高)及8*16(全高)点阵英文字库,用户输入区位码或ASCII码即可实现文本显示。
OCMJ中文模块系列液晶显示器也可用作一般的点阵图形显示器之用。
提供有位点阵和字节点阵两种图形显示功能,用户可在指定的屏幕位置上以点为单位或以字节为单位进行图形显示。
完全兼容一般的点阵模块。
OCMJ中文模块系列液晶显示器可以实现汉字、ASCII码、点阵图形和变化曲线的同屏显示,并可通过字节点阵图形方式造字。
引脚功能图和内部结构图分别如下图1所示。
图1液晶显示器
3.3、各功能模块作用描述
矩阵模块由四个子电路构成,对应于源程序的四个进程。
它们分别是时钟产生电路、键盘扫描电路、键盘消抖电路、以及键盘译码电路。
时钟产生电路时利用自由的计数器产生各种频率的时钟信号。
在设计中,用到了系统时钟信号、分频产生的键盘扫描信号、消抖信号。
键盘扫描电路的作用是用来提供键盘扫描信号的电路。
扫描时依序扫描八列按键,当扫描信号为000时,扫描0这一列按键......没扫描一列按键,就检查一次是否有按键按下,如果这排有按键按下,就马上停止扫描,立即进行按键编码动作,存储键码,如果没有按键按下,则继续扫描下一列。
键盘消抖电路的使用是因为按键大多是机械式的开关结构,在开关切换的瞬间会在接触点出现来回弹跳的现象,因此必须加上键盘消抖电路,避免误操作信号的发生。
相关信号定义:
在本次课程设计中,定义的主要输入输出信号有:
液晶模块的请求应答信号REQ\BUSY(主要用于OCMJ是否决定处理数据上的数据);键盘选通信号SEL/KEY(两者一起构成键盘行、列扫描信号结合后的信号dcc);数据输出信号DOUT。
同时还定义了重要的过程信号,其中counter为计数信号,用来确定REQ(本设计中是计3个数后,REQ才为1,否则为0)。
addrbegin用来定义存储器首地址,addr1用来存储地址变量(传送一个数据需要送4个字节,分别是写命令字节,横坐标字节,纵坐标字节,写的内容字节);addr用来定义数据地址(由addrbegin和addr1构成);DAT用来记录输入到lcd的数据,counter1用来分频计数(本设计是四分频);counte为键盘扫描辅助信号(类似于连接线的作用);counter2为弹跳消除信号(消抖的方法有三种:
加延时程序,需考虑不同器件的延时时间和温度;加触发器,需考虑时钟的同步性;本设计采用计数的方式来消除按键抖动的影响计三十次数之后数据稳定后才开始读入);dcc用来记录键盘行、列扫描信号结合后的信号,DCC1用来记录按下的为哪个键。
clk1,test,koff分别为时钟1信号,测试信号,按键消抖信号(test=’0‘时,表示有按键按下,koff='0'时,表示按键无抖动影响)。
3.4、程序VHDL语言源代码
LIBRARYieee;
USEieee.std_logic_1164.ALL;
USEieee.std_logic_unsigned.ALL;
USEieee.std_logic_arith.all;
ENTITYshixianis
PORT(clr,clk,BUSY:
INstd_logic;
REQ:
OUTstd_logic;
sel:
OUTSTD_LOGIC_VECTOR(2downto0);
key:
INSTD_LOGIC_VECTOR(3downto0);
dout:
outstd_logic_vector(7downto0));
ENDshixian;
ARCHITECTUREdoitOFshixianIS
signalcounter:
std_logic_vector(7downto0);
signaladdrbegin:
std_logic_vector(7downto0);
signaladdr1:
std_logic_vector(7downto0);
signaladdr:
std_logic_vector(7DOWNTO0);
signalDAT:
std_logic_vector(7downto0);
signalcounter1:
std_logic_vector(1downto0);
signalcounte:
std_logic_vector(2downto0);
signalcounter2:
std_logic_vector(4downto0);
signaldcc:
std_logic_vector(6downto0);
signalclk1,test,koff:
std_logic;
signalDCC1:
STD_LOGIC_VECTOR(3DOWNTO0);
BEGIN
test<=key(3)andkey
(2)andkey
(1)andkey(0);
P0:
process(clr,clk)
begin
if(clr='0')then
counter1<="00";
elsif(clk'eventandclk='1')then
counter1<=counter1+1;
endif;
endprocessP0;
clk1<='0'whencounter1<="01"else
'1';
P1:
process(clr,clk1,test)
begin
if(clr='0')then
counte<="000";
elsif(clk1'eventandclk1='1')then
if(test='0')or(koff='0')then
counte<=counte;
else
counte<=counte+1;
endif;
endif;
endprocessP1;
sel<=counte;
dcc<=counte&key;
P2:
process(clk,test)
begin
ifclr='0'then
dcc1<="0000";
elsif(clk'eventandclk='0')then
if(dcc="0001110")then
dcc1<="0000";
elsif(dcc="0011110")then
dcc1<="0001";
elsif(dcc="0101110")then
dcc1<="0010";
elsif(dcc="0111110")then
dcc1<="0011";
elsif(dcc="1101110")then
dcc1<="0100";
elsif(dcc="1111110")then
dcc1<="0101";
elsif(dcc="0001101")then
dcc1<="0110";
elsif(dcc="0011101")then
dcc1<="0111";
elsif(dcc="1001101")then
dcc1<="1000";
elsif(dcc="1011101")then
dcc1<="1001";
elsif(dcc="1101101")then
dcc1<="1010";
elsif(dcc="1111101")then
dcc1<="1011";
elsif(dcc="0101011")then
dcc1<="1100";
elsif(dcc="0111011")then
dcc1<="1101";
elsif(dcc="1001011")then
dcc1<="1110";
elsif(dcc="1011011")then
dcc1<="1111";
elsif(test='0')then
dcc1<="1111";
endif;
endif;
endprocessP2;
P3:
process(test,clk,clr)
begin
if(clr='0')then
counter2<="00000";
koff<='1';
elsif(clk'eventandclk='1')then
if(test='0')then
counter2<="00000";
koff<='0';
elsif(counter2<"11110")then
counter2<=counter2+1;
elsif(counter2="11110")then
koff<='1';
endif;
endif;
endprocessP3;
p4:
process(dcc1)
begin
casedcc1is
when"0000"=>addrbegin<="00000001";
when"0001"=>addrbegin<="00000101";
when"0010"=>addrbegin<="00001001";
when"0011"=>addrbegin<="00001101";
when"0100"=>addrbegin<="00010001";
when"0101"=>addrbegin<="00010101";
when"0110"=>addrbegin<="00011001";
when"0111"=>addrbegin<="00011101";
when"1000"=>addrbegin<="00100001";
when"1001"=>addrbegin<="00100101";
when"1010"=>addrbegin<="00101001";
when"1011"=>addrbegin<="00101101";
when"1100"=>addrbegin<="00110001";
when"1101"=>addrbegin<="00110101";
when"1110"=>addrbegin<="00111001";
when"1111"=>addrbegin<="00111101";
whenothers=>null;
endcase;
endprocessp4;
P5:
process(clr,busy)
begin
if(clr='0')then
addr<="00000000";
elsif(busy'eventandbusy='0')then
addr<=addrbegin+addr1;
endif;
endprocessP5;
P6:
process(clr,busy)
begin
if(clr='0')then
addr1<="00000000";
elsif(busy'eventandbusy='1')then
if(addr1="00000011")then
addr1<="00000000";
else
addr1<=addr1+1;
endif;
endif;
endprocessP6;
P7:
process(busy,clk)
begin
if(busy='1')then
counter<="00000000";
elsif(clk'eventandclk='1')then
counter<=counter+1;
endif;
endprocessP7;
dout<=DAT;
REQ<='1'whencounter>="00000011"else
'0';
P8:
PROCESS(addr)
BEGIN
CASEaddrIS
WHEN"00000000"=>DAT<="11110100";
WHEN"00000001"=>DAT<="11110001";
WHEN"00000010"=>DAT<="00001000";
WHEN"00000011"=>DAT<="00001000";
WHEN"00000100"=>DAT<="00110000";
WHEN"00000101"=>DAT<="11110001";
WHEN"00000110"=>DAT<="00001000";
WHEN"00000111"=>DAT<="00001000";
WHEN"00001000"=>DAT<="00110001";
WHEN"00001001"=>DAT<="11110011";
WHEN"00001010"=>DAT<="00001000";
WHEN"00001011"=>DAT<="00001000";
WHEN"00001100"=>DAT<="00110010";
WHEN"00001101"=>DAT<="11110001";
WHEN"00001110"=>DAT<="00001000";
WHEN"00001111"=>DAT<="00001001";
WHEN"00010000"=>DAT<="00110011";
WHEN"00010001"=>DAT<="11110001";
WHEN"00010010"=>DAT<="00001000";
WHEN"00010011"=>DAT<="00001000";
WHEN"00010100"=>DAT<="00110100";
WHEN"00010101"=>DAT<="11110001";
WHEN"00010110"=>DAT<="00001000";
WHEN"00010111"=>DAT<="00001000";
WHEN"00011000"=>DAT<="00110101";
WHEN"00011001"=>DAT<="11110001";
WHEN"00011010"=>DAT<="00001000";
WHEN"00011011"=>DAT<="00001000";
WHEN"00011100"=>DAT<="00110110";
WHEN"00011101"=>DAT<="11110001";
WHEN"00011110"=>DAT<="00001000";
WHEN"00011111"=>DAT<="00001000";
WHEN"00100000"=>DAT<="00110111";
WHEN"00100001"=>DAT<="11110001";
WHEN"00100010"=>DAT<="00001000";
WHEN"00100011"=>DAT<="00001000";
WHEN"00100100"=>DAT<="00111000";
WHEN"00100101"=>DAT<="11110001";
WHEN"00100110"=>DAT<="00001000";
WHEN"00100111"=>DAT<="00001000";
WHEN"00101000"=>DAT<="00111001";
WHEN"00101001"=>DAT<="11110001";
WHEN"00101010"=>DAT<="00001000";
WHEN"00101011"=>DAT<="00001000";
WHEN"00101100"=>DAT<="01000001";
WHEN"00101101"=>DAT<="11110001";
WHEN"00101110"=>DAT<="00001000";
WHEN"00101111"=>DAT<="00001000";
WHEN"00110000"=>DAT<="01000010";
WHEN"00110001"=>DAT<="11110001";
WHEN"00110010"=>DAT<="00001000";
WHEN"00110011"=>DAT<="00001000";
WHEN"00110100"=>DAT<="01000011";
WHEN"00110101"=>DAT<="11110001";
WHEN"00110110"=>DAT<="00001000";
WHEN"00110111"=>DAT<="00001000";
WHEN"00111000"=>DAT<="01000100";
WHEN"00111001"=>DAT<="11110011";
WHEN"00111010"=>DAT<="00001000";
WHEN"00111011"=>DAT<="00001000";
WHEN"00111100"=>DAT<="01000101";
WHEN"00111101"=>DAT<="11110001";
WHEN"00111110"=>DAT<="00001000";
WHEN"00111111"=>DAT<="00001000";
WHEN"01000000"=>DAT<="01000110";
WHENOTHERS=>DAT<="00000000";
ENDCASE;
ENDPROCESSP8;
ENDdoit;
3.5、仿真结果
图2仿真波形
3.6、实验箱验证情况
图3数字0图4数字1
图5数字2图6数字3
图7数字4图8数字5
图9数字6图10数字7
图11数字8图12数字9
图13字母A图14字母B
图15字母C图16字母D
图17字母E图18字母F
图19管脚分配图
图20连接图
4、课程设计总结
回顾起此次的利用键盘开关控制液晶显示器进行十六进制数字显示课程设计,至今我仍感慨颇多:
即便这是第二次做课程设计,但每次对我来说都是新的,都需要自己去构思,去熟悉以前的知识。
本次课程设计所应用的主要由矩阵键盘模块和液晶模块两部分构成,由于需要两个模块共同完成这次试验的,连接的部分显得尤为重要。
在源程序中使用的是信号来作为连接的,它的作用就是一个桥梁,就类似于连接线。
我查阅了相关矩阵键盘和液晶模块的书籍,了解了设计中所用到的模块的电气性能和参数(主要是液晶模块OCMJ)。
在设计的过程中遇到问题,可以说得是困难重重,即使是第二次做的,难免会遇到过各种各样的问题:
在仿真程序的时候能顺利通过,但在和机箱连接之后,当有些按下键时,会出现明显的延时,有的甚至不能显示出相应的数字。
后来查阅书籍才知道,当按键按下时,会出现抖动,数据有一段不稳定的时期,这就需要我们进行消抖。
消抖的方法有三种:
加延时程序,需考虑不同器件的延时时间和温度;加触发器,需考虑时钟的同步性;本设计采用计数的方式来消除按键抖动的影响计三十次数之后数据稳定后才开始读入。
但有时候电脑的发热等情况也会影响到仿真波形,出现抖动。
这次课程设计终于顺利完成了,我了解了液晶显示屏的逻辑和时序控制要求,掌握液晶显示器的工作原理及应用
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 利用 键盘 开关 控制 液晶显示器 进行 十六进制 数字 显示