利用按键开关控制液晶显示器进行十六进制数字显示说明书.docx
《利用按键开关控制液晶显示器进行十六进制数字显示说明书.docx》由会员分享,可在线阅读,更多相关《利用按键开关控制液晶显示器进行十六进制数字显示说明书.docx(21页珍藏版)》请在冰豆网上搜索。
利用按键开关控制液晶显示器进行十六进制数字显示说明书
中北大学
课程设计说明书
学生姓名:
张又木
学号:
0906044112
学院:
电子与计算机科学技术学院
专业:
电子科学与技术
题目:
利用按键开关控制液晶显示器进行十六进制数字显示
指导教师:
焦新泉职称:
讲师
2012年6月20日
目录
1、课程设计目的……………………………………………………………………2
2、课程设计内容和要求……………………………………………………………2
2.1、设计内容………………………………………………………………………………2
2.2、设计要求………………………………………………………………………………2
3、 设计方案及实现情况…………………………………………………………2
3.1、设计思路………………………………………………………………………………2
3.2、工作原理及框图………………………………………………………………………2
3.3、各模块功能描述………………………………………………………………………4
3.4、仿真结果………………………………………………………………………………15
3.5、实验箱验证情况………………………………………………………………………17
4、课程设计总结……………………………………………………………………18
5、参考文献…………………………………………………………………………18
1、课程设计目的
1.学习操作数字电路设计实验开发系统,掌握液晶显示模块的工作原理及应用。
2.掌握组合逻辑电路、时序逻辑电路的设计方法。
3.学习掌握可编程器件设计的全过程
2、课程设计内容和要求
2.1、设计内容
1.学习掌握按键开关控制模块、液晶显示模块的工作原理及应用;
2.熟练掌握VHDL编程语言,编写按键开关控制模块的控制逻辑;
3.仿真所编写的程序,模拟验证所编写的模块功能;
4.下载程序到芯片中,硬件验证所设置的功能,能够实现十六进制数字的显示;
5.整理设计内容,编写设计说明书。
2.2、设计要求
1.本课程设计说明书。
2.VHDL源程序及内部原理图。
3.该设计可以在实验箱上正常工作并演示。
3、设计方案和实现情况
3.1、设计思路
对于这个题目,首先对试验箱上的时钟频率进行降频,因为试验箱上的时钟频率很高,而液晶系统并不需要很高的时钟频率,并且低频时钟更加有利于消抖功能的实现,其次对所使用的按键进行消抖处理,然后将消抖处理后的按键信号直接送入按键计数模块进行计数,再将按键计数模块的计数结果送往译码显示模块,严格按照液晶OCMJ的显示时序将要显示的数据的行坐标,列坐标和数据对应的在BUSY信号不为高的情况下,通过数据线送出,然后在REQ信号线上送出一个高脉冲,将数据显示在液晶OCMJ上。
3.2、工作原理及框图
总体工作原理:
在经过分频的时钟信号的驱动下,利用按键计数模块对进行了消抖处理后的按键信号进行计数,然后将计数数据送给译码液晶显示模块,进而驱动液晶屏幕进行数据的显示。
系统总体原理图如图1所示。
图1系统总体原理图
液晶显示器工作原理:
OCMJ中文模块系列液晶显示器内含GB231216*16点阵国标一级简体汉字和ASCII8*8(半高)及8*16(全高)点阵英文字库,用户输入区位码或ASCII码即可实现文本显示。
OCMJ中文模块系列液晶显示器可以实现汉字、ASCII码、点阵图形和变化曲线的同屏显示,并可通过字节点阵图形方式造字。
由于显示的是十六进制数字,故只须掌握接口协议和其中一条用户命令。
接口协议为请求/应答(REQ/BUSY)握手方式。
应答BUSY高电平(BUSY=1)表示OCMJ忙于内部处理,不能接收用户命令;BUSY低电平(BUSY=0)表示OCMJ空闲,等待接收用户命令。
发送命令到OCMJ可在BUSY=0后的任意时刻开始,先把用户命令的当前字节放到数据线上,接着发高电平REQ信号(REQ=1)通知OCMJ请求处理当前数据线上的命令或数据。
OCMJ模块在收到外部的REQ高电平信号后立即读取数据线上的命令或数据,同时将应答线BUSY变为高电平,表明模块已收到数据并正在忙于对此数据的内部处理,此时,用户对模块的写操作已经完成,用户可以撤消数据线上的信号并可作模块显示以外的其他工作,也可不断地查询应答线BUSY是否为低(BUSY=0?
),如果BUSY=0,表明模块对用户的写操作已经执行完毕。
可以再送下一个数据。
液晶显示器显示8X8ASCII字符命令:
格式:
F1XXYYAS
该命令为4字节命令(最大执行时间为0.8毫秒,Ts2=0.8mS),其中
XX:
为以ASCII码为单位的屏幕行坐标值,取值范围00到0F、04到13、00到13;
YY:
为以ASCII码为单位的屏幕列坐标值,取值范围00到1F、00到3F、00到4F;
AS:
坐标位置上要显示的ASCII字符码。
OCMJ液晶控制时序图如图2所示:
3.3、各模块功能描述
说明书要求:
图2OCMJ液晶控制时序图
3.3、各模块功能描述
总原理图如图3所示:
图3总原理图
模块一:
分频模块
图4分频模块符号
利用VHDL语言生成的分频符号如图4所示,clk和rst分别是输入的时钟信号引脚和复位引脚,clkout是分频后的时钟输出引脚。
本模块使用13位计数常量分频,可以将试验箱上1.25MHZ的时钟频率降到150HZ左右,这足以驱动液晶工作。
代码如下:
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
useieee.std_logic_arith.all;
entityfenpinis
port(clk,rst:
instd_logic;
clkout:
outstd_logic
);
endfenpin;
architecturefenpin_behaveoffenpinis
signalinclk:
std_logic_vector(12downto0);
signalinner:
std_logic;
begin
process(clk,rst)
begin
ifrst='0'then
inclk<="0000000000000";
inner<='0';
elsifclk'eventandclk='1'then--每来一个上升沿,inclk加一
ifinclk="1111111111111"then
inner<=notinner;--当inclk加满的时候,inner取反
inclk<=inclk+1;
else
inclk<=inclk+1;
endif;
endif;
endprocess;
clkout<=inner;
endfenpin_behave;
模块二:
消抖模块
图5消抖模块符号
利用VHDL语言生成的按键消抖模块符号如图5所示,clk和rst分别是时钟信号引脚和复位引脚,din是按键的输入信号,直接连接在试验箱的按键上,dout是经过消抖处理后的输出引脚。
本模块采用状态机实现,共八个状态,当din信号为低的时候,状态机才会向下传递状态,否则重新回到状态0,也就是说当有按键按下的时候,需要低电平信号持续八个时钟周期,才能算是一个信号输入。
由于本系统的时钟频率是150HZ,经过计算,每次按键必须持续大约50ms才算有效,如果din信号持续为低电平,那么输出端每隔约50ms,输出一个低脉冲。
代码如下:
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entitykey_xdis
port
(clk,rst,din:
instd_logic;
dout:
outstd_logic
);
endentity;
architecturertlofkey_xdis
typexd_stateis(s0,s1,s2,s3,s4,s5,s6,s7);
signalpre_s,next_s:
xd_state;
begin
pcs0:
process(rst,clk)
begin
ifrst='0'then
pre_s<=s0;
elsifclk'eventandclk='1'then--每次时钟来临,把next_s给pre_s
pre_s<=next_s;
else
null;
endif;
endprocesspcs0;
pcs1:
process(pre_s,next_s,din)
begin
casepre_sis
whens0=>
dout<='1';--dout置高,确保到不为低电平
ifdin='1'then
next_s<=s0;--如果din=1,那么返回起始状态
else
next_s<=s1;--如果din=0,那么进入下一个状态
endif;
whens1=>--状态s1到s6同上
dout<='1';
ifdin='1'then
next_s<=s0;
else
next_s<=s2;
endif;
whens2=>
dout<='1';
ifdin='1'then
next_s<=s0;
else
next_s<=s3;
endif;
whens3=>
dout<='1';
ifdin='1'then
next_s<=s0;
else
next_s<=s4;
endif;
whens4=>
dout<='1';
ifdin='1'then
next_s<=s0;
else
next_s<=s5;
endif;
whens5=>
dout<='1';
ifdin='1'then
next_s<=s0;
else
next_s<=s6;
endif;
whens6=>
dout<='1';
ifdin='1'then
next_s<=s0;
else
next_s<=s7;
endif;
whens7=>
dout<='0';
ifdin='1'then--若din=1,回到起始状态
next_s<=s0;
Else--若din=0,回到s1状态,进入循环
next_s<=s1;
endif;
endcase;
endprocesspcs1;
endrtl;
模块三:
计数模块
图6计数模块符号
利用VHDL语言生成的计数模块符号如图6所示,key和rst分别是按键输入引脚和复位引脚,dout是计数结果输出引脚。
本模块采用基本的计数原理,即每当key来一个上升沿,做为缓冲的内部四位二进制信号inclk自增一,最后将inclk给到dout。
代码如下:
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
useieee.std_logic_arith.all;
entitycntis
port(key,rst:
instd_logic;
dout:
outstd_logic_vector(3downto0)
);
endcnt;
architecturecnt_behaveofcntis
signalinclk:
std_logic_vector(3downto0);
begin
process(key,rst)
begin
ifrst='0'then
inclk<="0000";
elsifkey'eventandkey='0'then--每次来一个下降沿,inclk加一
inclk<=inclk+1;
endif;
endprocess;
dout<=inclk;
endcnt_behave;
模块四:
译码及显示模块
图7译码及显示模块符号
利用VHDL语言生成的译码及显示模块符号如图7所示,clk和rst分别是时钟输入引脚和复位引脚,busy是来自液晶的握手信号,din是需要显示的十六进制数据,req是向液晶发出的握手信号,dout是向液晶发出要显示的数据的信息的引脚。
本模块采用状态机来实现,严格按照液晶的时序图经过判断busy信号不为高的情况下向液晶依次输出ASCII码命令字,行坐标,列坐标以及经过译码得到的ASCII码,然后再从req输出一个高脉冲。
从而驱动液晶屏幕工作。
代码如下:
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
useieee.std_logic_arith.all;
entitydisplyis--实体说明
port(clk,busy,rst:
instd_logic;
din:
instd_logic_vector(3downto0);
req:
outstd_logic;
dout:
outstd_logic_vector(7downto0)
);
enddisply;
architecturedisply_archofdisplyis
typeztstateis
(st0,st1,st2,st3,st4,st5,st6,st7,st8,st9,st10,st11,st12,st13,st14);
signalstate:
ztstate;
Begin--结构体说明
process(rst,clk)
begin
ifrst='0'then--复位信号
req<='0';
state<=st0;
dout<="ZZZZZZZZ";
elsifclk'eventandclk='1'then
casestateis
whenst0=>
dout<="11110100";--清屏命令字
req<='0';
state<=st1;
whenst1=>--req输出一个高脉冲
req<='1';
state<=st2;
whenst2=>
req<='0';
state<=st3;
whenst3=>
ifbusy='0'then
dout<="11110001";--写ASCII命令字
req<='0';
state<=st4;
else
state<=st3;
endif;
whenst4=>
req<='1';
state<=st5;
whenst5=>
req<='0';
state<=st6;
whenst6=>--写列坐标
ifbusy='1'then
state<=st6;
else
dout<="00001111";
req<='0';
state<=st7;
endif;
whenst7=>
req<='1';
state<=st8;
whenst8=>
req<='0';
state<=st9;
whenst9=>--写行坐标
ifbusy='1'then
state<=st9;
else
dout<="00000001";
req<='0';
state<=st10;
endif;
whenst10=>
req<='1';
state<=st11;
whenst11=>
req<='0';
state<=st12;
whenst12=>
ifbusy='1'then
state<=st12;
else
casedinis--根据输入写ASCII码
when"0000"=>
dout<="00110000";
when"0001"=>
dout<="00110001";
when"0010"=>
dout<="00110010";
when"0011"=>
dout<="00110011";
when"0100"=>
dout<="00110100";
when"0101"=>
dout<="00110101";
when"0110"=>
dout<="00110110";
when"0111"=>
dout<="00110111";
when"1000"=>
dout<="00111000";
when"1001"=>
dout<="00111001";
when"1010"=>
dout<="01000001";
when"1011"=>
dout<="01000010";
when"1100"=>
dout<="01000011";
when"1101"=>
dout<="01000100";
when"1110"=>
dout<="01000101";
when"1111"=>
dout<="01000110";
whenothers=>
dout<="00000000";
endcase;
req<='0';
state<=st13;
endif;
whenst13=>
req<='1';
state<=st14;
whenst14=>
req<='0';
state<=st3;
whenothers=>
state<=st0;
endcase;
endif;
endprocess;
enddisply_arch;
3.4、仿真结果
1.分频器仿真如图8所示:
图8分频器功能仿真波形图
2.消抖模块仿真如图9所示:
图9消抖模块功能仿真波形图
说明:
通过仿真可以看出,当按键时间适当的时候,dout端出现了一个低脉冲,而当按键时间过短的时候,此时din输入的低脉冲被当作毛刺,而持续按键的时候,dout会出现连续规律的低脉冲。
这种消抖方式比较符合实际需要。
3.计数模块仿真如图10所示:
图10计数模块功能仿真波形图
4.译码及显示模块仿真如图11所示:
图11译码及显示模块功能仿真波形图
说明:
通过仿真波形图可以看出,如果假设busy一直为低,那么当din输入0010即2的时候,输出端依次输出F1(ASCII码命令字)、0F(行坐标)、01(列坐标)、和32(2的ASCII码),同时在每次输出的时候还在req给出一个高脉冲。
因此,此程序是可行的。
5.总体仿真如图12所示:
图12总体仿真波形图
3.5、实验箱验证情况
试验箱验证情况如图13所示:
图13试验箱验证图
4、课程设计总结
通过本次课程设计,我熟练的掌握了使用QuartusII软件进行可编程逻辑器件的开发流程,我巩固了对VHDL语法和基本语句的掌握,并且真正学会了分析任务,发现问题,分析问题,解决问题的能力。
此外,我还意识到和同学相互交流的重要性,只有通过不断的和别人的交流,才能逐渐的发现别人的某些想法的先进性,为己所用。
然而,通过这次课程设计我也发现的不少问题,对于自身而言,在调试程序的过程中在遇到难以解决的问题时,总是缺乏耐心,容易急躁;对于基础的东西,总是不屑于去学,最后也总是在这方面栽跟头;另外一点要提出的是实验室里的试验箱大部分液晶不可用,而且缺少说明书,这导致大家在课设过程中遇到很大的问题。
5、参考文献
(1)侯伯亨,顾新.VHDL硬件描述语言与数字逻辑电路设计.西安:
西安电子科技大学出版社,1999
(2)求是科技.CPLD/FPGA应用开发技术与工程实践.北京:
人民邮电出版社,2005
(3)罗苑棠.CPLD/FPGA常用模块与综合系统设计实例精讲.北京:
电子工业出版社,2007
(4)任勇峰,庄新敏.VHDL与硬件实现速成.北京:
国防工业出版社,2005