基于FPGA的液晶数字钟程序.docx
《基于FPGA的液晶数字钟程序.docx》由会员分享,可在线阅读,更多相关《基于FPGA的液晶数字钟程序.docx(11页珍藏版)》请在冰豆网上搜索。
![基于FPGA的液晶数字钟程序.docx](https://file1.bdocx.com/fileroot1/2022-10/4/6ada1a46-0439-41ea-abd3-617b319f744b/6ada1a46-0439-41ea-abd3-617b319f744b1.gif)
`timescale1ns/1ps
//////////////////////////////////////////////////////////////////////////////////
//Company:
//Engineer:
//
//CreateDate:
21:
00:
2506/13/2011
//DesignName:
//ModuleName:
lcd1602shizhong
//ProjectName:
//TargetDevices:
//Toolversions:
//Description:
//
//Dependencies:
//
//Revision:
//Revision0.01-FileCreated
//AdditionalComments:
//
/////////////////////////////////////////////////////////////////////
modulelcd1602shizhong(
inputclk,
//inputCLOCK_50,//板载时钟50MHz
inputrst,//板载按键RST
//LCD1602Interface
output[7:
0]LCD1602_DATA,//LCD1602数据总线
outputLCD1602_E,//LCD1602使能
outputLCD1602_RS,//LCD1602指令数据选择
outputLCD1602_RW,//LCD1602读写选择
inputsw1,sw2,sw3,sw4,
outputled
);
//0~(8*16-1)=128
//16bits->0123456789ABCDEF<-
wire[127:
0]row1_val="theFPGAclock";
//wire[127:
0]row2_val="Amy-studioPub";
wire[3:
0]second_L,second_H;
wire[3:
0]miniute_L,miniute_H;
wire[3:
0]hour_L,hour_H;
wire[3:
0]sw_code;
////////////////////例化LCD1602驱动//////////////////////
lcd1602_driveu0(
.clk(clk),
.rst(rst),
//LCD1602InputValue
.row1_val(row1_val),
//.row2_val(row2_val),
.second_L(second_L),
.second_H(second_H),
.miniute_L(miniute_L),
.miniute_H(miniute_H),
.hour_L(hour_L),
.hour_H(hour_H),
//LCD1602Interface
.lcd_data(LCD1602_DATA),
.lcd_e(LCD1602_E),
.lcd_rs(LCD1602_RS),
.lcd_rw(LCD1602_RW)
);
////////////////////时钟例化//////////////////////
watchwatch(
.clk(clk),
.rst(rst),
.sw_code(sw_code),
.second_L(second_L),
.second_H(second_H),
.miniute_L(miniute_L),
.miniute_H(miniute_H),
.hour_L(hour_L),
.hour_H(hour_H),
.led(led)
);
///////////////按键例化/////////////////////////
keykey(
.clk(clk),
.rst(rst),
.sw1(sw1),
.sw2(sw2),
.sw3(sw3),
.sw4(sw4),
.sw_code(sw_code)
);
endmodule
//////////////////lcd1602驱动模块////////////////////////
modulelcd1602_drive(
inputclk,//50MHz时钟
inputrst,//复位信号
//LCD1602InputValue
input[127:
0]row1_val,//第一行字符
//input[127:
0]row2_val,//第二行字符
input[3:
0]second_L,
input[3:
0]second_H,
input[3:
0]miniute_L,
input[3:
0]miniute_H,
input[3:
0]hour_L,
input[3:
0]hour_H,
//LCD1602Interface
outputreg[7:
0]lcd_data,//数据总线
outputlcd_e,//使能信号
outputreglcd_rs,//指令、数据选择
outputlcd_rw//读、写选择
);
//+++++++++++++++++++++++++++++++++++++
//分频模块开始
//+++++++++++++++++++++++++++++++++++++
reg[15:
0]cnt;//计数子
reg[7:
0]date[9:
0];
initial
begin
date[0]="0";
date[1]="1";
date[2]="2";
date[3]="3";
date[4]="4";
date[5]="5";
date[6]="6";
date[7]="7";
date[8]="8";
date[9]="9";
end
always@(posedgeclk,negedgerst)
if(!
rst)
cnt<=0;
else
cnt<=cnt+1'b1;
//500Khz~1MHz皆可
wirelcd_clk=cnt[15];//(2^16/50M)=1.31ms
//-------------------------------------
//分频模块结束
//-------------------------------------
//+++++++++++++++++++++++++++++++++++++
//LCD1602驱动模块开始
//+++++++++++++++++++++++++++++++++++++
//格雷码编码共40个状态
parameterIDLE=8'h00;
//写指令初始化
parameterDISP_SET=8'h01;//显示模式设置
parameterDISP_OFF=8'h03;//显示关闭
parameterCLR_SCR=8'h02;//显示清屏
parameterCURSOR_SET1=8'h06;//显示光标移动设置
parameterCURSOR_SET2=8'h07;//显示开及光标设置
//显示第一行
parameterROW1_ADDR=8'h05;//写第1行起始地址
parameterROW1_0=8'h04;
parameterROW1_1=8'h0C;
parameterROW1_2=8'h0D;
parameterROW1_3=8'h0F;
parameterROW1_4=8'h0E;
parameterROW1_5=8'h0A;
parameterROW1_6=8'h0B;
parameterROW1_7=8'h09;
parameterROW1_8=8'h08;
parameterROW1_9=8'h18;
parameterROW1_A=8'h19;
parameterROW1_B=8'h1B;
parameterROW1_C=8'h1A;
parameterROW1_D=8'h1E;
parameterROW1_E=8'h1F;
parameterROW1_F=8'h1D;
//显示第二行
parameterROW2_ADDR=8'h1C;//写第2行起始地址
parameterROW2_0=8'h14;
parameterROW2_1=8'h15;
parameterROW2_2=8'h17;
parameterROW2_3=8'h16;
parameterROW2_4=8'h12;
parameterROW2_5=8'h13;
parameterROW2_6=8'h11;
parameterROW2_7=8'h10;
parameterROW2_8=8'h30;
parameterROW2_9=8'h31;
parameterROW2_A=8'h33;
parameterROW2_B=8'h32;
parameterROW2_C=8'h36;
parameterROW2_D=8'h37;
parameterROW2_E=8'h35;
parameterROW2_F=8'h34;
reg[5:
0]current_state,next_state;//现态、次态
//FSM:
always1
always@(posedgelcd_clk,negedgerst)
if(!
rst)current_state<=IDLE;
elsecurrent_state<=next_state;
//FSM:
always2
always
begin
case(current_state)
IDLE:
next_state=DISP_SET;
//写指令初始化
DISP_SET:
next_state=DISP_OFF;
DISP_OFF:
next_state=CLR_SCR;
CLR_SCR:
next_state=CURSOR_SET1;
CURSOR_SET1:
next_state=CURSOR_SET2;
CURSOR_SET2:
next_state=ROW1_ADDR;
//显示第一行
ROW1_ADDR:
next_state=ROW1_0;
ROW1_0:
next_state=ROW1_1;
ROW1_1:
next_state=ROW1_2;
ROW1_2:
next_state=ROW1_3;
ROW1_3:
next_state=ROW1_4;
ROW1_4:
next_state=ROW1_5;
ROW1_5:
next_state=ROW1_6;
ROW1_6:
next_state=ROW1_7;
ROW1_7:
next_sta