FPGA笔记(八)-驱动12864

最近俩天由于要求所致,必须马上要会使用FPGA驱动12864和驱动矩阵键盘,虽然之前用C51做过这类驱动,毕竟不一样,所以时间上也是很匆忙。通过各种网上找资料和实验,今天算是完成了LCD12864的驱动的学习。赶紧做个笔记巩固一下!

要驱动12864首先得它的datasheet,看明白主要的几个问题:

1、LCD的时钟频率所在范围。(FPGA一般都是20M、50M及以上晶振,太大导致LCD无法响应过来)下图为RT12864-s液晶的所需时钟频率

范围为470KHZ-590KHZ。(如果小了的话也没关系,只不过是显示的时候一个字一个字的显示出来,而不是人眼察觉不到地整篇出现)

2、整个的工作流程。(初始化->写数,从而可以用状态机来描述)

我记得在单片机里驱动液晶的话,是这样的

把写命令和写数据的指令的时序和RW、RS、EN设置好,方便后续调用

void write_data(int data)

{

。。。。

。。。。

}

void write_com(int com)

{

。。。。

}

//设置好初始化的指令

void initialLCD_12864()

{

write_com(0x80);

。。。。。等等一些列的初始化指令

}

FPGA驱动液晶显示,也差不多,一样是得先初始化后再进行写数字,只不过是用状态机来实现这一顺序的过程,啥也不用多说,看程序吧。

