《基于FPGA的数字系统设计》课件第5章_第1页
《基于FPGA的数字系统设计》课件第5章_第2页
《基于FPGA的数字系统设计》课件第5章_第3页
《基于FPGA的数字系统设计》课件第5章_第4页
《基于FPGA的数字系统设计》课件第5章_第5页
已阅读5页,还剩263页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

5.1控制发光二极管循环发光

5.2旋转开关控制发光二极管轮流发光

5.3控制液晶显示屏显示字符

5.4电子数字钟

5.5运动计时器

5.6液晶显示屏显示PS/2键盘的键值

5.7通过RS-232异步串行通信接口

实现FPGA与计算机的通信

第5章设计实例

5.1控制发光二极管循环发光

实验开发板有8个并排放置的发光二极管LED7~LED0,其中1个发光二极管发光,其它7个发光二极管都处于截止状态。发光二极管的导通顺序按照向左或向右两个方向移动,并且通过拨动开关SW0(L13)控制发光二极管循环发光移动的方向,如图5-1所示。图5-1控制发光二极管循环发光实现控制发光二极管循环发光的电路的输入和输出端口信号如图5-2所示。

图5-2中,clk、reset和dir_r_l分别是50 MHz时钟、复位和拨动开关的输入信号。led为控制8个发光二极管发光的控制信号,FPGA控制发光二极管的导通和截止,输出高电平时对应发光二极管有电流流过而发光。实验开发板上的BTNSOUTH(K17)为复位按键,高电平有效,复位按键按下时,8个发光二极管中的LED0发光。图5-2输入和输出端口信号由于输入时钟信号的频率为50 MHz,为了能够观察到发光的发光二极管循环移动方向,将频率为50 MHz的输入时钟信号分频,得到一秒的信号new_second,不过该一秒信号脉冲的占空比不是1∶1的方波,其高电平的脉冲宽度等于50MHz时钟信号的一个周期,该信号控制发光的发光二极管循环移动的速度。程序如下:

moduleled_shift(clk,reset,dir_r_l,led);

inputclk;

inputreset;

inputdir_r_l;

output[7:0]led;

reg[7:0]led;

reg[27:0]cnt; //计数分频器

always@(posedgeclkorposedgereset)

begin

if(reset)

begin

cnt<=28'd0;

end

else

begin

