• 【毕业设计】42-基于FPGA的LCD1602控制器设计仿真与实现(原理图+仿真+源代码+论文)


    【毕业设计】42基于FPGA的LCD1602控制器设计仿真与实现(原理图+仿真+源代码+论文)

    任务书

    基于altera 公司cyclone4代芯片的fpga以及quartusII软件设计一款屏幕显示系统,显示装置可以选择点阵或字符型液晶,最终实现滚动显示、可控制滚动方向、暂停、清屏等功能。

    原理图工程文件
    仿真工程文件
    源代码
    仿真截图
    低重复率论文,字数:19964

    设计说明书

    摘要

    本次系统为基于FPGA的显示控制器设计,实现液晶显示器的左翻滚、右翻滚、暂停、清屏的功能。程序编写对各个功能编写程序。系统具有多功能,通过模块化的方式来进行设计,根据各个功能进行编程,在设计上和仿真上均通过模块化的方式进行,保证设计可以减少调试时间,更可以使功能顺利实现。本次系统由于考虑多方面的因素实现了显示控制器设计,具有一定的推广意义和学习意义。
    该控制器可以显示字符、图片两个部分。字符显示功能上通过调用RAM实现,可以通过调用液晶显示器内部的字库来实现字符的调用。功能按键实时控制液晶显示器的状态,同步改变LCD上显示的内容,并且将内部RAM的字符图片数据显示在LCD1602显示器中。
    本次毕业设计使用FPGA系列产品开发,并且使用到了当前市面上常用的LCD1602液晶显示器。使用FPGA开发系统可以缩短研发系统的开发时间。并且系统分两个模块按键、与液晶显示模块。模块化的设计可以使其应用在更多FPGA系列产品上。基于FPGA的显示控制器设计是当前热门研究方式,具有人机交互意义并且可以使人们生活出现新的改变。

    设计框架架构

    在这里插入图片描述

    第一章 绪论 1
    1.1 研究背景与意义 1
    1.2 课题发展现状 1
    1.3 国内外发展情况 1
    1.31 国外发展情况 2
    1.32 国内发展情况 2
    1.4 EDA技术的设计流程 2
    第二章 系统设计平台及方案 4
    2.1 EDA技术发展 4
    2.2 FPGA介绍 6
    2.21 FPGA工作原理 6
    2.22 FPGA基本特点 7
    2.3 Quartus II简编程软件的介绍 8
    2.31 Quartus II简介 8
    2.32 Quartus II设计流程 8
    2.4 编程语言介绍 9
    2.5 系统设计方案 10
    2.51 系统实现功能描述 10
    2.52 系统功能框架 11
    第三章 系统硬件设计 13
    3.1 FPGA最小系统设计 13
    3.11 电源电路 13
    3.12 晶振电路 14
    3.13 复位电路 15
    3.14 EPCS4SI8配置芯片电路 15
    3.15 下载接口电路 16
    3.2 LCD1602电路设计 16
    3.3 按键电路设计 19
    3.4 系统总电路设计 19
    3.5 系统PCB设计 20
    第四章 系统软件设计及仿真 22
    4.1 系统软件设计 22
    4.12 LCD1602控制模块设计 22
    4.13 按键模块软件设计 26
    4.14 顶层模块设计 28
    4.2 系统仿真验证 29
    4.21 仿真流程 29
    4.22 仿真结果 31
    结 论 35
    参考文献 37
    致 谢 38
    附录 39
    外文资料原文 50
    译文 53

    设计说明书及设计文件

    在这里插入图片描述在这里插入图片描述字数:19964
    在这里插入图片描述

    源码展示

    源代码:
    library verilog;
    use verilog.vl_types.all;
    entity lcd1602 is
        port(
            clk             : in     vl_logic;
            rst_n           : in     vl_logic;
            key1            : in     vl_logic;
            key2            : in     vl_logic;
            key3            : in     vl_logic;
            key4            : in     vl_logic;
            lcd_rs          : out    vl_logic;
            lcd_rw          : out    vl_logic;
            lcd_en          : out    vl_logic;
            lcd_data        : out    vl_logic_vector(7 downto 0)
        );
    end lcd1602;
    library verilog;
    use verilog.vl_types.all;
    entity key_bounce is
        port(
            key_in          : in     vl_logic_vector(3 downto 0);
            clk             : in     vl_logic;
            rst_n           : in     vl_logic;
            key1            : out    vl_logic;
            key2            : out    vl_logic;
            key3            : out    vl_logic;
            key4            : out    vl_logic
        );
    end key_bounce;
    library verilog;
    use verilog.vl_types.all;
    entity top is
        port(
            clk             : in     vl_logic;
            rst_n           : in     vl_logic;
            key_in          : in     vl_logic_vector(3 downto 0);
            lcd_rs          : out    vl_logic;
            lcd_rw          : out    vl_logic;
            lcd_en          : out    vl_logic;
            lcd_data        : out    vl_logic_vector(7 downto 0)
        );
    end top;
    module lcd1602(
    	input				clk			,
    	input				rst_n		,
    	input				key1		,//左滚动
    	input				key2		,//右滚动
    	input				key3		,//暂停
    	input				key4		,//清屏
    	output	reg			lcd_rs		,//0:命令 1:数据
    	output			    lcd_rw		,//0:写  1:读
    	output	reg			lcd_en		,//使能
    	output	reg	[7:0]	lcd_data	 //8-bit 
    	);
    assign 				lcd_rw = 1'b0		;  //只写
    reg	[4:0]			char_cnt			;
    reg	[7:0]			data_display1 =8'b0	; //第一行数据
    reg	[7:0]			data_display2 =8'b0	; //第二行数据
    localparam	S0			= 4'd0	;
    localparam	S1			= 4'd1	;
    localparam	S2			= 4'd2	;
    localparam	S3			= 4'd3	;
    localparam	S4			= 4'd4	;
    localparam	S5			= 4'd5	;
    localparam	S6			= 4'd6	;
    localparam	S7			= 4'd7	;
    localparam	S8			= 4'd8	;
    localparam	IDLE		= 4'd9	;
    localparam	LEFT		= 4'd10	;
    localparam	RIGHT		= 4'd11	;
    localparam	STOP		= 4'd12	;
    localparam	CLEAR		= 4'd13	;
    //localparam	cnt_2ms		= 17'd50000		;
     // 2ms 时钟计数
    //localparam	cnt_15ms	= 17'd7			;
     // 16ms延时
    //localparam	cnt_500ms	= 17'd249		;
     // 500ms延时
    localparam	cnt_2ms		= 17'd500	;
     // 缩短仿真计数2ms 时钟
    localparam	cnt_15ms	= 17'd7;	
    // 缩短仿真计数16ms延时
    localparam	cnt_500ms	= 17'd9	;
     // 缩短仿真计数500ms延时	
    reg	[16:0]			cnt_en			;
    always @(posedge clk or negedge rst_n) 
    	if (!rst_n) 
    		cnt_en <= 17'd0;
    	else if (cnt_en==cnt_2ms - 1) 
    		cnt_en <= 17'd0;
    	else 
    		cnt_en <= cnt_en + 1'b1;
    //**************************************************************		
    reg		[1:0]	key1_reg			; 
    //同步key1 ,左滚动
    reg		[1:0]	key2_reg			;
     //同步key2 ,右滚动
    reg		[1:0]	key3_reg			;
     //同步key3 ,暂停
    reg		[1:0]	key4_reg			;
     //同步key4 ,清屏
    wire [3:0] 			key ;
    assign key ={key4_reg[1],key3_reg[1],key2_reg[1],key1_reg[1]};
    	always @(posedge lcd_en or negedge rst_n) 
    	if (!rst_n)begin 
    		key1_reg <= 2'b11;
    		key2_reg <= 2'b11;
    		key3_reg <= 2'b11;
    		key4_reg <= 3'b111;
    	end
    	else begin 
    		key1_reg <= {key1_reg[0],	key1};
    		key2_reg <= {key2_reg[0],	key2};
    		key3_reg <= {key3_reg[0],	key3};
    		key4_reg <= {key4_reg[0], 	key4};
    	end                     
    //**********************************************	
    always @(posedge clk or negedge rst_n) //lcd_en为500khz
    	if (!rst_n) 
    		lcd_en <= 1'b0;
    	else if (cnt_en==cnt_2ms - 1) 
    		lcd_en <= ~lcd_en;
    reg [3:0] 		state;
    reg [31:0] 		cnt;
    always @(posedge lcd_en or negedge rst_n)
    begin
    	if(!rst_n)begin
    		cnt			<=  1'b0;
    		lcd_rs		<=	1'b0;
    		lcd_data	<=	1'b0;
    		state		<= 	S0;
    		char_cnt	<= 	4'd0;
    	end
    	else case(state)
    		S0:begin	
    					lcd_rs		<=	1'b0;           //15ms延时
    				if(cnt==cnt_15ms) begin
    					cnt			<=  10'b0;
    					state		<= 	S1;
    				end
    				else begin
    					cnt			<=  cnt+1'b1;
    					state		<= 	state;
    				end
    			end	
    		S1:begin
    				lcd_rs		<=	1'b0;
     //功能设定,数据8位,显示2行,5x7点阵
    				lcd_data	<=	8'b0011_1000;
    				state		<= 	S2;
    			end
    		S2:begin
    				lcd_rs		<=	1'b0;
     /显示开关控制,一直显示,无光标。
    				lcd_data	<=	8'b0000_1100;   //8'b0000_1ABC;
    A:显示功能;0关1开。
    				state		<= 	S3;			/
    /B:光标;	0无1有。	
    			end									
    //C:光标闪 ; 0闪1不闪。
    		S3:begin
    				lcd_rs		<=	1'b0; 
    //清屏,指令码01h
    				lcd_data	<=	8'h01;
    				state		<= 	S4;
    			end
    		S4:begin
    				lcd_rs		<=	1'b0;
    //设置模式,写入一个数据,光标右移
    				lcd_data	<=	8'b0000_0101;
    //8'b0000_01DS;	DS: 00光标左移,10光标右移
    				state		<= 	S5;	
    //10显示屏不移动,11显示屏右移 
    			end 
    		S5:begin
    				lcd_rs		<=	1'b0; 
    //设置第一行地址
    				lcd_data	<=	8'b10000000;
    高位
    				state		<= 	S6;
    			end
    		S6:begin
    				lcd_rs		<=	1'b1;
    //写入第一行数据
    				lcd_data	<=	data_display1;
    				char_cnt	<=  char_cnt+1'b1;
    				if(char_cnt==5'd15)begin
    					state	<= 	S7;
    				end
    				else 
    					state	<= 	state;
    			end
    		S7:begin
    				lcd_rs		<=	1'b0;
    //设置第二行地址
    				lcd_data	<=	8'b11000000;
    				state		<= 	S8;
    			end	
    		S8:begin
    				lcd_rs		<=	1'b1;
    //写入第二行数据
    				lcd_data	<=	data_display2;
    				char_cnt	<=  char_cnt+1'b1;
    				if(char_cnt==5'd31)begin
    					state		<= 	IDLE;
    					char_cnt	<=  5'd0;
    				end   
    				else 
    					state		<= 	S8;	
    			end	
    ****************以上都是初始****************************//
    		IDLE:begin
    				lcd_rs	<=	1'b0;    
    				cnt		<=  0;
    				lcd_data<=	8'b0;
    				begin
    				case(key)
    					4'b1110:state	<=	LEFT    ;
    					4'b1101:state	<=	RIGHT   ;
    					4'b1011:state	<=	STOP    ;
    					4'b0111:state	<=	CLEAR    ;
    				default: state	<=	IDLE;
    				endcase
    				end
    			end
    		LEFT:begin 
    					lcd_rs		<=	1'b0; 
    				begin
    					case(key)
    					4'b1110:state	<=	LEFT    ;
    					4'b1101:state	<=	RIGHT   ;
    					4'b1011:state	<=	STOP    ;
    					4'b0111:state	<=	CLEAR   ;
    					default: state	<=	LEFT	;
    					endcase
    //左滚动,0.5s移动一次。
    				end
    //设置显示屏或光标移动方向,
    				begin
    					if(cnt==1)                                  //8'b0001_AB00;	    AB: 00光标左移,01光标右移;   
    						lcd_data	<=	8'b0001_1000;           
    //10显示屏左移,11显示屏右移 ;   
    					else
    						lcd_data	<=	8'h0;
    				end
    				begin
    					if(cnt==cnt_500ms)	
    						cnt			<=  0;
    					else
    						cnt<=cnt+1'b1;
    				end
    			end		
    		RIGHT:begin 
    					lcd_rs			<=	1'b0; 
    				begin
    					case(key)								
    //右滚动,0.5s移动一次。
    						4'b1110:state	<=	LEFT    ;
    //设置显示屏或光标移动方向,
    						4'b1101:state	<=	RIGHT   ;
     //8'b0001_AB00;	    AB: 00光标左移,01光标右移;   
    						4'b1011:state	<=	STOP    ;       
    //10显示屏左移,11显示屏右移 ; 
    						4'b0111:state	<=	CLEAR    ;
    					default: 	state	<=	RIGHT;
    					endcase	
    				end
    				begin
    					if(cnt==1)
    						lcd_data	<=	8'b0001_1100;	
    					else
    						lcd_data	<=	8'h0;
    				end
    				begin
    					if(cnt==cnt_500ms)	   	
    						cnt			<=  0;
    					else
    						cnt<=cnt+1'b1;
    				end
    			end
    		STOP:begin 
    //暂停
    				cnt		<=  32'b0;
    				lcd_data<=	8'b0;
    				lcd_rs  <=  1'b0;
    				case(key)
    					4'b1110:state	<=	LEFT    ;
    					4'b1101:state	<=	RIGHT   ;
    					4'b1011:state	<=	STOP    ;
    					4'b0111:state	<=	CLEAR    ;
    				default: state	<=	STOP;
    				endcase
    			end
    		CLEAR:begin
    //清屏
    				cnt		<=  32'b0; 
    				lcd_rs  <=  1'b0;
    				lcd_data<=	8'h01;
    				case(key)
    					4'b1110:state	<=	LEFT    ;
    					4'b1101:state	<=	RIGHT   ;
    					4'b1011:state	<=	STOP    ;
    					4'b0111:state	<=	CLEAR    ;
    				default: 	state	<=	CLEAR;
    				endcase
    			end
    		default:state <= 4'd0;
    		endcase
    end
    always @(*) begin
    //第一行数据显示“hello chengdu”
    	case(char_cnt)
    		5'd0: data_display1   = "h";
    		5'd1: data_display1   = "e";
    		5'd2: data_display1   = "l";
    		5'd3: data_display1   = "l";
    		5'd4: data_display1   = "o";
    		5'd5: data_display1   = " ";
    		5'd6: data_display1   = "c";
    		5'd7: data_display1   = "h";
    		5'd8: data_display1   = "e";
    		5'd9: data_display1   = "n";
    		5'd10: data_display1  = "g";
    		5'd11: data_display1  = "d";
    		5'd12: data_display1  = "u";
    		5'd13: data_display1  = "-";
    		5'd14: data_display1  = "-";
    		5'd15: data_display1  = "-";
    //第二行数据显示“---2021-03-15---”
    		5'd16: data_display2  = "-";
    		5'd17: data_display2  = "-";
    		5'd18: data_display2  = "-";
    		5'd19: data_display2  = "-";
    		5'd20: data_display2  = "2";
    		5'd21: data_display2  = "0";
    		5'd22: data_display2  = "2";
    		5'd23: data_display2  = "1";
    		5'd24: data_display2  = "-";
    		5'd25: data_display2  = "0";
    		5'd26: data_display2  = "3";
    		5'd27: data_display2  = "-";
    		5'd28: data_display2  = "1";
    		5'd29: data_display2  = "5";
    		5'd30: data_display2  = "-";
    		5'd31: data_display2  = "-";
    		default:begin
    				data_display1 = "-";
    				data_display2 = "-";
    				end
    	endcase
    end
    endmodule
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
  • 相关阅读:
    Vue 3中toRaw和markRaw的使用
    2023-11 | 短视频批量下载/爬取某个用户的所有视频 | Python
    docker和docker compose安装使用、入门进阶案例
    Goby 漏洞发布|Cockpit 平台 upload 文件上传漏洞(CVE-2023-1313)
    数字图像处理(十六)非局部均值去噪
    基于HTML仿oppo手机商城电商项目的设计与实现6个页面
    Spring Boot-3-AbstractApplicationContext
    对象切割时虚指针VPTR探索
    计算机毕业设计Python+djang基于大数据的应届生求职系统(源码+系统+mysql数据库+Lw文档)
    电脑电源灯一闪一闪开不了机怎么办
  • 原文地址:https://blog.csdn.net/qq_22592979/article/details/128073753