module Lcd12864(//针对型号为RT12864-Sinput Sys_Clk,input Rst,output reg LCD_RS,output LCD_RW,output LCD_E,output reg [7:0]LCD_Data//      output PSB//串并控制端口,H为并行,L为串行,直接接5v//     output LCD_Rst,//液晶的复位端口,低电平有效//由于端口不够,暂时让其悬空);reg LCD_Clk;reg[7:0] state;//状态机寄存器reg [23:0] cnt;//计数器reg flag;//显示完成标志reg[5:0]char_cnt;reg[7:0]data_disp;//一个字节是八位,一个英文字符是一个字节,中文是俩个字节parameter T500KHZ=24'd49999;//    parameter T500KHZ=24'd24_999_999;//测试低频现象//   parameter T500KHZ=24'd24_9;//仿真专用//首先先对系统频率分频,液晶所需频率不用这么高,但是是多少呢?由datasheet可得出该液晶的最大频率是590kHZ//典型值为530KH,为了好算取个值500KHZ,50M/500KHZ=10HZ,计数5M/2变化一次方向always@(posedge Sys_Clk or negedge Rst)beginif(!Rst)begincnt<=24'd0;LCD_Clk<=1'b0;endelse  if(cnt==T500KHZ)begincnt<=24'd0;LCD_Clk<=~LCD_Clk;endelsecnt<=cnt+1'b1;end//state machine description,8个状态 只要用把位二进制就可以全部表示parameter IDLE=8'b00_000_000;//初始状态parameter SETFUNCTION=8'b00_000_001;//功能设置,8-bit+基本指令集0x30//  parameter SETFUNCTION2=8'b00_000_010;//同上parameter SWITCHMODE=8'b00_000_100;//设置显示开和光标闪烁关闭parameter CLEAR=8'b00_001_000;//清屏操作parameter SETMODE=8'b00_010_000;//点设置parameter SETDDRAM=8'b00_100_000;//起始行设置parameter WRITERAM=8'b01_000_000;//写设置parameter STOP=8'b10_000_000;//LCD操作停止,释放其控制initialbegincnt=24'd0;state=IDLE;flag=1'b1;LCD_Clk=1'b10;char_cnt=6'd0;data_disp=8'd32;end//设置好RS、RW、Ealways@(posedge LCD_Clk or negedge Rst)beginif(!Rst)LCD_RS<=1'b0;else  if(state==WRITERAM)LCD_RS<=1'b1;elseLCD_RS<=1'b0;end//如果定义了LCD_Rst俩个端口的话,可做如下设置//assign LCD_Rst=1'b1;//assign PSB=1'b1;assign LCD_RW=1'b0;//只是写操作,不需要读操作assign LCD_E=(flag==1)?LCD_Clk:1'b0;//使能信号与液晶时钟同步//descible the state machinealways@(posedge LCD_Clk or negedge Rst)beginif(!Rst)beginstate<=IDLE;LCD_Data<=8'bzz_zzz_zzz;endelsebegincase(state)IDLE:beginstate<=SETFUNCTION;LCD_Data<=8'h30;endSETFUNCTION:beginstate<=SWITCHMODE;//   state<=SETFUNCTION2;LCD_Data<=8'h30;end//      SETFUNCTION2://         begin   //                  state<=SWITCHMODE;//                    LCD_Data<=8'h30;//         endSWITCHMODE:beginstate<=CLEAR;LCD_Data<=8'h0c;//显示设置,全显示开,光标和闪烁关endCLEAR:beginstate<=SETMODE;LCD_Data<=8'h01;//清屏、endSETMODE:beginstate<=SETDDRAM;LCD_Data<=8'h06;//点设置,光标右移,地址加一,整体不动endSETDDRAM://设置起始位置beginstate<=WRITERAM;if(char_cnt==6'd0)LCD_Data<=8'h80;//line1elseLCD_Data<=9'h90;//line2endWRITERAM:beginif(char_cnt<=6'd11)beginchar_cnt<=char_cnt+1'b1;LCD_Data<=data_disp;if(char_cnt==6'd11)state<=SETDDRAM;//第一行写完后从新返回设置地址elsestate<=WRITERAM;endelse if(char_cnt>=6'd12&&char_cnt<=6'd25)beginif(char_cnt==6'd25)beginstate<=STOP;char_cnt=6'd0;flag<=1'b0;endelsebegin  LCD_Data<=data_disp;//不管到没到第25个都要继续写数state<=WRITERAM;char_cnt<=char_cnt+1'b1;endendendSTOP:       state<=STOP;default: state<=IDLE;endcaseend         endalways@(char_cnt)begincase(char_cnt)6'd0:data_disp="G";6'd1:data_disp="U";6'd2:data_disp="X";6'd3:data_disp="I";6'd4:data_disp="A";6'd5:data_disp="N";6'd6:data_disp="Y";6'd7:data_disp="I";6'd8:data_disp="L";6'd9:data_disp="C";6'd10:data_disp="D";6'd11:data_disp="!";6'd12:data_disp="H";6'd13:data_disp="E";6'd14:data_disp="L";6'd15:data_disp="L";6'd16:data_disp="O";6'd17:data_disp="E";6'd18:data_disp="V";6'd19:data_disp="E";6'd20:data_disp="R";6'd21:data_disp="Y";6'd22:data_disp="O";6'd23:data_disp="N";6'd24:data_disp="E";//        default:data_disp=8'h32;endcaseendendmodule

我所使用的12864型号为RT12864-S,各个引脚功能如下

所以可以清楚的看到RS、RW、EN等引脚的使用方法

我从这个时序图看到了只有当RS=H,RW=L,在一个使能周期内完成数据的读取,也就是说使能信号是一个周期信号

对于程序中的assign LCD_E=(flag==1)?LCD_Clk:1'b0;//使能信号与液晶时钟同步。

程序中来看状态机大概就是这样一个流程(开始->设置8bit控制+基本指令集(0x30)->设置全显示开、光标关、闪烁关(0x0c)->清屏(0x01)->设置输入方式,数据读写后,光标右移,地址加一,整体画面不动(0x06)->设置写数的起始地址(0x80、0x90、0x88,0x98)->写数(对应ASCI来写字符)->结束),我就懒得去画图了,凑合看吧,饿死我了!

最后再想,既然初始化都是顺序执行,为什么还要状态机,在一个begin-end内不就完成了初始化吗?(如果你这么想,那么请看上述时序图,不管是写数还是写命令都是在一个使能周期内完成的,而这个周期是有时间限制的,而不是俩句程序语句之间的时间周期)

看一下仿真图就更加清晰明了了。任何操作都是一步一步来的,一个使能周期内只能写一次数据或命令

对应这看这些二进制数(三个使能周期的00110000(0x30)(分别是initial+SETFUNCTION+SETFUNCTION2),而后是00001100(0x0c)依次一下。。。。),时序上面完全符合。

其实我很想知道为什么要俩个SETFUNCTION状态,只不过是多了一个周期的0x30指令而已,于是我把SETFUNCTION2这个状态去掉了,看看情况,结果液晶一样能正常显示出数!如网上所写的程序,说第二个SETFUNCTION2给的数(0x30)是清屏操作,很明显看datasheet里的基本指令集所写更本不是什么清屏指令,只是指明8-bit控制和指令集是基本指令集

一样是可以的,所以学习不是拿来主义,多问一句为什么,可以让我学到更多的东西,更希望把它变为自己的东西。而不是下次还得抄袭。

FPGA笔记(八)-驱动12864相关推荐

  1. 170504_(读书笔记)ST7920驱动12864液晶模块学习

    学习芯片,应该以数据手册为主,书本为辅,学习ST7920驱动芯片手册地址 ST7920手册 先把手册看一遍,不求快,只求弄懂 170514: 1.ST7920数据手册看了两遍,但是还是不太清楚具体操作 ...

  2. FPGA学习笔记(八):ASK调制解调的仿真

    笔记八是ASK调制解调的仿真实现. ASK调制解调的实现原理:首先使用MATLAB产生存储基带波形的coe文件,再让ROM读取coe文件输出基带波形,然后DDS产生正弦波信号作为载波信号,接下来使用乘 ...

  3. 读书笔记:详解FPGA人工智能的驱动引擎(石侃)

    最近读了一本关于我偶像的一本书,知名up主老石的一本书<详解FPGA人工智能的驱动引擎>,这本书写了老石对FPGA的一些心得和行业总结,个人觉得写的非常不错,第一次看还是有点难以深刻理解, ...

  4. FPGA笔记之verilog语言(基础语法篇)

    文章目录 FPGA笔记之verilog语言(基础语法篇) 1. verilog 的基础结构 1.1 verilog设计的基本单元--module 1.2 module的使用 1.3 I/O的说明 1. ...

  5. 爬虫笔记八----selenium

    爬虫笔记八 来自风变编程 在爬虫过程中,我们还可能会遇到各种各样棘手的问题-- 有的网站登录很复杂,验证码难以破解,比如大名鼎鼎的12306. 有的网站页面交互复杂,所使用的技术难以被爬取,比如,腾讯 ...

  6. ReactJS学习笔记八:动画

    ReactJS学习笔记八:动画 分类: react学习笔记 javascript2015-07-06 20:27 321人阅读 评论(0) 收藏 举报 react动画 目录(?)[+] 这里只讨论Re ...

  7. 【opencv学习笔记八】创建TrackBar轨迹条

    createTrackbar这个函数我们以后会经常用到,它创建一个可以调整数值的轨迹条,并将轨迹条附加到指定的窗口上,使用起来很方便.首先大家要记住,它往往会和一个回调函数配合起来使用.先看下他的函数 ...

  8. 吴恩达《机器学习》学习笔记八——逻辑回归(多分类)代码

    吴恩达<机器学习>笔记八--逻辑回归(多分类)代码 导入模块及加载数据 sigmoid函数与假设函数 代价函数 梯度下降 一对多分类 预测验证 课程链接:https://www.bilib ...

  9. python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑

    python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑 许多人在安装Python第三方库的时候, 经常会为一个问题困扰:到底应该下载什么格式的文件? 当我们点开下载页时, 一 ...

  10. (38)FPGA数码管驱动设计(第8天)

    (38)FPGA数码管驱动设计(第8天) 1 文章目录 1)文章目录 2)FPGA初级课程介绍 3)FPGA初级课程架构 4)FPGA数码管驱动设计(第8天) 5)技术交流 6)参考资料 2 FPGA ...

