LCD12864 液晶显示-汉字及自定义显示(串口)

在网上找了许久,发现FPGA用串口驱动LCD12864程序很少,基本上没有。刚开始窃喜,中间郁闷,最后还是高兴,为什么这样说呢!头一回在没有参考程序的情况下,完全是照时序图写(自信),中间调试过程遇到一点小插曲(郁闷),后来搞定(高兴),也算是对这段时间学习FPGA的一个能力检测吧。废话少说,赶紧步入正题。

首先来看一下串口模式的几个重要管脚:

1、lcd_cs(PIN4),使能信号,高有效(有的资料上写着低有效,高低我都试过,确认是低有效),定义output。

2、lcd_sid(PIN5),数据传输线,相当于I2C的SBDA数据传输线,可定义双向,这里仅只有写,所以定义output。

3、lcd_scl(PIN6),数据传输的时钟,相当于I2C的SBCL时钟线,定义output,这里注意,很多资料上没说这频率多少合适,而有的资料上写的是高脉冲和低脉冲不能小于800ns或其他数据,一开始本以为这个时钟会比并口时钟会快一些,参考“verilog hdl的那些事儿”中,频率设置100KHZ,他的是ST7566P,我的是ST7920,同一个系列,频率应该会差不多吧,以上条件完全让我把频率设置在100KHZ,那么这个实验注定要失败,我就是栽倒在这,中间调试时,把频率往小降,往大增(就是没想到要那么慢的时钟),结果就是不行,要么出现乱码,要么不显示,后来干脆就把这频率设置成与并口一样的时钟,周期6MS(当然这个频率不是最佳值,到底多少只有自己去试试了),喔、喔,终于正确的显示了,高兴阿。

4、PSB(PIN15),串口模式,可以直接接地,程序中是设置为低,定义output。

管脚都清楚了,那么接下来看时序图,是很重要的一步:在发送数据前,CS要为高,发送数据是先连续发送5个1,用来启动一个周期,此时传输计数被重置,并且串行传输被同步。紧接的两个位指定传输方向(RW,确定读还是写)和传输性质(RS,确定是命令寄存器还是数据寄存器),最后的第八位是一个“0”,一个启动字节发送完毕,那么紧接着发送数据或是指令。一个数据或指令要分为两个字节来处理,先发高4bit,紧接着连续发送4个0,在发送低4bit,又紧接着发送4个0,也就是说完整发送完一个数据或命令,lcd_scl得打24个节拍。由于本实验也是只写不读,所以得避开LCD的忙状态,所以每次发送完一个数据或是命令后,在打一个节拍(25个),本程序中一个节拍的时间(6MS)足够避开LCD的忙状态。这里也要注意,当把所有数据处理完之后,lcd_scl得关闭,也就是拉低,否则,屏会一直刷新,覆盖掉原有的内容,最终全屏成乱码

 OK,时序搞定,那么可以利用状态机完成,代码实现

LCD12864_SPI.v

  1 module LCD12864_SPI(
  2                         //input
  3                         sys_clk,
  4                         rst_n,
  5                         
  6                         //output
  7                         lcd_cs,
  8                         lcd_sid,
  9                         lcd_scl,
 10                         lcd_psb
 11                     );
 12 input sys_clk;//50MHZ
 13 input rst_n;
 14 
 15 output lcd_cs;  //enable,H active
 16 output lcd_sid; //SPI data
 17 output lcd_scl; //SPI clk
 18 output lcd_psb;    ////H:parallel module   L:SPI module
 19 /***************************************************/
 20 assign lcd_psb = 1'b0;//串口模式
 21 /***************************************************/
 22 parameter   T3MS         = 18'd149_999;
 23 parameter   IDLE        = 4'd0,  //准备状态
 24             SEND_1      = 4'd1,     //连续发送5个1
 25             SNED_RW     = 4'd2,  //是写还是读
 26             SEND_RS     = 4'd3,  //是指令还是数据
 27             SEND_0      = 4'd4,  //发送一个0,代表启动字节结束
 28             SEND_DATA_H = 4'd5,  //发送数据的高4bit
 29             SEND_FOUR_0 = 4'd6,     //连续发送四个0
 30             SEND_DATA_L = 4'd7,     //发送数据的低4bit
 31             DELAY       = 4'd8,  //延时一个lcd_clk周期,避开LCD的忙状态
 32             STOP        = 4'd9;  //结束
 33 /***************************************************/
 34 ////产生周期为6MS的lcd_clk给LCD
 35 reg [17:0] cnt;
 36 reg lcd_clk;
 37 always @(posedge sys_clk or negedge rst_n)
 38 if(!rst_n) begin
 39     cnt <= 18'd0;
 40     lcd_clk <= 1'b0;
 41 end
 42 else if(cnt == T3MS)begin
 43     cnt <= 18'd0;
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值