华中科技大学
电子线路课程设计
题 目:智能洗衣机
院 系:控制科学与工程系
班 级:自动化100X班
姓 名:
:fanjunchao1991@
指导老师:
目录
一 题目分析。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。1
二 系统流程图.。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。2
三 主要模块介绍.。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。5
四 各按键功能.。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。6
五 仿真波形.。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。7
六 实验总结。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。8
七 附录。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。9
一:题目分析
本次课程设计要求以Verilog HDL硬件描述语言为基础,以DE2开发板为工具,编写智能洗衣机的模拟程序。
首先,我在熟悉题目要求的前提下,将题目要求划分为以下几个小的项目,每个项目尽量用单独的模块实现其功能:
① 洗衣过程的转换:控制洗衣过程在每个过程对应的状态机之间
转换,用control.v模块实现。
② 洗衣时间的显示:通过直接调用上学期编写的24小时智能时钟程序的计时模块,并用总时间减去已用时间得到剩余时间,用led_show.v实现。
本程序的特:
①led灯表示水位: 通过一定的算法,实现用led灯的亮灭表示水位。Led依次点亮表示注水过程,相反,表示排水和甩干过程。
②1602 LCD液晶屏: 用LCD显示所有操作步骤和过程,包括选择模式,当前洗衣模式和状态,洗衣完毕等。这些过程都是用LCD液晶屏具体显示。
③按键使用和去抖: 因为要使用按键进行模式的选择,所以我用软件去抖的方式实现按键按动时的去抖。
1
④暂停键模拟断电保护:设计了一个暂停键,模拟真实情况中的断电保护。当暂停时模拟现实中的断电;暂停结束模拟现实中的重新上电,程序从断点继续运行。
二:系统流程图
2
MODE 1 OR MODE 2 OR MODE 3:
Inject
(注水))
NO
是否已经洗过衣服?
YES
Wash
(洗衣)
Potch
(漂洗)
Drain
(排水)
Dry
(甩干)
洗衣完毕?
3
N
Y
MODE 4
4
Inject
(注水)
Potch
(漂洗)
Drain
(排水)
Dry
(甩干)
洗衣完毕?
N
Y
Wash over
MODE 5
流程图说明:第一个为总的控制系统的流程图,后面三个为总流程图中,每种模式的详细流程图。
Wash over
Dry
(甩干)
三:主要模块介绍
module my_start: 顶层模块,调用下层模块。
module HZ_1: 分频模块,通过10分频和5分频将50Mhz
分频成为1hz。
module control: 控制模块,控制洗衣模式状态机的转换。
module led_show: 倒计时模块,通过减去已用时间,得到剩余时间。
module put_bottom:软件去抖模块,通过软件去抖,检测按键按动情况。
module lcd_show: 1602液晶屏显示模块,包括驱动和需要显示的字符。
Module water_station:用led灯显示当前水位。
5
四:各按键功能
SW_0 :电源键,‘0’时表示power off(未开电源),‘1’表示洗衣机已经开机,处于工作状态,优先级最高。
SW_1 :暂停键,‘0’时表示正常工作,‘1’时表示暂停工作, 处于待机状态。
Key_2
Key_1
液晶屏
数码管
Led:
:确定键,按下表示模式选择确定,进入洗衣工作状态。
:模式选择键,洗衣机共有5种工作模式,用此键进行选择模式。
:显示洗衣机工作状态。
:显示洗衣机当前工作模式剩余时间和整个工作状态剩余时间。
Hex7,hex6:表示当前状态剩余分钟。
Hex5,hex4:表示剩余时间(秒)。
Hex1,hex0:表示整个状态剩余时间。
表示洗衣机水位状态,水位越高,led灯亮的越多。
6
五:仿真波形
说明:bot_1为模式选择按键,bot_2为确认按键,当57us按动确认键后,进入所选择的的mode 1。wsh_sty为当前洗衣状态,0代表注水,1代表洗衣(为了缩短仿真时间,我将洗衣时间改成一分钟),2代表排水,3代表甩干,4代表漂洗。可以看到,洗衣过程如下:0-1-2-3---0-4-2-3---0-4-2-3---wash over。符合要求,下载到开发板上以后也验证成功,mode 2和mode 3是类似状态,不再累述。
7
说明:这是mode 4的仿真图,wsh_sty中0代表注水,2代表排水,3代表甩干,4代表漂洗。可以看到,洗衣方式为0-4-2-3--0-4-2-3--wash over,符合题目要求。
实验总结
在去年多功能时钟的基础上,今年的课程设计让我学会了很多的新知识,也少走了很多弯路。
①模块化设计的思想:本次课程设计使用了很多去年设计多功能时钟的模块,编写可移植模块,对程序编写有莫大的好处。
②学习到很多小的注意事项:以前编写程序,从来不管warning,但是本次课设,本着严格要求的态度,我把所有warning8
都详细baidu和修改了一遍,最终将两百多个warning减少到了15个。通过修改warning,可以发现并改正很多不良习惯。
我的200多个警告里面大部分是因为无意识的疏忽造成的。比如,time_flag <= time_flag + 1;其中time_flag为11位寄存器型变量,编译时提示的警告为‘1’没有标明位数,被默认设置成为32位,所以改成 11'b1即可消除警告,这种重复性错误占有很大比例。
再比如,case语句没有养成加defaulet的习惯,我认为虽然运行时似乎对程序没有影响,但是遇到干扰或者时序混乱等情况时可能会出现问题。
还有比如,写代码时,在模块名后面的输入输出变量声明时多写了一个逗号等。
这些都提醒自己在写代码时不能投机取巧,尽管不会产生错误,但却可能造成以后写Verilog时习惯性疏忽。
但是也有一些警告需要我上网查才能知道是什么意思,比如quartus软件里可以自己设定时钟频率,比如为输入输出引脚分配电容等。
③ 体的构思和准备:我在写代码之前,构思了洗衣机的操作流程和可能遇到的问题,解决方案等。将准备工作做充足以后,写代码就会很快,遇到的错误也更少。
9
附录:(完整代码)
module my_start(
input key_0,key_1,
input cp_50,
input bot_1,bot_2,
output LCD_EN,
output LCD_RS,
output LCD_RW,
output LCD_ON,
output LCD_BLON,
output[7:0] LCD_DATA,
output [6:0] led_min0,led_min1,led_sec0, led_sec1,min_all1,min_all2,
output[0:14] led_wt
);
reg [2:0]mode;
initial mode=3'b000;
wire [2:0] wsh_sty;
wire [2:0] mode_slt;
wire cp_1,mode_change,bot_2t;
HZ_1 h_1(cp_50,1,cp_1);
control con_1( key_1,mode,cp_1,cp_50,wsh_sty, mode_change,led_min0,led_min1,led_sec0,
always
begin
end
put_bottom put_1(cp_50,bot_1,bot_2,mode,bot_2t,mode_slt);
lcd_show lcd(
.CLOCK_50(cp_50),
.RST_N(1),
.mode(mode),
.mode_slt(mode_slt),
.wsh_sty(wsh_sty),
.LCD_DATA(LCD_DATA),
.LCD_EN(LCD_EN),
.LCD_RS(LCD_RS),
.LCD_RW(LCD_RW),
10
if((key_0==1)&&(mode==3'b000)) mode<=3'b110;
else if(key_0==0)
mode<=3'b000;
mode<=3'b111;
mode<=mode_slt;
if(mode_change==1)
@ (posedge cp_50)
led_sec1,min_all1,min_all2,led_wt);
if((mode==3'b110)&&(bot_2t==0))
.LCD_ON(LCD_ON),
.LCD_BLON(LCD_BLON)
);
Endmodule
module put_bottom(cp_50,bot_1,bot_2,mode,bot_2t,mode_slt);//去抖时间20ms,检测时间20um,没有按是1
input cp_50,bot_1,bot_2;
input[2:0]mode;
output bot_2t;
output[2:0]mode_slt;
reg bot_1f,bot_1t,bot_2f,bot_2t;
reg [2:0]mode_slt;
reg [10:0]flag_1,flag_2;
initial
begin
end
bot_1f
bot_2f
bot_1t
bot_2t
<=
<=
<=
<=
1;
1;
1;
1;
mode_slt<=3'b001;
wire [3:0]q_0,q_1,q_2;
wire Q_0,Q_1,cp_u;
counter_10 u1 (1,cp_50,q_0[3:0],Q_0);
counter_10 u2 (1,Q_0,q_1[3:0],Q_1);
counter_10 u3 (1,Q_1,q_2[3:0],cp_u);//20微秒
always @ (posedge cp_u)
begin
if(bot_1f==bot_1)
else
if(bot_2f==bot_2)
flag_2 <= flag_2+11'b1;
11
begin
end
>11'd2000)
flag_1<=0;
bot_1t<=bot_1f;
begin
flag_1
bot_1f
<= 0;
<=bot_1;
flag_1 <= flag_1+11'b1;
if(flag_1
end
end
@
else
begin
end
>11'd2000)
flag_2<=0;
bot_2t<=bot_2f;
begin
flag_2
bot_2f
<= 0;
<=bot_2;
if(flag_2
end
always
end
( posedge bot_1t )
begin
if((mode==3'b110)&&(mode_slt<3'b101))
mode_slt <= mode_slt + 3'b001;
mode_slt <= 3'b001;
else if((mode==3'b110)&&(mode_slt>3'b100))
endmodule
module water_station(key_1,led_sec0,cp_1,wsh_sty,mode,time_flag,led_wt);
input [2:0]wsh_sty,mode;
input [10:0] time_flag;
input cp_1,key_1;
input[7:0] led_sec0;
output[0:14] led_wt;
reg [0:14] led_wt;
always @ (posedge cp_1)
begin
if((~(key_1==0))&&(mode!=3'b000))
else
case(mode)
3'b001,
3'b010,
3'b011,
3'b100:
12
begin
end
if((wsh_sty==3'b001)||(wsh_sty==3'b100))
else
led_wt <= led_wt;
led_wt <= 0;
1) + 1'b1;
1);
end
begin
end
begin
end
led_wt <= 15'b0;
if(time_flag==0)
led_wt <= 15'h00ff;
led_wt <= (led_wt >> 1);
else if(time_flag[2:0]==3'b000)
case(wsh_sty)
3'b000:
3'b001:
3'b010:
led_wt <= (led_wt >> 1);
end
if(time_flag[4:0]==3'b00000)led_wt <= (led_wt >>
if(time_flag[1:0]==2'b00)
led_wt <= ~led_wt;
led_wt <= 15'h7fff ;
led_wt <= (led_wt <<
begin
if(time_flag==0)
if((led_sec0==8'b1001_1001)||(led_sec0==8'b1001_0000))
3'b011:
3'b100:
end
begin
if(time_flag==0)
begin
end
else
led_wt <= ~led_wt;
led_wt <= 15'h7fff ;
default: led_wt <= 15'b0;
endcase
3'b101:
default:
endcase
endmodule
module control (key_1,mode,cp_1,cp_50,wsh_sty[2:0] ,mode_change,led_min0,led_min1 ,led_sec0,
led_sec1,min_all1,min_all2,led_wt);
input [2:0]mode;
input cp_1,cp_50,key_1;
output [2:0] wsh_sty;
output mode_change;
output [7:0] led_min0,led_min1,led_sec0, led_sec1,min_all1,min_all2;
13
output[14:0] led_wt;
//wire [2:0]mode;
reg[2:0] wsh_sty;
reg[1:0]
reg
initial
led_show led_1(key_1,time_flag , mode, wsh_sty,cp_50,cp_1,led_min0,led_min1,led_sec0,
led_sec1,min_all1,min_all2,seccp);
water_station(key_1,led_sec0,cp_1,wsh_sty,mode,time_flag,led_wt);
always @ ( posedge seccp)
begin
if((~(key_1==0))&&(mode!=3'b000))
else
case(mode)
3'b000:
begin
wsh_sty<=3'b000;
wsh_flag<=1'b0;
dry_flag<=2'b00;
time_flag=0;
begin
end
wsh_sty <= wsh_sty;
wsh_flag <= wsh_flag;
dry_flag <= dry_flag;
time_flag <= time_flag;
mode_change <= mode_change;
begin
end
wsh_sty<=3'b000;
wsh_flag<=1'b0;
dry_flag<=2'b00;
dry_flag;
mode_change,wsh_flag;
reg[10:0] time_flag;
wire seccp;
end //断电状态将洗衣方式清零
3'b001,
3'b010,
3'b011:
begin
case(wsh_sty)
3'b000:
14
//注水
begin
if((time_flag>=11'd60)&&(wsh_flag==0))
式
if((time_flag>=11'd60)&&(wsh_flag==1))
式
if((time_flag>=11'd1800)&&(mode==3'b001))
式
if((time_flag>=11'd1200)&&(mode==3'b010))
式
if((time_flag>=11'd600)&&(mode==3'b011))
式
begin
time_flag=0;
wsh_sty<=3'b001; //转到洗衣模 end
else
begin
time_flag=0;
wsh_sty<=3'b100; //转到漂洗模 end
else
time_flag <= time_flag + 1'b1 ;
end
3'b001: //洗衣
begin
wsh_flag <= 1;
begin
time_flag=0;
wsh_sty<=3'b010; //转到排水模 end
else
begin
time_flag=0;
wsh_sty<=3'b010; //转到排水模 end
else
begin
time_flag=0;
wsh_sty<=3'b010; //转到排水模 end
else
time_flag <= time_flag +1'b1 ;
end
3'b010: //排水
15
式
时向外部表示已经洗完,请求改变模式
if((time_flag>=11'd60)&&(dry_flag<2'b10))
式
式
begin
if(time_flag>=11'd60)
begin
time_flag=0;
wsh_sty<=3'b011; //转到甩干模 end
else
time_flag <= time_flag + 1'b1 ;
end
3'b011: //甩干
begin
if((time_flag>=11'd60)&&(dry_flag>=2'b10))
begin
time_flag =0;
dry_flag <= 0;
wsh_sty <= 3'b000;
wsh_flag<=1'b0;
mode_change<=1; //高电平 end
else
begin
time_flag = 0;
wsh_sty <= 3'b000; //转到注水模 dry_flag <= dry_flag + 1'b1;
end
else
time_flag <= time_flag + 1'b1 ;
end
3'b100: //漂洗
begin
if(time_flag>=11'd300)
begin
time_flag=0;
wsh_sty<=3'b010; //转到甩干模 end
else
time_flag <= time_flag +1'b1 ;
16
end
end
wsh_sty <=3'b000; default:
endcase
3'b100: begin
case(wsh_sty)
式
式
时向外部表示已经洗完,请求改变模式
if((time_flag>=11'd60)&&(dry_flag<2'b01))
3'b000: //注水
begin
if(time_flag>=11'd60)
begin
time_flag=0;
wsh_sty<=3'b100; //转到漂洗模 end
else
time_flag <= time_flag + 1'b1;
end
3'b010: //排水
begin
if(time_flag>=11'd60)
begin
time_flag=0;
wsh_sty<=3'b011; //转到甩干模 end
else
time_flag <= time_flag + 1'b1 ;
end
3'b011: //甩干
begin
if((time_flag>=11'd60)&&(dry_flag>=2'b01))
begin
time_flag =0;
dry_flag <= 0;
wsh_sty <= 3'b000;
wsh_flag<=1'b0;
mode_change<=1; //高电平 end
else
17
式
式
求改变模式
begin
time_flag = 0;
wsh_sty <= 3'b000; //转到注水模 dry_flag <= dry_flag + 1'b1;
end
else
time_flag <= time_flag + 1'b1 ;
end
3'b100: //漂洗
begin
if(time_flag>=11'd300)
begin
time_flag=0;
wsh_sty<=3'b010; //转到排水模 end
else
time_flag <= time_flag + 1'b1 ;
end
default: wsh_sty <=3'b000;
endcase
end
3'b101: begin
wsh_sty <= 3'b011;//甩干
if(time_flag>=7'd60)
begin
time_flag=0;
wsh_sty <= 3'b000;
wsh_flag<=1'b0;
mode_change<=1;//高电平时向外部表示已经洗完,请 end
else
time_flag <= time_flag + 1'b1;
end
3'b110: begin
wsh_sty<=3'b000;
time_flag=0;
wsh_flag<=1'b0;
dry_flag<=2'b00;
end
3'b111: begin
18
end
end
wsh_sty<=3'b000;
time_flag=0;
wsh_flag<=1'b0;
dry_flag<=2'b00;
mode_change<=0;
endcase
endmodule
module counter_6(ncr, en,cp,q);
module counter_10 (nclr,clk,Q,out_0);
input clk, nclr;
output
output
[3:0]Q;
out_0;
input cp, ncr,en;
output
reg
[3:0] q;
[3:0] q;
always @ (posedge cp or negedge ncr)
begin
end
if(!ncr)
q <= 4'b0000;
else if(~en)
else
q <= q;
q <= q + 1'b1;
else if(q == 4'b0101) q <= 4'b0000;
endmodule
reg [3:0]Q;
reg out_0;
(!nclr) begin
begin
begin
Q <= 4'b000; out_0=0 ; end
Q <= 4'b000; out_0=1 ; end
Q <= Q+1'b1; out_0=0 ; end
always @(posedge clk or negedge nclr)
begin
if
else if (Q==9)
else
end
endmodule
module led_show ( key_1,time_flag , mode, wsh_sty,cp_50,cp_1,led_min0,led_min1,led_sec0,
led_sec1,min_all1,min_all2,seccp);
input [10:0]time_flag;
input [2:0]mode;
19
input [2:0]wsh_sty;
input cp_50,cp_1,key_1;
output [7:0] led_min0,led_min1,led_sec0, led_sec1,min_all1,min_all2;
output seccp;
wire [7:0] led_min0,led_min1,led_sec0, led_sec1,min_all1,min_all2,min_use,sec_use,min_all;
wire mincp,seccp ;
wire [10:0]time_flag;
wire [2:0]mode;
wire [2:0]wsh_sty;
reg [7:0] min_now,sec_now,sec_now_old,min_now_old,min_sy,min_sy_old;
reg en_time,en_time_all;
//initial mincp<=1;
counter_60 u1(en_time, seccp,sec_use);
counter_60 u2(en_time, mincp,min_use);
counter_60 u3(en_time_all,mincp,min_all);
assign
assign
always
@
if(time_flag[10:0]==11'b0) en_time<=0;
else
case(mode)
3'b000,
3'b110,
3'b111:
default:
en_time_all <= 0;
en_time_all <= 1;
en_time<=1;
mincp = key_1 ? (mincp) :(sec_use == 8'b00000000);
seccp = key_1 ? (seccp):(cp_1);
(posedge cp_50)
begin
endcase
sec_now_old <= 8'b01011010- sec_use;
if(sec_now_old[3:0]==4'b1010)
case(wsh_sty)
3'b001:
begin
case(mode)
3'b001:
3'b010:
min_now_old <= 8'b00101001 - min_use;
min_now_old <= 8'b00011001 - min_use;
20
begin
end
sec_now[3:0] <= 0;
sec_now[7:4] <= sec_now_old[7:4]+4'b0001;
else sec_now <= sec_now_old;
end
3'b011:
endcase
min_now_old <= 8'b00001001 - min_use;
default:min_now_old <=0;
3'b100:
default:
min_now_old <= 8'b00000100 - min_use;
min_now_old <= 0;
endcase
if(min_now_old[3:0]==4'b1010)
case(mode)
3'b001:
begin
end
begin
end
begin
end
begin
end
min_sy <= 0;
min_sy_old <= 8'b00011001 - min_all;
if(min_sy_old[3:0]<4'b0100) min_sy <= min_sy_old - 8'd10;
else min_sy <= min_sy_old - 8'b00000100;
min_sy_old <= 8'b00101001 - min_all ;
if(min_sy_old[3:0]==4'b0000) min_sy <=min_sy_old - 8'd7;
else min_sy <= min_sy_old - 8'b00000001;
min_sy_old <= 8'b00111001 - min_all ;
if(min_sy_old[3:0]==4'b0000) min_sy <=min_sy_old - 8'd7;
else min_sy <= min_sy_old - 8'b00000001;
min_sy_old <= 8'b01001001 - min_all ;
if(min_sy_old[3:0]==4'b0000) min_sy <=min_sy_old - 8'd7;
else min_sy <= min_sy_old - 8'b00000001;
begin
end
min_now[3:0] <= 0;
min_now[7:4] <= min_now_old[7:4]+4'b0001;
else min_now <= min_now_old ;
3'b010:
3'b011:
3'b100:
default:
endcase
21
end
led led_1(cp_50,sec_now, led_sec0, led_sec1);
led led_2(cp_50,min_now, led_min0, led_min1);
led led_3(cp_50,min_sy, min_all1, min_all2);
endmodule
module led(cp_50,BCD,led0, led1);
input [7:0] BCD;
input cp_50;
output [7:0] led0, led1;
reg [7:0] led0, led1;
always @( posedge cp_50)
begin
casez (BCD[3:0])
casez (BCD[7:4])
4'd0 : led1 = 8'b1100_0000;
4'd1 : led1 = 8'b1111_1001;
4'd2 : led1 = 8'b1010_0100;
4'd3 : led1 = 8'b1011_0000;
4'd4 : led1 = 8'b1001_1001;
4'd5 : led1 = 8'b1001_0010;
4'd6 : led1 = 8'b1000_0010;
4'd7 : led1 = 8'b1111_1000;
4'd8 : led1 = 8'b1000_0000;
4'd9 : led1 = 8'b1001_0000;
default: led0 = 8'b1111_1111;
22
4'd0 : led0 = 8'b1100_0000;
4'd1 : led0 = 8'b1111_1001;
4'd2 : led0 = 8'b1010_0100;
4'd3 : led0 = 8'b1011_0000;
4'd4 : led0 = 8'b1001_1001;
4'd5 : led0 = 8'b1001_0010;
4'd6 : led0 = 8'b1000_0010;
4'd7 : led0 = 8'b1111_1000;
4'd8 : led0 = 8'b1000_0000;
4'd9 : led0 = 8'b1001_0000;
default: led0 = 8'b1111_1111;
endcase
end
endcase
endmodule
/*******************************************************************************************************
***********************************lcd显示部分**********************************************************
***********************************用lcd显示当前的mode
*************************************************
********************************************************************************************************
*/
module lcd_show(
);
wire[7:0] LCD_D_1;
wire LCD_RS_1;
wire LCD_RW_1;
wire LCD_EN_1;
wire DLY_RST;
assign LCD_DATA=LCD_D_1;
assign LCD_RS=LCD_RS_1;
assign LCD_RW=LCD_RW_1;
assign LCD_EN=LCD_EN_1;
assign LCD_ON=1'b1;
assign LCD_BLON=1'b1;
Reset_Delay r0(.iCLK(CLOCK_50), .oRESET(DLY_RST),.RST_N(RST_N));
LCD1602_TEST u1(
.iCLK(CLOCK_50),
.iRST_N(DLY_RST),
.mode(mode),
23
input CLOCK_50,
input RST_N,
input [2:0]mode,// new
output[7:0] LCD_DATA,
input[2:0] wsh_sty,
input [2:0]mode_slt,
output LCD_EN,
output LCD_RS,
output LCD_RW,
output LCD_ON,
output LCD_BLON
.mode_slt(mode_slt),
.wsh_sty(wsh_sty),
.LCD_DATA(LCD_D_1),
.LCD_RW(LCD_RW_1),
.LCD_EN(LCD_EN_1),
.LCD_RS(LCD_RS_1)
);
endmodule
//RST_N初始延迟代码:
module Reset_Delay(iCLK,oRESET,RST_N);
input iCLK,RST_N;
output reg oRESET;
reg[19:0] Cont;
always@(posedge iCLK)
begin
if(~RST_N)
begin
Cont<=0;
oRESET<=1'b0;
end
if((Cont!=20'hfffff)&&(RST_N))
begin
Cont<=Cont+1'b1;
oRESET<=1'b0;
end
else
oRESET<=1'b1;
end
endmodule
//底层代码LCD1602_TEST:
module LCD1602_TEST(
input iCLK,iRST_N,
input [2:0]mode ,
24
//初始化的延时部分
input [2:0]mode_slt ,
input [2:0]wsh_sty,
output[7:0] LCD_DATA,
output LCD_RS,LCD_RW,LCD_EN
);
reg[5:0] LUT_INDEX;
reg[8:0] LUT_DATA;
reg[5:0] mLCD_ST;
reg[17:0] mDLY;
reg[7:0] mLCD_DATA;
reg mLCD_Start;
reg mLCD_RS;
reg [2:0]mode_flag,mode_slt_flag;
reg [3:0]wsh_sty_flag;
wire mLCD_Done;
parameter LCD_INITIAL = 0;
parameter LCD_LINE1 = 5; //初始化命令有5个parameter LCD_CH_LINE = LCD_LINE1+16; //换行parameter LCD_LINE2 = LCD_LINE1+16+1;
parameter LUT_SIZE = LCD_LINE1+32+1;
initial
begin
mode_flag<=3'b000;
end
always@(posedge iCLK or negedge iRST_N)
begin
if(!iRST_N)
部清零
begin
LUT_INDEX <= 0;
mLCD_ST <= 0;
mDLY <= 0;
mLCD_Start <= 0;
mLCD_DATA <= 0;
mLCD_RS <= 0;
end
else
begin
if(mode_flag !=mode)
begin
mode_flag<=mode;
LUT_INDEX <= 0;
end
if(mode_slt_flag !=mode_slt)
25
//程序的初始化,全
begin
end
if(wsh_sty_flag != wsh_sty)
begin
wsh_sty_flag<=wsh_sty;
mode_slt_flag<=mode_slt;
LUT_INDEX <= 0;
LUT_INDEX <= 0;
end
if(LUT_INDEX begin 序需要的时延 case(mLCD_ST) 0: begin mLCD_DATA <= LUT_DATA[7:0]; 是显示位 mLCD_RS <= LUT_DATA[8]; 是控制位 mLCD_Start <= 1; mLCD_ST <= 1; end 1: begin if(mLCD_Done) 否已经显示 begin mLCD_Start <= 0; 经显示重新归零,否则保持原来的1 mLCD_ST <= 2; 转到下一步 end end 2: begin if(mDLY<16'hffff) mDLY <= mDLY+17'b1; else begin mDLY <= 0; 零 mLCD_ST <= 3; 转到下一步 end end 3: begin 26 //提供程//低八位//第九位//检查是//如果已 //跳//延时 //归 //跳 转到初始状态 示光标 针清零 址指针加一 (power off) end end end LUT_INDEX <= LUT_INDEX+6'b1; mLCD_ST <= 0; //自加 //跳endcase begin case(mode) 3'b000: begin end case(LUT_INDEX) LCD_INITIAL+0: LUT_DATA <= 9'h038; //设置16x2显示,LCD_INITIAL+1: LUT_DATA <= 9'h00C; //设置开显示,不显LCD_INITIAL+2: LUT_DATA <= 9'h001; //显示清零,数据指LCD_INITIAL+3: LUT_DATA <= 9'h006; //写一个字符后地LCD_INITIAL+4: LUT_DATA <= 9'h080; //第一行首地址 LCD_LINE1+0: LUT_DATA <= 9'h120; // 未开电源LCD_LINE1+3: LUT_DATA <= 9'h170; //p LCD_LINE1+4: LUT_DATA <= 9'h16f; //o LCD_LINE1+5: LUT_DATA <= 9'h177; //w LCD_LINE1+6: LUT_DATA <= 9'h165; //e LCD_LINE1+7: LUT_DATA <= 9'h172; //r LCD_LINE1+10: LUT_DATA <= 9'h16f; //o LCD_LINE1+11: LUT_DATA <= 9'h166; //f LCD_LINE1+12: LUT_DATA <= 9'h166; //f LCD_CH_LINE: LUT_DATA <= 9'h0C0; default: LUT_DATA <= 9'h120; 5x7点阵,8位数据接口 endcase 3'b001, 3'b010, 3'b011, 3'b100, 3'b101: begin case(LUT_INDEX) LCD_INITIAL+0: LUT_DATA <= 9'h038; //设置16x2显示,5x7点阵,8位数据接口 27 数据指针清零 址 LCD_INITIAL+1: LUT_DATA <= 9'h00C; //设置开显LCD_INITIAL+2: LUT_DATA <= 9'h001; //显示清零,LCD_INITIAL+3: LUT_DATA <= 9'h006; //写一个字符LCD_INITIAL+4: LUT_DATA <= 9'h080; //第一行首地LCD_LINE1+6: LUT_DATA <= 9'h16d; //m 示,不显示光标 后地址指针加一 <= 9'h131; <= 9'h132; <= 9'h133; <= 9'h134; <= 9'h135; LUT_DATA <= 9'h120; <= 9'h169;//i <= 9'h120;//120 <= 9'h120;//120 <= 9'h120;//120 <= 9'h120;//120 LUT_DATA <= 9'h120; LCD_LINE1+7: LCD_LINE1+8: LCD_LINE1+9: LCD_LINE1+11: LCD_CH_LINE: LCD_LINE2+5: 28 LUT_DATA <= 9'h16f; //o LUT_DATA <= 9'h164; //d LUT_DATA <= 9'h165; //e begin case(mode) 3'b001: LUT_DATA 3'b010: LUT_DATA 3'b011: LUT_DATA 3'b100: LUT_DATA 3'b101: LUT_DATA default: endcase end LUT_DATA <= 9'h0C0; begin case(wsh_sty) 3'b000: LUT_DATA 3'b001: LUT_DATA 3'b010: LUT_DATA 3'b011: LUT_DATA 3'b100: LUT_DATA default: endcase end LCD_LINE2+6: begin <= 9'h16e;//n <= 9'h177;//w <= 9'h164;//d <= 9'h120;//120 <= 9'h170;//p LUT_DATA <= 9'h120; <= 9'h16a;//j <= 9'h161;//a <= 9'h172;//r <= 9'h164;//d <= 9'h16f;//o LUT_DATA <= 9'h120; <= 9'h165;//e <= 9'h173;//s <= 9'h161;//a <= 9'h172;//r LCD_LINE2+7: LCD_LINE2+8: 29 case(wsh_sty) 3'b000: 3'b001: 3'b010: 3'b011: 3'b100: default: endcase end begin case(wsh_sty) 3'b000: 3'b001: 3'b010: 3'b011: 3'b100: default: endcase end begin case(wsh_sty) 3'b000: 3'b001: 3'b010: 3'b011: 3'b100: LUT_DATA LUT_DATA LUT_DATA LUT_DATA LUT_DATA LUT_DATA LUT_DATA LUT_DATA LUT_DATA LUT_DATA LUT_DATA LUT_DATA LUT_DATA LUT_DATA LUT_DATA <= 9'h174;//t end default: LUT_DATA <= 9'h120; endcase LCD_LINE2+9: begin <= 9'h163;//c <= 9'h168;//h <= 9'h169;//i <= 9'h179;//y <= 9'h163;//c LUT_DATA <= 9'h120; <= 9'h174;//t <= 9'h120;//120 <= 9'h16e;//n <= 9'h120;//120 <= 9'h168;//h LUT_DATA <= 9'h120; end 3'b110: begin case(wsh_sty) 3'b000: 3'b001: 3'b010: 3'b011: 3'b100: default: endcase end LCD_LINE2+10: begin case(wsh_sty) 3'b000: 3'b001: 3'b010: 3'b011: 3'b100: default: endcase end default: LUT_DATA <= 9'h120; endcase case(LUT_INDEX) 30 LUT_DATA LUT_DATA LUT_DATA LUT_DATA LUT_DATA LUT_DATA LUT_DATA LUT_DATA LUT_DATA LUT_DATA 示光标 针清零 址指针加一 end LCD_INITIAL+0: LUT_DATA <= 9'h038; //设置16x2显示,LCD_INITIAL+1: LUT_DATA <= 9'h00C; //设置开显示,不显LCD_INITIAL+2: LUT_DATA <= 9'h001; //显示清零,数据指LCD_INITIAL+3: LUT_DATA <= 9'h006; //写一个字符后地LCD_INITIAL+4: LUT_DATA <= 9'h080; //第一行首地址 LCD_LINE1+1: LUT_DATA <= 9'h170; //p LCD_LINE1+2: LUT_DATA <= 9'h16c; //l LCD_LINE1+3: LUT_DATA <= 9'h165; //e LCD_LINE1+4: LUT_DATA <= 9'h161; //a LCD_LINE1+5: LUT_DATA <= 9'h173; //s LCD_LINE1+6: LUT_DATA <= 9'h165; //e LCD_LINE1+9: LUT_DATA <= 9'h173; //s LCD_LINE1+10: LUT_DATA <= 9'h165; //e LCD_LINE1+11: LUT_DATA <= 9'h16c; //l LCD_LINE1+12: LUT_DATA <= 9'h165; //e LCD_LINE1+13: LUT_DATA <= 9'h163; //c LCD_LINE1+14: LUT_DATA <= 9'h174; //t LCD_CH_LINE: LUT_DATA <= 9'h0C0; LCD_LINE2+5: LUT_DATA <= 9'h16D; //m LCD_LINE2+6: LUT_DATA <= 9'h16F; //o LCD_LINE2+7: LUT_DATA <= 9'h164; //d LCD_LINE2+8: LUT_DATA <= 9'h165; //e LCD_LINE2+10:begin if(mode_slt==3'b001) else end LUT_DATA <= 9'h13F; LUT_DATA <= 9'h131; LUT_DATA <= 9'h132; LUT_DATA <= 9'h133; LUT_DATA <= 9'h134; LUT_DATA <= 9'h135; else if(mode_slt==3'b010) else if(mode_slt==3'b011) else if(mode_slt==3'b100) else if(mode_slt==3'b101) 5x7点阵,8位数据接口 LCD_LINE2+12: LUT_DATA <= 9'h13f; default: LUT_DATA <= 9'h120; endcase 31 示光标 3'b111: begin case(LUT_INDEX) LCD_INITIAL+0: LUT_DATA <= 9'h038; //设置16x2显示,LCD_INITIAL+1: LUT_DATA <= 9'h00C; //设置开显示,不显LCD_INITIAL+2: LUT_DATA <= 9'h001; //显示清零,数据指5x7点阵,8位数据接口 针清零 LCD_INITIAL+3: LUT_DATA 址指针加一 LCD_INITIAL+4: LUT_DATA LCD_LINE1+5: LUT_DATA LCD_LINE1+6: LUT_DATA LCD_LINE1+7: LUT_DATA LCD_LINE1+8: LUT_DATA LCD_LINE1+9: LUT_DATA LCD_LINE1+10: LUT_DATA LCD_CH_LINE: LUT_DATA LCD_LINE2+6: LUT_DATA LCD_LINE2+7: LUT_DATA LCD_LINE2+8: LUT_DATA LCD_LINE2+9: LUT_DATA default: LUT_DATA endcase end endcase end end LCD1602_Controller u0 ( .iDATA(mLCD_DATA), .iRS(mLCD_RS), .iStart(mLCD_Start), .oDone(mLCD_Done), .iCLK(iCLK), .iRST_N(iRST_N), .LCD_DATA(LCD_DATA), .LCD_RW(LCD_RW), .LCD_EN(LCD_EN), .LCD_RS(LCD_RS) ); endmodule 32 <= 9'h006; //写一个字符后地<= 9'h080; //第一行首地址 <= 9'h177; //w <= 9'h161; //a <= 9'h173; //s <= 9'h168; //h <= 9'h165; //e <= 9'h172; //r <= 9'h0C0; <= 9'h16F; //o <= 9'h176; //v <= 9'h165; //e <= 9'h172; //r <= 9'h120; //底层代码LCD1602_Controller: module LCD1602_Controller( input iCLK,iRST_N, input iRS,iStart, input[7:0] iDATA, output reg oDone, output[7:0] LCD_DATA, output LCD_RS, output LCD_RW, output reg LCD_EN ); reg[4:0] Cont; reg[1:0] ST; reg preStart,mStart; assign LCD_DATA = iDATA; assign LCD_RS = iRS; assign LCD_RW = 1'b0; parameter CLK_Divide = 16; always@(posedge iCLK or negedge iRST_N) begin if(!iRST_N) begin oDone <= 1'b0; LCD_EN <= 1'b0; preStart<= 1'b0; mStart <= 1'b0; Cont <= 0; ST <= 0; end else begin preStart <= iStart; if({preStart,iStart}==2'b01) begin mStart <= 1'b1; oDone <= 1'b0; end if(mStart) begin 33 //提 供程序需要的脉冲 end endmodule module HZ_1 (input_0,nclr,output_fin); input input_0,nclr; output output_fin; wire [3:0]q_0,q_1,q_2,q_3,q_4,q_5,q_6,q_7; wire Q_0,Q_1,Q_2,Q_3,Q_4,Q_5,Q_6; counter_10 u1 (nclr,input_0,q_0[3:0],Q_0); counter_10 u2 (nclr,Q_0,q_1[3:0],Q_1); counter_10 u3 (nclr,Q_1,q_2[3:0],Q_2); counter_10 u4 (nclr,Q_2,q_3[3:0],Q_3); counter_10 u5 (nclr,Q_3,q_4[3:0],Q_4); counter_10 u6 (nclr,Q_4,q_5[3:0],Q_5); counter_10 u7 (nclr,Q_5,q_6[3:0],Q_6); counter_5 u8 (nclr,Q_6,q_7[3:0],output_fin); endmodule module counter_60(nclr, cp,ct); input cp, nclr; output [7:0] ct; // 模六十计数器输出信号 34 end case(ST) end 0: ST <= 1; 1: begin end end end LCD_EN <= 1'b0; mStart <= 1'b0; oDone <= 1'b1; Cont <= 0; ST <= 0; if(Cont else ST <= 3; Cont <= Cont+5'b1; LCD_EN <= 1'b1; ST <= 2; 2: begin 3: begin endcase wire [7:0] ct; wire cp_6,en; counter_10 counter_6 assign // 输出 8421 BCD 码 uc0 (nclr,cp,ct[3:0],cp_6); uc1 (nclr,en,cp,ct[7:4]); en = (ct[3:0] == 4'h9); // 产生计数器十位使能信号 endmodule module counter_5 (nclr,clk,Q,out_0); input clk, nclr; output [3:0]Q; output out_0; reg [3:0]Q; reg out_0; always @(posedge clk or negedge nclr) begin if (!nclr) begin else if (Q==3) begin else if (Q==4) begin else begin end endmodule Q <= 4'b000; out_0=0 ; Q <= Q+1'b1; out_0=1 Q <= 4'b000; out_0=0 ; Q <= Q+1'b1; out_0=0 35 end ; end end ; end
本文发布于:2024-09-24 11:25:36,感谢您对本站的认可!
本文链接:https://www.17tex.com/fanyi/17730.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |