返回信息流现在的问题是,烧进了cpld里面以后,液晶1602只能出现一行黑框,我琢磨是不是不能直接给赋值字符,得有一个转换模块呢?求改编,只要能显示hello就行,代码如下
// LCD_Top.v
//连接Clock_Gen模块和LCD_Driver模块
module LCD_Top(clk_48M,rst,LCD_EN,RS,RW,DB8);
input clk_48M,rst;
output LCD_EN,RS,RW;
output [7:0] DB8;
wire clk_LCD; //用于将Clock_Gen模块clk_LCD输出连接至LCD_Driver模块的clk_LCD输入
Clock_Gen U1(.clk_48M(clk_48M),
.rst(rst),
.clk_LCD(clk_LCD));
LCD_Driver U2(.clk_LCD(clk_LCD),
.rst(rst),
.LCD_EN(LCD_EN),
.RS(RS),
.RW(RW),
.DB8(DB8));
endmodule
// Clock_Gen.v
/****************为LCD_Drvier模块产生500Hz的时钟信号**************/
module Clock_Gen(clk_48M,rst,clk_LCD);
input clk_48M,rst; //rst为全局复位信号(高电平有效)
output clk_LCD;
wire clk_counter;
reg [11:0] cnt; //对时钟进行计数分频
wire clk_equ;
reg [9:0] count;
reg clk_BUF;
parameter counter= 50; //多少分频
/********************************************************************************
** 模块名称:分频器
** 功能描述:通过计数器实现分频功能.
********************************************************************************/
always@(posedge clk_48M)
begin
if(!rst) //低电平复位
cnt <= 12'd0;
else
if(clk_equ)
cnt <= 12'd0;
else
cnt <= cnt+1'b1;
end
assign clk_equ = (cnt==counter);
assign clk_counter = clk_equ;
always @(posedge clk_counter or negedge rst)
begin //利用计数器分频产生500Hz时钟
if(!rst)
begin
clk_BUF <= 1'b0;
count <= 10'b0;
end
else
begin
if(count == 10'd1000)
begin
clk_BUF <= ~clk_BUF;
count <= 10'b0;
end
else
begin
clk_BUF <= clk_BUF; //clk_BUF为500Hz的时钟信号
count <= count + 1'b1;
end
end
end
assign clk_LCD = clk_BUF;
//clk_LCD为LCD_Drvier模块所需要的500Hz的时钟信号
endmodule
// LCD_Driver.v
//功能简述:在1602液晶模块上显示字符串,其中第一行显示"Welcom to hx"
// 在第二行显示"www.mcuhx.com"
//液晶模块为TC1602A,相关特性请参考其数据手册
module LCD_Driver(clk_LCD,rst,LCD_EN,RS,RW,DB8);
input clk_LCD,rst; //rst为全局复位信号(高电平有效)
output LCD_EN,RS,RW;
//LCD_EN为LCD模块的使能信号(下降沿触发)
//RS=0时为写指令;RS=1时为写数据
//RW=0时对LCD模块执行写操作;RW=1时对LCD模块执行读操作
output [7:0] DB8; //8位指令或数据总线
reg [7:0] DB8;
reg [48:0] Data_First_Buf,Data_Second_Buf; //液晶显示的数据缓存
reg RS,LCD_EN_Sel;
reg [3:0] disp_count;
reg [3:0] state;
parameter Clear_Lcd = 4'b0000, //清屏并光标复位
Set_Disp_Mode = 4'b0001, //设置显示模式:8位2行5x7点阵
Disp_On = 4'b0010, //显示器开、光标不显示、光标不允许闪烁
Shift_Down = 4'b0011, //文字不动,光标自动右移
Write_Addr = 4'b0100, //写入显示起始地址
Write_Data_First = 4'b0101, //写入第一行显示的数据
Write_Data_Second = 4'b0110, //写入第二行显示的数据
Idel = 4'b0111; //空闲状态
parameter Data_First = "w", //液晶显示的第一行的数据
Data_Second = "B"; //液晶显示的第二行的数据
assign RW = 1'b0; //RW=0时对LCD模块执行写操作
assign LCD_EN = LCD_EN_Sel ? clk_LCD : 1'b0;
//通过LCD_EN_Sel信号来控制LCD_EN的开启与关闭
always @(posedge clk_LCD or negedge rst)
begin
if(!rst)
begin
state <= Clear_Lcd; //复位:清屏并光标复位
RS <= 1'b0; //复位:RS=0时为写指令;
DB8 <= 8'b0; //复位:使DB8总线输出全0
LCD_EN_Sel <= 1'b1; //复位:开启夜晶使能信号
//Data_First_Buf <= Data_First;
//Data_Second_Buf <= Data_Second;
disp_count <= 4'b0;
end
else
case(state) //初始化LCD模块
Clear_Lcd:
begin
state <= Set_Disp_Mode;
DB8 <= 8'b00000001; //清屏并光标复位
end
Set_Disp_Mode:
begin
state <= Disp_On;
DB8 <= 8'b00111000; //设置显示模式:8位2行5x8点阵
end
Disp_On:
begin
state <= Shift_Down;
DB8 <= 8'b00001100; //显示器开、光标不显示、光标不允许闪烁
end
Shift_Down:
begin
state <= Write_Addr;
DB8 <= 8'b00000110; //文字不动,光标自动右移
end
Write_Addr:
begin
state <= Write_Data_First;
DB8 <= 8'b10000001; //写入第一行显示起始地址:第一行第二个位置
Data_First_Buf <= Data_First; //将第一行显示的数据赋给Data_First_Buf?
end
Write_Data_First: //写第一行数据
begin
if(disp_count == 7) //disp_count等于14时表示第一行数据已写完
begin
DB8 <= 8'b11000001; //送入写第二行的指令
RS <= 1'b0;
disp_count <= 4'b0;
Data_Second_Buf <= Data_Second;
state <= Write_Data_Second; //写完第一行进入写第二行状态
end
else
begin
DB8 <= Data_First;
Data_First_Buf <= (Data_First_Buf << 8);
RS <= 1'b1; //RS=1表示写数据
disp_count <= disp_count + 1'b1;
state <= Write_Data_First;
end
end
Write_Data_Second: //写第二行数据
begin
if(disp_count == 7)
begin
LCD_EN_Sel <= 1'b0;
RS <= 1'b0;
disp_count <= 4'b0;
state <= Idel; //写完进入空闲状态
end
else
begin
DB8 <= Data_First;
Data_Second_Buf <= (Data_Second_Buf << 8);
RS <= 1'b1;
disp_count <= disp_count + 1'b1;
state <= Write_Data_Second;
end
end
Idel:
begin
state <= Idel; //在Idel状态循环
end
default: state <= Clear_Lcd; //若state为其他值,则将state置为Clear_Lcd
endcase
end
endmodule
这是一条镜像帖。来源:北邮人论坛 / circuit / #17274同步于 2011/5/19
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Circuit机器人发帖
verilog编一个液晶显示,问题求助
anhenaiguo
2011/5/19镜像同步2 回复
订阅后,新回复会通过你的通知中心匿名送达。
2 条回复
Set_Disp_Mode一定要在第一步做,然后是clear_disp
下面这两行是什么东西??
parameter Data_First = "w", //液晶显示的第一行的数据
Data_Second = "B"; //液晶显示的第二行的数据
可综合的verilog代码只认识二进制,你给个字符串显然是有问题的。
LCD的字符是有映射的,W用8'b0101_0111表示,找个1602的手册看看就知道了
附件是一款类似芯片的手册,时序是一样的,仅供参考
另外记得看看手册里面的操作顺序,先做什么操作,后做什么操作
【 在 anhenaiguo 的大作中提到: 】
: 现在的问题是,烧进了cpld里面以后,液晶1602只能出现一行黑框,我琢磨是不是不能直接给赋值字符,得有一个转换模块呢?求改编,只要能显示hello就行,代码如下
: // LCD_Top.v
: //连接Clock_Gen模块和LCD_Driver模块
: ...................
附件(615.3KB) SITRONIX_ST7066U.pdf