if(cnt==28'd49999999)

begin

cnt<=28'd0;

end

else

begin

cnt<=cnt+1;

end

end

end

regnew_second; //得到1秒信号

always@(posedgeclkorposedgereset)

begin

if(reset)

new_second<=1'b0;

else

begin

if(cnt==28‘d49999999)

new_second<=1'b1; //只有计数到第49999999个脉冲时,

//秒信号脉冲才为高电平,在其它时

//间为低电平

elseif(new_second)

new_second<=1'b0;

end

endalways@(posedgeclk)

begin

if(reset)

led<=8'b0000001;

else

if(new_second)

begin

if(dir_r_l==1)

begin

led<={led[0],led[7:1]};//向右移动

end

else

begin

led<={led[6:0],led[7]};//向左移动

end

end

end

endmodule下面是程序使用到的信号和对应的管脚以及电平标准等参数的选择:

NET"clk" LOC="C9"|IOSTANDARD=LVTTL;

NET"reset" LOC="K17"|IOSTANDARD=LVTTL|pulldown|DRIVE=2;

NET"dir_r_l" LOC="L13"|IOSTANDARD=LVTTL|pullup|DRIVE=2;

NET"led<0>"LOC="F12"|IOSTANDARD=LVTTL|SLEW=SLOW|DRIVE=4;

NET"led<1>"LOC="E12"|IOSTANDARD=LVTTL|SLEW=SLOW|DRIVE=4;

NET"led<2>"LOC="E11"|IOSTANDARD=LVTTL|SLEW=SLOW|DRIVE=4;NET"led<3>"LOC="F11"|IOSTANDARD=LVTTL|SLEW=SLOW|DRIVE=4;

NET"led<4>"LOC="C11"|IOSTANDARD=LVTTL|SLEW=SLOW|DRIVE=4;

NET"led<5>"LOC="D11"|IOSTANDARD=LVTTL|SLEW=SLOW|DRIVE=4;

NET"led<6>"LOC="E9"|IOSTANDARD=LVTTL|SLEW=SLOW|DRIVE=4;

NET"led<7>"LOC="F9"|IOSTANDARD=LVTTL|SLEW=SLOW|DRIVE=4;5.2旋转开关控制发光二极管轮流发光

利用Spartan-3E实验开发板上的旋转开关和8个并排的发光二极管,设计一个旋转开关控制8个发光二极管循环发光及移位方向的电路。Spartan-3E实验开发板上的FPGA芯片型号为XC3S500E-4FG320C,FPGA芯片接收反映旋转开关旋转方向的两个开关A和B信号和FPGA芯片输出信号,控制实验开发板上的8个发光二极管的导通和截止。由于旋转开关的开关A和开关B的一个触点接地,另外两个分别接FPGA的I/O管脚,因此应该定义FPGA的I/O管脚为带有上拉电阻的输入管脚。

FPGA实现旋转开关控制8个发光二极管循环发光及移位方向的电路的输入和输出端口信号如图5-3所示。其中clk、reset、R_A和R_B分别是50MHz时钟、复位和旋转开关的输入信号,LED_DATA为控制8个发光二极管发光的控制信号。

要求在8个发光二极管中只有一个发光二极管导通,而旋转开关控制实验开发板上的8个发光二极管中的一个导通的发光二极管的移位方向。当旋转开关顺时针方向旋转时,导通发光二极管向右移动;当旋转开关逆时针方向旋转时,导通发光二极管向左移动,如图5-4所示。图5-3输入和输出端口信号图5-4旋转开关控制发光二极管的移位方向当旋转开关输出的开关B信号为高电平和开关A信号变为高电平时,表示旋转开关逆时针旋转;当旋转开关输出的开关B信号为低电平和开关A信号变为高电平时,表示旋转开关顺时针旋转,如图5-5所示。

任何机械触点接触时都存在抖动现象,抖动现象有可能导致错误判断旋转开关的旋转方向,如图5-6所示。

为了正确地获取旋转开关的旋转方向,必须加入消除机械触点接触时产生抖动的措施。对于带有两个开关A和B输出的旋转开关,检测第一个发生变化的开关信号,需要忽略紧接着后面的抖动信号,直到另外一个开关信号发生变化。图5-5旋转开关的输出波形

图5-6旋转开关的机械触点接触时存在的抖动现象例如,开关A信号经过消除抖动后的信号为rotary_q1,开关B信号经过消除抖动后的信号为rotary_q2。当检测到开关A信号由低电平变化到高电平时,rotary_q1信号先不发生变化,并且忽略紧接着后面的抖动信号,直到检测到开关B信号由低电平变化到高电平时,rotary_q1才由低电平变化到高电平,从而消除了开关A信号的抖动信号;检测到开关A信号由高电平变化到低电平时,rotary_q1信号先不发生变化,直到检测到开关B信号由高电平变化到低电平时,才由高电平变化到低电平,如图5-7所示。图中的rotary_q1信号波形中的细线表示保持当前状态不变。只有当开关A信号和开关B信号均为高电平时,rotary_q1才为高电平;当开关A信号和开关B信号均为低电平时,rotary_q1才为低电平,在其它情况下,rotary_q1的状态保持不变。同理,经过相同的方法可消除开关B信号的抖动信号。当检测到开关B信号由低电平变化到高电平时,rotary_q2信号先不发生变化,并且忽略紧接着后面的抖动信号,直到检测到开关A信号由高电平变化到低电平时,rotary_q2才由低电平变化到高电平,从而消除了开关B信号的抖动信号;当检测到开关B信号由高电平变化到低电平时,rotary_q2信号先不发生变化,直到检测到开关A信号由低电平变化到高电平时,才由高电平变化到低电平,如图5-7所示。只有当开关A信号为低电平和开关B信号为高电平时,rotary_q2才为高电平;当开关A信号为高电平和开关B信号为低电平时,rotary_q2才为低电平,在其它情况下,rotary_q2的状态保持不变。旋转开关逆时针旋转和顺时针旋转时的信号波形如图5-8所示。信号rotary_q1由低电平变为高电平时,如果rotary_q2为低电平,就表示顺时针旋转;如果rotary_q2为高电平,则表示逆时针旋转。

利用信号rotary_q1作为判断旋转开关旋转事件发生的信号,当rotary_q1由低电平变成高电平时,旋转开关旋转事件发生的信号rotary_event=“1”;当rotary_q1由低电平变成高电平时,根据信号rotary_q2判断旋转开关的旋转方向,旋转开关旋转方向信号rotary_left=“1”时,表示旋转开关逆时针旋转;rotary_left=“0”时,表示旋转开关顺时针旋转。图5-7消除旋转开关的机械触点接触时存在的抖动现象图5-8旋转开关逆时针旋转和顺时针旋转时的信号产生判断旋转事件发生信号rotary_event和旋转方向信号rotary_left的电路如图5-9所示。

用Verilog-HDL语言描述实现旋转开关控制发光二极管循环移位的程序如下:

modulerotary_led(clk,reset,R_A,R_B,LED_DATA);

//输入信号

inputclk; //50MHz的时钟信号

inputreset; /复位信号,高电平有效

inputR_A; //旋转开关A

inputR_B; //旋转开关B//输出信号

output[7:0]LED_DATA; //8个LED发光二极管

//引入一些内部信号

reg[7:0]shift_d; //控制8个LED发光二极管的8个移位寄存器

regrotary_q1,rotary_q2; //消除抖动后的开关信号

regrotary_q1_d; //保存前一时刻的rotary_q1信号

regrotary_event; //判断旋转开关旋转事件发生的信号

regrotary_left; //旋转开关的旋转方向

reg[3:0]clk_cnt; //计数器信号

regR_A_d,R_B_d; //保存开关A和B信号wire[7:0]LED_DATA;

wirerotary_press_in=1'b0;

//对50MHz时钟信号进行分频,获得低频时钟信号

always@(posedgeclkorposedgereset)

if(reset)

clk_cnt<=4'b0;

else

clk_cnt<=clk_cnt+1; //产生分频后的时钟信号clk_cnt[3]

//对旋转开关的开关A信号和开关B信号进行采集和锁存

always@(posedgeclk_cnt[3]orposedgereset)

if(reset)begin

R_A_d<=1'b0;

R_B_d<=1'b0;

end

elsebegin

R_A_d<=R_A;//锁存旋转开关的开关A信号和开关B信号

R_B_d<=R_B;

end

//对开关A信号进行滤波,得到消除抖动后的信号rotary_q1

always@(posedgeclkorposedgereset)

if(reset)

rotary_q1<=1'b0;

elseif(R_A_d&&R_B_d)

rotary_q1<=1'b1;

elseif(!(R_A_d||R_B_d))

rotary_q1<=1'b0;

//对开关B信号进行滤波,得到消除抖动后的信号rotary_q2

always@(posedgeclkorposedgereset)

if(reset)

rotary_q2<=1'b0;

elseif(!R_A_d&&R_B_d)

rotary_q2<=1'b1;

elseif(R_A_d&&!R_B_d)

rotary_q2<=1'b0;//保存前一时刻的rotary_q1信号

always@(posedgeclkorposedgereset)

if(reset)

rotary_q1_d<=1'b0;

else

rotary_q1_d<=rotary_q1;

//确认旋转事件是否发生,当信号rotary_event=“1”时,表示旋转事件发生

always@(posedgeclkorposedgereset)

if(reset)

rotary_event<=1'b0;

else

rotary_event<=!rotary_q1_d&&rotary_q1;/*确定旋转方向,当rotary_left=“1”时,表示逆时针旋转,rotary_left=“0”时,表示顺时针旋转*/

always@(posedgeclkorposedgereset)

if(reset)

rotary_left<=1'b0;

elseif(!rotary_q1_d&&rotary_q1)

rotary_left<=rotary_q2;

//控制8个发光二极管导通和截止的8个移位寄存器

always@(posedgeclkorposedgereset)

if(reset) //当按下复位按键时,8个发光二极管中只有LED0导通

shift_d<=8'h01;

elseif(rotary_event)

shift_d<=rotary_left?{shift_d[6:0],shift_d[7]}:{shift_d[0],shift_d[7:1]};

/*如果检测到旋转开关旋转事件发生(rotary_event=“1”),则判断旋转方向(当rotary_left=“1”时,表示旋转开关逆时针(向左)旋转,8个发光二极管中的一个导通的发光二极管向左移动

//shift_d<={shift_d[6:0],shift_d[7]})*/

//控制8个发光二极管的输出信号LED_DATA,由旋转开关控制

assignLED_DATA={8{rotary_press_in}}^shift_d;

endmodule图5-9事件发生信号和旋转方向信号的产生电路下面是程序使用到的信号和对应的管脚以及电平标准等参数的选择:

NET"clk"LOC="C9"|IOSTANDARD=LVCMOS33;

NET"reset"LOC="V16"|IOSTANDARD=LVTTL|PULLDOWN;

NET"R_A"LOC="K18"|IOSTANDARD=LVTTL|PULLUP;

NET"R_B"LOC="G18"|IOSTANDARD=LVTTL|PULLUP;

NET"LED_DATA<7>"LOC="F12"|IOSTANDARD=LVTTL|SLEW=SLOW|DRIVE=8;

NET"LED_DATA<6>"LOC="E12"|IOSTANDARD=LVTTL|SLEW=SLOW|DRIVE=8;NET"LED_DATA<5>"LOC="E11"|IOSTANDARD=LVTTL|SLEW=SLOW|DRIVE=8;

NET"LED_DATA<4>"LOC="F11"|IOSTANDARD=LVTTL|SLEW=SLOW|DRIVE=8;

NET"LED_DATA<3>"LOC="C11"|IOSTANDARD=LVTTL|SLEW=SLOW|DRIVE=8;

NET"LED_DATA<2>"LOC="D11"|IOSTANDARD=LVTTL|SLEW=SLOW|DRIVE=8;

NET"LED_DATA<1>"LOC="E9"|IOSTANDARD=LVTTL|SLEW=SLOW|DRIVE=8;

NET"LED_DATA<0>"LOC="F9"|IOSTANDARD=LVTTL|SLEW=SLOW|DRIVE=8;

5.3控制液晶显示屏显示字符

实验开发板上设置了一个2行16字符液晶显示屏LCD,液晶显示屏包含一个SitronixST7066U图形控制芯片,为了节约FPGA芯片的I/O管脚资源,尽可能少占用FPGA芯片的管脚,采用与StrataFlash存储器芯片共享FPGA的I/O管脚的方法,FPGA芯片仅通过4位数据信号线和3位控制信号线与LCD控制芯片进行通信。向液晶显示屏传输数据时,分两次输入到LCD控制芯片中,高4位先送,低4位后送。

用Verilog-HDL语言描述一个控制液晶显示屏显示字符“OK!”的电路。

FPGA实现控制液晶显示屏显示字符“OK!”的电路的输入和输出端口信号如图5-10所示。其中,clk、reset分别是50MHz时钟和复位输入信号,reset高电平有效。lcd_rs、lcd_rw、lcd_e和lcd_d分别为与液晶显示屏控制芯片连接的控制信号。lcd_rs为寄存器选择控制输出信号,当lcd_rs为低电平时,表示数据总线传输的是命令控制信号,当lcd_rs为高电平时,表示数据总线传输的是数据信号;lcd_rw为读/写控制输出信号,当lcd_rw为低电平时,表示向液晶显示屏控制芯片写数据,反之,为读取数据;lcd_e为读/写操作允许控制脉冲输出信号,高电平有效;

lcd_d为数据信号,由于在设计控制液晶显示屏显示字符时,严格按照液晶显示屏控制芯片的时序设计,留给液晶显示屏控制芯片完成所有操作的时间,因此不需要读取液晶显示屏控制芯片是否处于忙的状态,相对FPGA来说,4位lcd_d数据总线设置为单向输出信号。flash_ce为StrataFlash存储器芯片的使能控制信号,低电平有效,由于lcd_d数据信号分别与StrataFlash存储器芯片的数据信号SF_D<9>~SF_D<11>连接在一起,因此在控制液晶显示屏显示字符的设计中,该信号设置为高电平,不允许StrataFlash存储器芯片占用数据总线。图5-10输入和输出端口信号设置为高电平,不允许StrataFlash存储器芯片占用数据总线。

图5-10输入和输出端口信号上电后,必须传送给液晶显示屏控制芯片初始化命令,初始化完成后,还要传输指定地址计数器地址和显示字符的编码数据。接通电源后,FPGA向液晶显示屏控制芯片发送指令的流程如图5-11所示。

根据上述流程图,可以采用状态机实现对液晶显示屏控制芯片的控制。由于执行不同的操作过程,需要的时间也不一样,因此采用计数器和状态机配合的方式。为每个状态设置不同的时间(也就是延迟计数值的不同),计数器与状态设置不同延迟计数值相比较,并且给状态机发出计数时间到的信号,通知状态机转换到下一个状态,直到所有的数据传送完毕后,再循环向液晶显示屏控制芯片发送显示字符编码数据。图5-11FPGA向液晶显示屏控制芯片发送指令的流程图

向液晶显示屏控制芯片发送指令或数据的时序如图5-12所示,每次发送数据需要满足:①数据超前使能信号lcd_e的时间大于40ns;②使能信号lcd_e保持高电平的时间大于230ns;③使能信号lcd_e无效后,经过大于10ns时间,有效数据信号才能改变为其它数据信号。

根据上述时序,传送一次数据可以分三个状态:第一个状态先建立数据,等待时间大于40ns;第二个状态将使能信号lcd_e变成高电平,等待时间大于230ns;第三个状态将使能信号lcd_e变成低电平,等待大于1μs(对应8位数据分两次传输,两个4位传输之间的间隔)或40μs(对应完成一个8位数据传输,与下一次数据传输之间的间隔)时间后,有效数据信号才能改变为其它数据信号。图5-12数据传输时序

例如,传送命令“0010”到液晶显示屏控制芯片,则在第一个状态时,设置定时计数值为4(大于40ns);lcd_rs设置为1'b0,表示传输的是命令控制字;4位数据总线信号lcd_d为4'h2;使能信号lcd_e仍然为低电平。转换到第二个状态时,设置定时计数值为12(大于230ns);使能信号lcd_e变成高电平。转换到第三个状态时,设置定时计数值为80(大于1μs)或2000(等于40μs);使能信号lcd_e变成低电平。该状态机的敏感信号为state_change,信号state_change由定时计数器模块提供,这一段传送命令“0010”的状态及代码如下:

state1:begin

state<=state2;

num_count<=20'd4;

lcd_rs<=1'b0;

cd_e<=1'b0;

lcd_d<=4'h2;

end

state2:begin

state<=state3;

num_count<=20'd12;

lcd_e<=1'b1;

end

state3:begin

state<=state4;

num_count<=20'd4000;

lcd_e<=1'b0;

end

描述控制液晶显示屏显示字符“OK!”的电路,采用计数器和状态机配合的方式。状态机根据计数器发出的转换状态控制信号转换到下一个状态;计数器根据状态下机在不同的状态下提供计数值,发出转换状态控制信号,如图5-13所示。图5-13两个模块的通信信号用Verilog-HDL语言描述实现液晶显示屏显示字符“OK!”的程序如下:

modulelcd_control(clk,reset,lcd_rs,lcd_rw,lcd_e,lcd_d,flash_ce);

inputclk;

inputreset;

outputlcd_rs;

outputlcd_rw;

outputlcd_e;

outputflash_ce;

output[3:0]lcd_d;

reglcd_rs,lcd_e;

reg[3:0]lcd_d;

/*StrataFlash存储器芯片的使能控制信号flash_ce信号设置为高电平,不允许StrataFlash存储器芯片占用数据总线*/

assignflash_ce=1;

//lcd_rw为读/写控制信号,由于只向液晶显示屏控制芯片写数据,lcd_rw设置为低电平

assignlcd_rw=0;

//定义用于定时的计数器信号

reg[19:0]delay_count;

reg[19:0]num_count;/*根据传送给液晶显示屏控制芯片初始化命令和指定地址计数器地址以及显示字符的编码数据的时序,定义若干状态*/

parameterstate1=6'b000001;

parameterstate2=6'b000010;

parameterstate3=6'b000011;

parameterstate4=6'b000100;

parameterstate5=6'b000101;

parameterstate6=6'b000110;

parameterstate7=6'b000111;

parameterstate8=6'b001000;

parameterstate9=6'b001001;parameterstate10=6'b001010;

parameterstate11=6'b001011;

parameterstate12=6'b001100;

parameterstate13=6'b001101;

parameterstate14=6'b001110;

parameterstate15=6'b001111;

parameterstate16=6'b010000;

parameterstate17=6'b010001;

parameterstate18=6'b010010;

parameterstate19=6'b010011;

parameterstate20=6'b010100;

parameterstate21=6'b010101;parameterstate22=6'b010110;

parameterstate23=6'b010111;

parameterstate24=6'b011000;

parameterstate25=6'b011001;

parameterstate26=6'b011010;

parameterstate27=6'b011011;

parameterstate28=6'b011100;

parameterstate29=6'b011101;

parameterstate30=6'b011110;

parameterstate31=6'b011111;

parameterstate32=6'b100000;

parameterstate33=6'b100001;

parameterstate34=6'b100010;

parameterstate35=6'b100011;

parameterstate36=6'b100100;

parameterstate37=6'b100101;

parameterstate38=6'b100110;

parameterstate39=6'b100111;

parameterstate40=6'b101000;

parameterstate41=6'b101001;

parameterstate42=6'b101010;

parameterstate43=6'b101011;

parameterstate44=6'b101100;

parameterstate45=6'b101101;

parameterstate46=6'b101110;parameterstate47=6'b101111;

parameterstate48=6'b110000;

parameterstate49=6'b110001;

parameterstate50=6'b110010;

parameterstate51=6'b110011;

parameterstate52=6'b110100;

parameterstate53=6'b110101;

reg[5:0]state; //状态信号

regstate_change; //改变状态信号/*计数定时器根据对液晶显示屏控制芯片进行初始化和传输数据的时序,以及各状态的停留时间,完成计数定时功能,输出改变状态信号*/

always@(posedgeclkorposedgereset)

if(reset)

begin

state_change<=1'b0;

delay_count<=1'b1;

end

else

if(delay_count==num_count-1)

begin

state_change<=1'b1;

delay_count<=1'b1;

end

else

begin

state_change<=1'b0;

delay_count<=delay_count+1'b1;

end

/*状态机根据对液晶显示屏控制芯片进行初始化和传输数据的时序,以及各状态的停留时间,设置下一个状态停留的时间常数,同时完成状态转移和输出液晶显示屏控制芯片的控制信号lcd_rs和lcd_e,数据信号lcd_d*/

always@(posedgestate_changeorposedgereset)

if(reset)

begin

state<=state1;

num_count<=20'd750000; //等待15ms,对应750000个时

//钟脉冲信号

endelse

case(state)

state1:begin

state<=state2;

num_count<=20'd4;//先传送控制命令,超前使能信号

//lcd_e的时间大于40ns

lcd_rs<=1'b0;

lcd_e<=1'b0;

lcd_d<=4'h3; //写入功能设置指令

end

state2:begin

state<=state3;

num_count<=20'd12; //保持使能信号lcd_e为高电平

//时间大于等于240ns

lcd_e<=1'b1;

end

state3: begin

state<=state4;

num_count<=20'd205000; //等待100μs

lcd_e<=1'b0;

end

state4: begin //重复写入功能设置指令

state<=state5;

num_count<=20'd4;

lcd_d<=4'h3;

end

state5: begin

state<=state6;

num_count<=20'd12;

lcd_e<=1'b1;

end

state6: begin

state<=state7;

num_count<=20'd5000;

lcd_e<=1'b0;

end

/*写入功能设置指令,采用4位数据总线传输,传输功能设置控制字中的DL=0,功能控制字为0x2*/

state7: begin

state<=state8;

num_count<=20'd4;

lcd_d<=4'h2;

end

state8: begin

state<=state9;

num_count<=20'd12;

lcd_e<=1'b1;

end

state9: begin

state<=state10;

num_count<=20'd4000;

lcd_e<=1'b0;

end/*传送功能设置命令控制字0x28,采用4位数据总线DB7~DB4,所以DL(对应数据DB4)=0,双行显示N(对应数据DB3)=1,5×7点阵F(对应数据DB2)=0*/

state10:begin

state<=state11;

num_count<=20'd4;

lcd_rs<=0;

lcd_d<=4'h2;

end

state11:begin

state<=state12;

num_count<=20'd12;

lcd_e<=1'b1;

end

state12: begin

state<=state13;

num_count<=20'd80;//两个四位数据之间的时间

//间隔大于1μs

lcd_e<=1'b0;

end

state13:begin

state<=state14;

num_count<=20'd4;

lcd_d<=4'h8;

end

state14:begin

state<=state15;

num_count<=20'd12;

lcd_e<=1'b1;

end

state15:begin

state<=state16;

num_count<=20'd4000;

lcd_e<=1'b0;

end/*输入模式控制字0x06,采用增量模式(地址计数器AC自动加1),数据位DB1(I/D)设置为1。

显示不移动,则DB0(S)设置为0*/

state16:begin

state<=state17;

num_count<=20'd4;

lcd_d<=4'h0;

end

state17:begin

state<=state18;

num_count<=20'd12;//50

lcd_e<=1'b1;

end

state18:begin

state<=state19;

num_count<=20'd80;

lcd_e<=1'b0;

end

state19:begin

state<=state20;

num_count<=20'd4;

lcd_d<=4'h6;

end

state20:begin

state<=state21;

num_count<=20'd12; //50

lcd_e<=1'b1;

end

state21:begin

state<=state22;

num_count<=20'd4000;

lcd_e<=1'b0;

end

/*输入打开显示控制字0x0C,打开显示,则D(对应DB2)设置为1,关光标显示和光标不闪烁,则C(对应DB1)和B(对应DB0)均设置为0*/

state22:begin

state<=state23;

num_count<=20'd4;

lcd_d<=4'h0;

end

state23:begin

state<=state24;

num_count<=20'd12; //50

lcd_e<=1'b1;

end

state24:begin

state<=state25;

num_count<=20'd80;

lcd_e<=1'b0;

end

state25:begin

state<=state26;

num_count<=20'd4;

lcd_d<=4'hc;

end

state26:begin

state<=state27;

num_count<=20'd12; //50

lcd_e<=1'b1;

end

state27:begin

state<=state28;

num_count<=20'd2000;

lcd_e<=1'b0;

end

state28:begin

state<=state29;

num_count<=20'd82000;//完成初始化命令后,等待时

//间大于等于1.64ms(对应

//82000个时钟脉冲)

end

/*输入DDRAM地址,其中DB7=1,DB6(A6)~DB0(A0)为DDRAM地址,第一行第一个字符的存储地址为0,所以输入DDRAM地址命令为0x80*/

state29: begin

state<=state30;

num_count<=20'd4;

lcd_rs<=1'b0;

lcd_e<=1'b0;

lcd_d<=4'h8;

end

state30:begin

state<=state31;

num_count<=20'd12;

lcd_e<=1'b1;

end

state31:begin

state<=state32;

num_count<=20'd80;

lcd_e<=1'b0;

end

state32:begin

state<=state33;

num_count<=20'd4;

lcd_d<=4'h0;

end

state33:begin

state<=state34;

num_count<=20'd12;

lcd_e<=1'b1;

end

state34:begin

state<=state35;

num_count<=20'd4000;

lcd_e<=1'b0;

end//传输字符"OK!"的字符编码,其中字符O的编码为0x4F

state35:begin

state<=state36;

num_count<=20'd4;

lcd_rs<=1'b1;//传输数据

lcd_d<=4'h4;

end

state36:begin

state<=state37;

num_count<=20'd12;

lcd_e<=1'b1;

end

state37:begin

state<=state38;

num_count<=20'd80;

lcd_e<=1'b0;

end

state38:begin

state<=state39;

num_count<=20'd4;

lcd_d<=4'hf;

end

state39:begin

state<=state40;

num_count<=20'd12;

lcd_e<=1'b1;

end

state40:begin

state<=state41;

num_count<=20'd2000;

lcd_e<=1'b0;

end//字符K的编码为0x4B

state41:begin

state<=state42;

num_count<=20'd4;

lcd_rs<=1'b1;

lcd_d<=4'h4;

end

state42:begin

state<=state43;

num_count<=20'd12;

lcd_e<=1'b1;

end

state43:begin

state<=state44;

num_count<=20'd80;

lcd_e<=1'b0;

end

state44:begin

state<=state45;

num_count<=20'd4;

lcd_d<=4'hb;

end

state45:begin

state<=state46;

num_count<=20'd12;

lcd_e<=1'b1;

end

state46:begin

state<=state47;

num_count<=20'd2000;

lcd_e<=1'b0;

end

//字符!的编码为0x21

state47:begin

state<=state48;

num_count<=20'd4;

lcd_rs<=1'b1;

lcd_d<=4'h2;

end

state48:begin

state<=state49;

num_count<=20'd12;

lcd_e<=1'b1;

end

state49:begin

state<=state50;

num_count<=20'd80;

lcd_e<=1'b0;

end

state50:begin

state<=state51;

num_count<=20'd4;

lcd_d<=4'h1;

end

state51:begin

state<=state52;

num_count<=20'd12;

lcd_e<=1'b1;

end

state52:begin

state<=state53;

num_count<=20'd4000;

lcd_e<=1'b0;

end

state53: begin

state<=state29;

num_count<=20'd800;

end

default: begin

state<=state1;

num_count<=20'd800;

end

endcase

endmodule

下面是程序使用到的信号和对应的管脚以及电平标准等参数的选择:

NET"clk"LOC="C9"|IOSTANDARD=LVTTL;

NET"reset"LOC

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论