最新文章

  1. 排名前 16 的 Java 工具类,哪个你没用过?
  2. 查看详细_丹江口EH油泵入口滤芯W.38.B.0035_滤芯详细查看
  3. 锁类型_ sys.dm_os_wait_stats
  4. 第三章 dubbo内核之ioc源码解析
  5. Mybatis查询日期范围
  6. 机器学习导论(张志华):多元高斯分布
  7. XCTF-Reverse:python-trade
  8. node 调用腾讯大数据接口
  9. MyBatis 缓存详解-缓存体系结构
  10. ElasticSearch对地理数据查询(二)
  11. python文件处理seek()方法的参数是,在Python中操作文件之seek()方法的使用教程
  12. ICallbackEventHandler不支持二次回调的问题
  13. web端log4net输出错误日志到mysql
  14. ajax php cookie,php setcookie没有使用ajax调用
  15. 潭州课堂25班:Ph201805201 tornado 项目 第八课 增加喜欢功能(课堂笔记)
  16. CSS-四种引入方式
  17. 阿里云centos7上yum安装并连接mysql
  18. Linux 用户空间审计系统
  19. Linux下安装Nginx与配置
  20. python爬虫淘宝评论图片_淘宝上的图片是怎么被爬取的

热门文章

  1. 如何将录屏转换为高清GIF
  2. 搭建测试环境如何配置软件,软件测试环境的搭建(Windows版)
  3. 音频测试方法(tiny)
  4. 考研心得--一个差劲的ACMer
  5. 安卓linux关机命令行,linux定时关机命令?安卓定时关机命令?windows关机命令?Linux系统下定时关机命令shutdown...
  6. Linux上mysql忘记密码重置密码
  7. 机器学习项目简历收集册-----机器学习(仅供参考)
  8. 十个实用的谷歌搜索小技巧
  9. 看拉扎维《模拟CMOS集成电路设计》的一些总结和思考(三)——单级放大器
  10. 从零开始学sai,5天精通板绘基础