话不多说先上图

前言

在做这个实验的时候在网上找了许多资料,都是关于使用单片机驱动LCD显示,确实用单片机驱动是要简单不少,记得在FPGA学习交流群里问问题的时候,被前辈指教,说给我最好的指教便是别在玩这个了,多看看关于FPGA方面的书籍,比做这个单片机做的东西价值强多了。现在想来确实,自从学习FPGA以来,看过的书没有多少,只是想做个什么了,就在网上找找例程,照抄下来,把算法推理一遍,下个板子实现了,便以为自己会了懂了,要是自己在写一个便问题百出。那么菜鸟始终是菜鸟。自己根本没有掌握FPGA的设计思想和优势,用着FPGA做着单片机的东西,这种东西练练手就足够了,所以,做完这个实验LCD就到此为止了,我也要好好想想该如何进行下面的学习了。在这个上面我还是花费了不少时间,所以写一篇博文总结记录想,回头看的时候,以警醒自己。

摘要

做完这个实验我最大的感触是一定要会读数据手册。拿到元件(LCD12864),上面有16个的引脚,先要搞清楚每个引脚的功能,这时候就一定要会读数据手册。我个qc12864b的中文手册琢磨了很久才看懂了一些简单的操作指令,包括在手册上要提取出来,元件的驱动时序,扫描时钟,引脚定义,操作指令,功能描述等。

LCD显示原理

扫描时钟

      

  从手册上可以读出,qc12864b(这是我所使用LCD12864的型号)的扫描时钟介于470—590khz之间,最适为530khz,为了方便分频,所以取500khz。

 

引脚说明

  VSS        电源地,0v ­——接开发板GND就行

  VDD      电源正极(5v,3.3v)

  VO        液晶显示偏压,调整对比度

  RS         RS=1时,当mpu进行读模块操作,指向地址寄存器

          当mpu进行写模块操作,指向指令寄存器

  RS=0时,无论进行读/写操作,都指向数据寄存器

  R/W             高电平读操作,低电平写操作

  E           使能信号,高电平读取信息,下降沿执行命令

  DB0      数据总线第0位

  DB1      数据总线第1位

  DB2      数据总线第2位

  DB3      数据总线第3位

  DB4      数据总线第4位

  DB5      数据总线第5位

  DB6      数据总线第6位

  DB7      数据总线第7位

  PSB      串并控制端口,H为并行,L为串行,直接接5v

  RST       液晶复位端口,低电平有效

  A           背光正极输入,调整电压大小可以调整亮度

  K           背光负极输入,一般直接接地

指令说明

       具体指令说明,这里就不一一列出,可查阅qc12864b中文数据手册,我在阅读这一部分的时候耗费了很长时间,这些指令是驱动LCD显示文字与图片的核心,所以必须要掌握。

并口显示时序

Verilog实现方案

  从时序图可以看出在使能信号的一个周期内可以完成写入数据操作,扫描时钟与使能信号周期相同即可。

状态转移图

  状态机初始化位置          IDLE                            lcd_data = 8’hzz

  功能设计                          SETFUNCTION            lcd_data = 8’h36//扩充指令绘图显示

  显示设置                          SWITCHMODE           lcd_data = 8’h0c//显示状态

  清屏                                  CLEAR                       lcd_data = 8’h01//清零指令

  设置Y坐标                      SETDDRAM_Y

  设置X坐标                      SETDDRAM_X

  写入数据                          WRITERAM

  结束                                  STOP

 

绘图指令下的坐标图

