基于FPGA的LCD1602驱动(含代码)

2023-11-12

目录

 LCD1602显示原理

LCD1602接口

LCD1602操作时序

(1)读操作时序

(2)写操作时序

 LCD1602初始化

LCD1602读写数据 


 LCD1602显示原理

将LCD显示屏与FPGA连接之后,需要做的第一件事就是进行LCD驱动(也就是LCD初始化),之后往LCD里写一些字符,调试LCD是否可以正常使用

这里用的是LCD1602如下图:一共2行,一行16个显示块,其地址和屏幕的对应关系如下:

 如果想在屏幕左上角显示字符‘A’,那么就把字符‘A’的字符代码41H写入DDRAM的00H地址处即可

但如果要显示CGROM中没有的字符,比如摄氏温标的符号,那么就只有先在CGRAM中定义,然后再在DDRAM中写入这个自定义字符的字符代码即可。具体参考这篇:基于FPGA的LCD1602显示屏驱动_panhongfeng111的博客-CSDN博客_基于fpga的lcd显示

LCD1602接口

 对这里面比较重要的几个接口进行说明:

(1)RS 命令/数据选择引脚当RS为低电平时,选择命令;当RS为高电平时,选择数据。

(2)RW 读/写选择引脚,当RW为低电平时,向LCD1602写入命令或数据;当RW为高电平时,从LCD1602读取状态或数据。如果不需要进行读取操作,可以直接将其接VSS。

(3) 执行命令的使能引脚。

(4)D0—D7 并行数据输入/输出引脚

LCD1602操作时序

(1)读操作时序

读状态:输入RS=0,RW=1,E=高脉冲。输出:D0—D7为状态字。

读数据:输入RS=1,RW=1,E=高脉冲。输出:D0—D7为数据。

(2)写操作时序

 写命令:输入RS=0,RW=0,E=高脉冲。输出:无。

 写数据:输入RS=1,RW=0,E=高脉冲。输出:无。
 

 LCD1602初始化

根据数据手册,LCD的初始化需要完成下面12步:

1   延时15ms
2   写指令38H(不检测忙信号)
3   延时5ms
4   写指令38H(不检测忙信号)
5   延时5ms
6   写指令38H(不检测忙信号)
7   以后每次写指令、读/写数据操作均需要检测忙信号
8   写指令38H:显示模式设置
9   写指令08H:显示关闭
10  写指令01H:显示清屏
11  写指令06H:显示光标移动设置
12  写指令0CH:显示开及光标设置

 这里面有1次15ms延时,和2次5ms延时,写指令是38H,我们可以把1~8步合在一起,延时25ms,写指令38H,那么初始化就可以简化为5步:

LCD1602读写数据 

初始化完成之后一般往LCD里写入一些字符串,验证一下是否可以正常显示

写的时候,要先指定地址,如果在第一行写入,首地址是00H,再加上DB7的1,即80H

如果在第二行写入,首地址是40H,再加上DB7的1,即C0H

因此在初始化完成之后,加入addr1 write1 addr2 write2 四个状态

把写数据和初始化放在一起,完整状态机如下:

