利用键盘开关控制液晶显示器进行十六进制数字显示.docx
《利用键盘开关控制液晶显示器进行十六进制数字显示.docx》由会员分享,可在线阅读,更多相关《利用键盘开关控制液晶显示器进行十六进制数字显示.docx(24页珍藏版)》请在冰豆网上搜索。
利用键盘开关控制液晶显示器进行十六进制数字显示
目录
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