代码如下

  1. module lcd_qc12864b(
  2. input mclk,
  3. input rst_n,
  4. output reg lcd_rs,//H读写数据,L指令
  5. output lcd_rw, //高电平读操作,低电平写操作
  6. output lcd_e,//使能信号高电平有效
  7. output reg [:]lcd_data,//八位数据总线
  8. output psb,//串并控制端口,H为并行,L为串行,直接接5v
  9. output lcd_rst//液晶的复位端口,低电平有效
  10. );
  11.  
  12. reg lcd_clk;//需要500khz频率的时钟
  13. reg [:] state;//状态机寄存器
  14. reg [:] cnt;//分频驱动12864计数器
  15. reg flag = 'b1;//显示完成标志
  16. reg [:] char_cnt;//
  17. wire [:] data_disp;//一个字节是八位,一个英文字符是一个字节,中文是俩个字节
  18. reg [:] cnt1;//行计数
  19.  
  20. parameter T500KHZ='d49999;
  21.  
  22. //分频500khz时钟
  23. always @(posedge mclk or negedge rst_n)
  24. begin
  25. if(!rst_n)begin
  26. lcd_clk <= 'b0;
  27. cnt <= 'd0;
  28. end
  29. else if(cnt == T500KHZ)begin
  30. cnt <= 'd0;
  31. lcd_clk <= ~lcd_clk;
  32. end
  33. else
  34. cnt <= cnt + 'd1;
  35. end
  36.  
  37. //状态机8个状态设置
  38. parameter IDLE = 'b00_000_000,//初始状态
  39. SETFUNCTION = 'b00_000_001,//功能设置
  40. SWITCHMODE = 'b00_000_010,//设置显示开和光标闪烁关闭
  41. CLEAR = 'b00_000_100,//清屏操作
  42. SETDDRAM_Y = 'b00_010_000,//设置y轴坐标
  43. SETDDRAM_X = 'b00_100_000,//设置x轴坐标
  44. WRITERAM = 'b01_000_000,//写设置写入寄存器
  45. STOP = 'b10_000_000;//LCD操作停止,释放其控制
  46.  
  47. //三段式书写状态机
  48. always @(posedge lcd_clk or negedge rst_n)
  49. begin
  50. if(!rst_n)
  51. lcd_rs <= 'b0;
  52. else begin
  53. if(state == WRITERAM)
  54. lcd_rs <= 'b1;//写数据模式
  55. else
  56. lcd_rs <= 'b0;//写命令模式
  57. end
  58. end
  59.  
  60. //lcd_rst始终为高电平,psb始终为低电平即可
  61. assign lcd_rst = 'b1;
  62. assign psb = 'b1;
  63. assign lcd_rw = 'b0;//只是写操作,不需要读操作
  64. assign lcd_e = (flag==)?lcd_clk:'b0;//使能信号与液晶时钟同步
  65.  
  66. always @(posedge lcd_clk or negedge rst_n)
  67. begin
  68. if(!rst_n)begin
  69. cnt1<= 'b0;
  70. state <= IDLE;
  71. lcd_data <= 'hzz;
  72. char_cnt <= 'd0;
  73. end
  74. else begin
  75. case(state)
  76. IDLE:begin
  77. state <= SETFUNCTION;//功能设置,8-bit+基本指令集0x30
  78. lcd_data <= 'h36;
  79. end
  80.  
  81. SETFUNCTION:begin
  82. state <= SWITCHMODE;//设置显示开和光标闪烁关闭
  83. lcd_data <= 'h36;
  84. end
  85.  
  86. SWITCHMODE:begin
  87. state <= CLEAR;
  88. lcd_data <= 'h3e;//显示设置,全显示开,光标和闪烁关
  89. end
  90. CLEAR:begin//清屏操作
  91. state <= SETDDRAM_Y;//点设置
  92. lcd_data <= 'h01;//清屏
  93. end
  94. SETDDRAM_Y:begin
  95. if(cnt1< )
  96. lcd_data <= 'h80 + cnt1;//80H~9fH
  97. else
  98. lcd_data <= 'h80 + (cnt1- 32); //80H~9fH
  99.  
  100. state <= SETDDRAM_X;
  101. end
  102. SETDDRAM_X:begin
  103. if(cnt1< )
  104. lcd_data <= 'h80; //80H
  105. else
  106. lcd_data <= 'h88; //88H
  107. state <= WRITERAM;
  108. end
  109. WRITERAM:begin
  110. lcd_data <= data_disp;
  111. char_cnt <= char_cnt + 'b1;
  112. if(char_cnt[:] == 'hf)begin //计算行
  113. cnt1<= cnt1+ 'b1;
  114. if(cnt1== )
  115. state <= STOP;
  116. else
  117. state <= SETDDRAM_Y;
  118. end
  119. else
  120. state <= WRITERAM;
  121. end
  122. STOP:begin
  123. flag <= 'b0;
  124. state <= STOP;//LCD操作停止,释放其控制
  125. end
  126. default: state <= IDLE;//回到初始状态
  127. endcase
  128. end
  129. end
  130.  
  131. // ROM
  132. rom U1_rom (
  133. .clka(mclk),
  134. .addra(char_cnt),
  135. .douta(data_disp)
  136. );
  137.  
  138. endmodule

lcd_qc12864b

配置ROM

  有分布式ROM/ROM和块ROM/RAM,这里配置的是块ROM/RAM。这两种方式具体我也不是了解很深,以后再深入学习。

该实验最让我头疼的是调用ROM,第一次接触IP核有许多地方都完全不懂。用LCD(带中文字库)显示文字的时候,可以直接输入文字的十六进制数值,设置显示地址坐标即可,12864显示原理点阵控制点的亮灭来实现,但是如果要显示图片的话一个个输入难免太过麻烦,这个时候调用ROM就方便许多。找一张或做一张像素为128x64的单色图片,使用取模软件,按c51的方式取模。取模出来的数据为十六进制,行8个,64个。

配置块RAM/ROM时,要加载的是.coe文件,所以需要将取模的十六进制数据保存到.coe文件中。最开始我一直在找如何能直接将图片取模出来的数据转化成.coe文件,试了很多方法都失败了,最后发现完全可以自己按文件格式编辑一个即可,最终文件保存格式如下。

  将图片取模出来的每个数据前的ox去掉,这只是C语言中16进制的表示形式,文件第一行的MEMORY_INITIALIZATION_RADIX=16;表示数据全都为16进制数,这里的16可以换成8、2、10都行。

打开ISE建立工程后,新建文件,选择IP(CORE Generator & Architecture Wizard),填写文件名,next

  找到Memories & Storage Elements单击,选择RAMs & ROMs单击,选择Block Memory Generator 7.3,next,finish。

  上面直接next,下面这里选Single Port ROM,next

  这里要填写数据位宽和深度,位宽是你所需要输出的数据位宽,LCD有8个数据位,故这里定义位宽为8,深度即有多少个这样的数据,从取模出来的数据看,易得共有1024个数据位。我使用的basys2开发板使用的是Xilinx Spantan3E—100TQ144 FPGA包含73728位的块RAM/ROM。因此,使用的块RAM的最大容量为9216字节或4608个16位字。从这里来看,是完全够用的。

  Next,加载.coe数据文件,勾选Load Init File 加载.coe文件,我这里是在桌面上保存着,直接找到选择就好。

  然后一直点击next直至最后一个界面,最后点击Generate,生成rom.xco。生成的IP核在工程目录下的ipcore_dir文件中。

  将rom.v文件打开端口定义如下,直接在顶层文件对其实例化,如代码所示

  最后可直接仿真,新建tb文件查看仿真传输数据是否正确。由波形图可得在功能设定指令传输完毕后,进入读数据状态,所读入的数据与文件中数据相符,一行数据传输完毕进入下一行,继续读入数据,仿真图结果正确。下板子也正确。

  最开始学习FPGA,最容易出现的就是两个问题,一个是把verilog当C语言来写,另一个就是把FPGA当单片机来用。前者我已经有了改善,后者我还需要继续努力。

转载请注明出处:NingHeChuan(宁河川)

个人微信订阅号:NingHeChuan

如果你想及时收到个人撰写的博文推送,可以扫描左边二维码(或者长按识别二维码)关注个人微信订阅号

知乎ID:NingHeChuan

微博ID:NingHeChuan

原文地址:http://www.cnblogs.com/ninghechuan/p/6340691.html

基于basys2驱动LCDQC12864B的verilog设计图片显示的更多相关文章

  1. 基于M9K块配置ROM的LCD12864图片显示实验

    先上传三张图片在说                             由于串口传输速度较慢,故此实验是在“LCD12864 液晶显示-汉字及自定义显示(并口)”基础上进一步修改而来.在写代码之前 ...

  2. 基于basys2用verilog设计多功能数字钟(重写)

    话不多说先上图         前言 自从学习FPGA以来,唯一做过的完整系统就是基于basys2得多功能数字表.记得当时做的时候也没少头疼,最后用时间磨出来了一个不是很完整的小系统,当时还是产生了满 ...

  3. 基于Basys2开发板的简易电子琴和音乐播放器设计

    背景:华中科技大学 电测综合实验 主要功能:Basys2开发板外接一个扬声器(或无源蜂鸣器也可)实现电子琴和音乐播放器的功能.其中由于开发板上只有4个按键,所以电子琴功能只做了4个音调,分别对应于4个 ...

  4. 【tornado】系列项目(一)之基于领域驱动模型架构设计的京东用户管理后台

    本博文将一步步揭秘京东等大型网站的领域驱动模型,致力于让读者完全掌握这种网络架构中的“高富帅”. 一.预备知识: 1.接口: python中并没有类似java等其它语言中的接口类型,但是python中 ...

  5. 基于AHB总线的master读写设计(Verilog)

    一.AHB总线学习 1. AHB总线结构 如图所示,AHB总线系统利用中央多路选择机制实现主机与从机的互联问题.从图中可以看出,AHB总线结构主要可分为三部分:主机.从机.控制部分.控制部分由仲裁器. ...

  6. 基于领域驱动设计(DDD)超轻量级快速开发架构(二)动态linq查询的实现方式

    -之动态查询,查询逻辑封装复用 基于领域驱动设计(DDD)超轻量级快速开发架构详细介绍请看 https://www.cnblogs.com/neozhu/p/13174234.html 需求 配合Ea ...

  7. 基于FPGA的XPT2046触摸控制器设计

    基于FPGA的XPT2046触摸控制器设计 小梅哥编写,未经许可,文章内容和所涉及代码不得用于其他商业销售的板卡 本实例所涉及代码均可通过向 xiaomeige_fpga@foxmail.com  发 ...

  8. 【tornado】系列项目(二)基于领域驱动模型的区域后台管理+前端easyui实现

    本项目是一个系列项目,最终的目的是开发出一个类似京东商城的网站.本文主要介绍后台管理中的区域管理,以及前端基于easyui插件的使用.本次增删改查因数据量少,因此采用模态对话框方式进行,关于数据量大采 ...

  9. 基于ZigBee的家居控制系统的设计与应用

    基于ZigBee的家居控制系统的设计与应用 PPT简介:http://pan.baidu.com/s/1i38PC6D 摘  要 智能家居是未来家居的发展方向,其利用先进的网络技术.计算机技术和无线通 ...

随机推荐

  1. CodeForces 609D Gadgets for dollars and pounds

    二分天数+验证 #include<cstdio> #include<cstring> #include<cmath> #include<algorithm&g ...

  2. FTP详解

    概述 FTP 是File Transfer Protocol(文件传输协议)的英文简称,而中文简称为“文传协议”.用于Internet上的控制文件的双向传输.同时,它也是一个应用程序(Applicat ...

  3. Zabbix的安装及简单配置

    Mysql源码安装:Mysql安装脚本 PHP源码安装:基于LNMP的Zabbbix之PHP源码安装 Nginx源码安装:Nginx安装 Zabbix监控端源码安装(包含Server和Agent):l ...

  4. IO之同步、异步、阻塞、非阻塞 (2)

    [原创链接: http://www.smithfox.com/?e=191, 转载请保留此声明, 谢谢! ] I/O Model 是一个很大的话题, 也是一个实践性很强的事情, 网上有各种说法和资料, ...

  5. PHP运行方式

    原文链接:http://www.cnblogs.com/xia520pi/p/3914964.html 1.运行模式 关于PHP目前比较常见的五大运行模式: 1)CGI(通用网关接口 / Common ...

  6. webservice-概念性学习(一)

    以下是本人原创,如若转载和使用请注明转载地址.本博客信息切勿用于商业,可以个人使用,若喜欢我的博客,请关注我,谢谢!博客地址 学习webservice之前呢,我想说我们先学习以下的知识,对你以后的学习 ...

  7. 用于ARM上的FFT与IFFT源代码(C语言,不依赖特定平台)(转)

    源:用于ARM上的FFT与IFFT源代码(C语言,不依赖特定平台) 代码在2011年全国电子大赛结束后(2011年9月3日)发布,多个版本,注释详细. /*********************** ...

  8. 歪国人DIY的MINI四轴

    歪国人DIY的MINI四轴 Crazyflie 2.0 自己仿Crazyflie.CrazyPony

  9. IOS软件国际化(本地化Localizable)

    IOS软件国际化(本地化Localizable) iPhone是支持语言最多的手机,它支持各国语言及中国少数名族如蒙古等语言,这也是好多少数名族都用苹果的原因.在这一点上我们自主品牌还是要多学习学习. ...

  10. 单纯觉得是篇好文——跨终端Web之Hybrid App

    [reference]http://www.infoq.com/cn/articles/hybrid-app#theCommentsSection 编者按:InfoQ开设新栏目“品味书香”,精选技术书 ...