module lcd(
  input				clk			,
	input				rst	,
	input      delay_en ,    //延时完成
	output	reg			lcd_rs		,//状态or数据选择
	output	reg		lcd_rw		,//读or写选择
	output	reg			lcd_en		,//使能信号
	output	reg	[7:0]	lcd_data //输出LCD指令
    );
    
    
    reg	[7:0]	data_display	;//显示数据
    
    reg [5:0] data_cnt; //数据计数器
    
    reg [3:0] state; //状态
    
    parameter IDLE =4'd0;
    parameter S0   =4'd1;
    parameter S1   =4'd2;
    parameter S2   =4'd3;
    parameter S3   =4'd4;
    parameter S4   =4'd5;
    parameter Addr1=4'd6;
    parameter WR1  =4'd7;
    parameter Addr2=4'd8;
    parameter WR2  =4'd9;
    parameter stop =4'd10;
    
  always @(*) begin//根据数据计数器输出显示数据
		case(data_cnt)
			5'd0: data_display   = "H";
			5'd1: data_display   = "E";
			5'd2: data_display   = "L";
			5'd3: data_display   = "L";
			5'd4: data_display   = "O";
			5'd5: data_display   = "W";
			5'd6: data_display   = "-";
			5'd7: data_display   = "W";
			5'd8: data_display   = "O";
			5'd9: data_display   = "R";
			5'd10: data_display  = "L";
			5'd11: data_display  = "D";
			5'd12: data_display  = "1";
			5'd13: data_display  = "6";
			5'd14: data_display  = "0";
			5'd15: data_display  = "2";
			5'd16: data_display  = "h";
			5'd17: data_display  = "e";
			5'd18: data_display  = "l";
			5'd19: data_display  = "l";
			5'd20: data_display  = "o";
			5'd21: data_display  = "w";
			5'd22: data_display  = "h";
			5'd23: data_display  = "e";
			5'd24: data_display  = "l";
			5'd26: data_display  = "l";
			5'd27: data_display  = "o";
			5'd28: data_display  = "w";
			5'd29: data_display  = "-";
			5'd30: data_display  = "-";
			5'd31: data_display  = "-";

			default:data_display = "-";
		endcase
	end
  
  always@(posedge clk)begin
  	if(rst)begin
  		lcd_rs  <=1'd0;
      lcd_rw  <=1'd0;
      lcd_en  <=1'd0;
      lcd_data<=8'd0;
      data_cnt<=6'd0;
      state   <=IDLE;
  	end
  	else begin
  		case(state)
  			IDLE :begin
  				if(delay_en)begin
  					state   <=S0;
  				end
  				else begin
  					state   <=IDLE;
  				end
  			end
        S0 :begin
  				lcd_rs  <=1'd0;
          lcd_rw  <=1'd0;
          lcd_en  <=1'd1;
          lcd_data<=8'h38;
          state   <=S1;
  			end  
        S1  :begin
  				lcd_rs  <=1'd0;
          lcd_rw  <=1'd0;
          lcd_en  <=1'd1;
          lcd_data<=8'h08;
          state   <=S2;
  			end 
        S2  :begin
  				lcd_rs  <=1'd0;
          lcd_rw  <=1'd0;
          lcd_en  <=1'd1;
          lcd_data<=8'h01;
          state   <=S3;
  			end 
        S3  :begin
  				lcd_rs  <=1'd0;
          lcd_rw  <=1'd0;
          lcd_en  <=1'd1;
          lcd_data<=8'h06;
          state   <=S4;
  			end 
        S4 :begin
  				lcd_rs  <=1'd0;
          lcd_rw  <=1'd0;
          lcd_en  <=1'd1;
          lcd_data<=8'h0C;
          state   <=Addr1;
  			end
        Addr1:begin
  				lcd_rs  <=1'd0;
          lcd_rw  <=1'd0;
          lcd_en  <=1'd1;
          lcd_data<=8'h80;//第一行地址
          state   <=WR1;
  			end
        WR1 :begin
  				lcd_rs  <=1'd1;
          lcd_rw  <=1'd0;
          lcd_en  <=1'd1;
          
          if(data_cnt==6'd15)begin//第一行写完
          	state   <=Addr2;
          	data_cnt<=6'd0;
          end
          else begin
          	data_cnt<=data_cnt+6'd1;
          	state   <=WR1;
          	lcd_data<=data_display;//显示第一行数据
          end
  			end 
        Addr2:begin
  				lcd_rs  <=1'd0;
          lcd_rw  <=1'd0;
          lcd_en  <=1'd1;
          lcd_data<=8'hC0;//第二行地址
          state   <=WR2;
  			end
        WR2 :begin
  				lcd_rs  <=1'd1;
          lcd_rw  <=1'd0;
          lcd_en  <=1'd1;
         
          if(data_cnt==6'd15)begin//第二行写完
          	state   <=stop;
          	data_cnt<=6'd0;
          end
          else begin
          	data_cnt<=data_cnt+6'd1;
          	lcd_data<=data_display;//显示第二行数据
          	state   <=WR2;
          end
  			end 
        stop :begin
  				lcd_rs  <=1'd0;
          lcd_rw  <=1'd0;
          lcd_en  <=1'd0;
          lcd_data<=8'h38;
          state   <=IDLE;
  			end

  		endcase
  	end
  end
    
endmodule

仿真结果如下:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于FPGA的LCD1602驱动(含代码) 的相关文章

  • Quartus II 安装

    本次介绍使用的 Quartus 版本为 10 1 目前 Quartus II 官网已经没有 13 1 以下版本的安装包 大家可以安装 13 1 以上版本的软件 功能都是大同小异 下载地址 FPGA Software Download Cen
  • PRBS笔记

    1 概述 PRBS 伪随机二进制序列 也称为伪随机码 通常被用来测试高速信号的信号质量 伪随机 也说明了该码流并不是真正的随机 而是具有特性属性 码流由 多项式 决定 具有重复周期 PRBS具有多种阶数 如PRBS7 PRBS15 PRBS
  • 各种FIFO硬件设计(FIFO概念、异步、同步、非2次幂深度FIFO)

    文章目录 一 FIFO概述 二 FIFO分类 三 FIFO重要信号与参数 3 1 信号 3 2 参数 3 2 1 data depth的确定 四 FIFO存储原理 五 同步FIFO 5 1 空满信号判断 5 2 同步FIFO源码 5 3 测
  • Verilog的奇技淫巧[更新中]

    1 Verilog常用的数据选择语句vect a b 或vect a b 转载自 MDY常用的数据选择语句Verilog明德扬论坛 Powered by Discuz vect为变量名字 a为起始位置 加号或者减号代表着升序或者降序 b是进
  • J-Link仿真器与JTAG和SWD下载与接线

    目录 1 JTAG 1 1JTAG今天被用来主要的三大功能 1 2JTAG引脚 1 3可选引脚 2 SWD 2 1 SWD引脚 2 2 可选择引脚 2 3 JTag和SWD模式引脚定义 3 J Link仿真器 4 IAR与MDK配置两种下载
  • 【科普】波特率和比特速率的理解

    什么是波特率 单位时间内传输的码元个数称为波特率 单位为 Baud 那码元又是什么呢 码元又称为 符号 即 symbol 维基百科上对码元的解释 持续一段固定时间的通信信道有效状态就是码元 这么解释比较抽象 可以解释码元的物理意义 在通信信
  • verilog中wire和reg类型的区别

    module counter parameter CNT MAX 25 d24 999 999 input wire sys clk input wire sys rst n output reg led out reg 24 0 cnt
  • 最详细的Vivado安装教程

    V i v a d o 安 装
  • 数码管电子时钟

    文章目录 前言 一 回顾数码管 二 任务描述 三 系统框图 四 模块调用 五 模块原理图 六 工程源码 6 2 时钟计数模块代码 6 2 数码管驱动模块代码 6 3 顶层模块代码 七 仿真测试 7 1 测试代码 7 2 仿真结果 八 管脚信
  • Verilog实现两路组相联cache

    cache代码 timescale 1ns 1ps cache共32块 分为16组 每组2块 即两路组相联 1块 4字 1字 4字节 主存共1024块 4096个字 主存地址共12位 1 0 为块内偏移 5 2 为组地址 11 6 为Tag
  • 握手2倍速率进,一倍速率出[verilog]

    module two to one parameter WORD LEN 33 input clk input arst input 2 WORD LEN 1 0 i din input i din valid output o din r
  • IC数字后端

    在 innovus 里面 有时候我们需要控制 tie cell 的 fanout 和 net length 来避免 tie cell 可能出现 max transition 或者 max fanout 的违例 一般来说 只要 fanout
  • 【FPGA】通俗理解从VGA显示到HDMI显示

    注 大部分参考内容来自 征途Pro FPGA Verilog开发实战指南 基于Altera EP4CE10 2021 7 10 上 贴个下载地址 野火FPGA Altera EP4CE10征途开发板 核心板 野火产品资料下载中心 文档 hd
  • 【电子技术】什么是LFSR?

    目录 0 前言 1 数学基础 1 1 逻辑异或 1 2 模2乘法 和 模2除法 2 线性反馈移位寄存器LFSR 3 抽头和特征多项式 4 阶线性反馈移位寄存器实例 0 前言 线性反馈移位寄存器 Linear Feedback Shift R
  • 【FPGA多周期时序约束详解】- 解读FPGA多周期时序约束的全过程

    FPGA多周期时序约束详解 解读FPGA多周期时序约束的全过程 FPGA作为数字电路设计的常见工具 其设计中必然会遇到时序约束的问题 而多周期时序约束更是FPGA设计中不可避免的难点之一 本文将详细介绍FPGA多周期时序约束的全过程 并结合
  • 【ZYNQ学习】PL第一课

    这节课讲什么 这节课的名字本来是想写为LED 但这一课里除了LED也有按键 又想换为GPIO控制 但关于PL的GPIO控制 不应该这么草率和简单 而且这一课有很多和ZYNQ或者PL关联性不强的东西要说 所以我写了删删了写改了好几遍 终于定为
  • 无线网络管理系统与无线路由器的区别

    第5章 波形发生器软件设计 本章我们将介绍系统的软件设计 系统中控制软件占有很重要的地位 它不仅要产生波形数据 控制波形的发生 还要控制显示电路和键盘电路 因此系统软件的好坏直接决定着系统的功能和稳定 5 1软件的总体结构 在本系统中 由于
  • [Verilog] Verilog 基本格式和语法

    主页 元存储博客 全文 3000 字 文章目录 1 声明格式 1 1 模块声明 1 2 输入输出声明 1 3 内部信号声明 1 4 内部逻辑声明
  • Vivado ILA的debug信息保存与读取

    保存 write hw ila data D Project FPGA ILA Debug Data 202401041115 ila upload hw ila data hw ila 1 读取 display hw ila data r
  • ESP10B 锁定连接器

    ESP10B 锁定连接器 ESP10B 电机新增内容包括双极型号标准 NEMA 尺寸 17 23 和 34 的步进电机现在包括输出扭矩范围从 61 盎司英寸到 1291 盎司英寸的双极型号 该电机配有带锁定连接器的尾缆 可轻松连接 每转可步

随机推荐

  • 测试类型分类

    测试类型 按方向 功能测试 性能测试 安全测试 兼容性测试 安装测试等 按阶段 单元测试 集成测试 系统测试 验收测试 按测试技术 黑盒测试 白盒测试 灰盒测试 按是否运行 静态测试 动态测试 其他 手工测试 自动化测试 冒烟测试 回归测试
  • 如何优雅的快速下载谷歌云盘的大文件 (一)

    一 注册MultCloud 官网地址 不让放网址 注册好了之后要在邮箱收一个激活链接 然后就可以登陆网页版了 二 加入云盘 点击云管理器 点击添加云盘 我们以从谷歌 百度作为示例 由于BaiDu云盘的限制 只能操作 我的应用数据 gt li
  • uni-app从入门到实战

    前些天发现了一个巨牛的人工智能学习网站 通俗易懂 风趣幽默 忍不住分享一下给大家 点击跳转到网站 uni app是啥 uni app是一个使用vue js来开发所有前端应用的框架 开发者开发一套代码可以发布到os 安卓 h5等各种小程序 u
  • notepad++ 文本文件内容丢失恢复

    今天用着notepad 不知道怎的 突然就崩溃了 然后我下次打开的时候弹了个框 我按了OK之后 里面所有的内容都不见了 网上百度了半天 总结如下 在如下目录下有notepad 会自动保存的文件 C Users Administrator A
  • mysql编码设置

    mysql 创建 数据库时指定编码很重要 很多开发者都使用了默认编码 乱码问题可是防不胜防 制定数据库的编码可以很大程度上避免倒入导出带来的乱码问题 网页数据一般采用UTF8编码 而数据库默认为latin 我们可以通过修改数据库默认编码方式
  • spring-mvc Restful风格

    Restful风格 概念 Restful就是一个资源定位及资源操作的风格 不是标准也不是协议 只是一种风格 基于这个风格设计的软件可以更简洁 更有层次 更易于实现缓存等机制 对比 之前controller类的写法 resource文件里存在
  • 创建conda环境配置出现conda env create -f environment.yml报错解决办法

    解决gitub项目conda创建环境environment yml出现的Solving environment failed 和 ResolvePackageNotFound错误的解决办法记录 问题 创建conda环境配置输入 conda
  • unity水特效与标准资源包的下载导入

    由于本个实例需要使用unity的标准资源包 一 方法一 1 进入unity官网 https unity cn 2 点击页面的Beta版本 3 找到对应自己版本下载即可 方法二 在unity中的商店中搜索 Standard Asset下载导入
  • 西门子PLC常用通信协议以及常用协议的区别(一)

    RS232 是硬件接口 描述 是目前最常用的串行通信接口 RS232 C只是表示RS232的版本 简称都是一样的 特性 标准接口采用9针或者25针D型接口 常用的一般是9针接口 因为大部分连接不需要使用对方的传送控制信号 只需要三条线 即发
  • 2020Unity中文项目用Vs2019打开脚本后一直Importing assets

    unity2018就不会有这个问题 而且我的External Script Editor 都设置的没有问题 新建一个项目中文名 在不用vs2019打开脚本之间都不会有这个进度条 一打开后就会有 高级编码设置的Unicode8 也不起作用了
  • 嘉立创PCB CAM软件

    概述 在PCB CAM软件中 Genesis2000 UCAM CAM350等国外软件占了大壁江山 其中的Genesis2000更是占了绝对份额 而中国却没有一款成熟可用的PCB CAM工业软件 根据公开资料显示 中国是PCB的制造大国 2
  • 快速学习Flutter

    文章目录 写在前面 Flutter官网 Flutter基本知识 Flutter 的特性 Flutter Windows环境搭建 查看文档时有几点注意 1 中国镜像地址 2 搭建 Android 开发环境 3 Flutter SDK Flut
  • MyCAT实现MySQL的读写分离

    在MySQL中间件出现之前 对于MySQL主从集群 如果要实现其读写分离 一般是在程序端实现 这样就带来一个问题 即数据库和程序的耦合度太高 如果我数据库的地址发生改变了 那么我程序端也要进行相应的修改 如果数据库不小心挂掉了 则同时也意味
  • 全排列、子集合subset、目标和combation、树的路径和问题

    主要的方法 深度优先搜索 回溯算法 宽度优先搜索 是否有相同元素需要考虑等问题 针对所给问题 确定问题的解空间 首先应明确定义问题的解空间 问题的解空间应至少包含问题的一个 最优 解 确定结点的扩展搜索范围 for等一系列循环等问题 以深度
  • matlab如何读取一个文件夹下所有文件,Matlab获取一个文件夹下所有文件名

    Matlab获取一个文件夹下所有文件名 fileFolder fullfile D MATLAB bin trc dirOutput dir fullfile fileFolder trc fileNames dirOutput name
  • 解决IDEA中ctrl+shift+f快捷键搜索没反应的问题

    文章目录 0写在前面 1 问题解决 1 1 直接切换英文输入法 1 2 win10 输入法 1 3 搜狗输入法 1 4 其他 2 写在末尾 0写在前面 今天想使用 在文件中查询 功能 使用ctrl shift f进行搜索的时候 疯狂的按组合
  • keil CMSIS_DAP.DLL missing

    由于keil版本支持问题 可以下载以下版本的CMSIS DAP DLL进行替换 CMSIS DAP DLL官方下载地址 百度云下载 提取码 g8ia keil安装目录如 D Keil v5 ARM BIN 先删除原来的CMSIS DAP D
  • MySQL存储过程遍历游标用loop嵌套循环的例子

    CREATE DEFINER root PROCEDURE procInitData IN sId1 INT IN sId2 INT IN sId3 INT IN sId4 INT IN sId5 INT IN sId6 INT IN sI
  • 函数调用约定cdecl、stdcall、fastcall

    我们在编写代码的时候都会调用函数 有点函数有多个参数 例如 int test int a char b char c 上面的函数调用方式是test 10 c tinus 那么这个函数编译器是怎么知道有多少个参数 参数类型是什么了 因为函数调
  • 基于FPGA的LCD1602驱动(含代码)

    目录 LCD1602显示原理 LCD1602接口 LCD1602操作时序 1 读操作时序 2 写操作时序 LCD1602初始化 LCD1602读写数据 LCD1602显示原理 将LCD显示屏与FPGA连接之后 需要做的第一件事就是进行LCD