CrazyBingo

逆袭屌炸天的Mini版LCD1602

0
阅读(4070)

为了配套某Book开发了One Board,再次屌丝版的寻求LCD1602;

由于完美及Mini强迫症,在淘宝找了一个晚上终于找到了逆袭的Mini版本LCD1602,尺寸图如下所示:

昨天刚拿到Mini版的1602,果然很Mini,11.5RMB买的。网址如下:http://item.taobao.com/item.htm?_u=m9mennn3efc&id=16328330242

clip_image002

只有50*30mm,比原始的的确小很多,但其他接口与传统的LCD1602完全一样。。。。。2跳线连LED正负极,以及10K的可调电阻,外加13跟杜邦线,如下所示:

clip_image004

结果蛋疼的事情开始,原先的代码怎么就是不行了,屌炸天的FPGA竟然驱动不了1602,瞬间觉得美好的世界担心只是个梦,好无助的说,难道让我拿出压箱底的STM8来调试一遍吗。。。。。

搞了半天,将LCD_EN从500KHz降低到了50Hz,结果还是不行。。。。。没心情吃饭有没有。。。

某师兄过来探望,突然说,诶。。。你这LCD视角怎么这么大,,,这么斜的都能看到。。。结果睁眼看不到。。。。。。

惊奇间突然发现,对比度问题。使劲拿起子转半天,最后发现VO在0~0.4V时候才有显示。。。这特么的对比度也略屌了吧。。。手册完全没说。。。

只给了这么一个图:事实上20K或者10K并不是问题的关键,而VO的电压才决定了对比度的高低,因此不是电位器的原因。。。。。。

clip_image005

最后,从新提高LCD_EN到500KHz,结果还是不行,手册明明说都可以到到4MHz的有木有。、。。。(500KHz是DE2的LCD1602的周期),如下

clip_image007

无奈,最后LCD_EN为20ms,并行的电路真不好操作,实现如下所示:


//--------------------------------------
localparam DELAY_TOP2 = 20'd1000_000;	//20ms(DT >= 2ns)
//localparam DELAY_TOP2 = 20'hf;		//Just for test
reg	[19:0]	delay_cnt2;
always @ (posedge clk or negedge rst_n)
begin
	if(!rst_n)
		delay_cnt2 <= 0;
	else if(delay_done)
		begin
		if(delay_cnt2 < DELAY_TOP2 - 1'b1)
			delay_cnt2 <= delay_cnt2 + 1'b1;	
		else
			delay_cnt2 <= 0;
		end
	else
		delay_cnt2 <= 0;
end
assign 	lcd_rw = 1'b0;		//write only, never read
assign	lcd_en = (delay_cnt2 >= DELAY_TOP2/2) ? 1'b0 : 1'b1;				//lcd enable,keep same time
wire	lcd_write_flag = (delay_cnt2 == DELAY_TOP2 - 1'b1) ? 1'b1 : 1'b0;	//write data when negedg


其中lcd_en作为Write LCD的写入周期,而lcd_write_flag作为LCD_DATA更新的数据。。。。相关状态的转移,如下所示:


//---------------------------------------
// FSM: always1
reg [7:0] current_state, next_state;
always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
		current_state = IDLE;
	else if(lcd_write_flag)
		current_state = next_state;
	else
		current_state = current_state;
end

//---------------------------------------
// FSM: always3-1
always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
		lcd_rs = 0;
	else if(lcd_write_flag)
		begin
		if(	next_state	==	IDLE 		|| 
			next_state 	==	DISP_SET 	||
			next_state 	==	DISP_OFF	||
			next_state	==	CLR_SCR		||
			next_state	==	CURSOR_SET1	||
			next_state	==	CURSOR_SET2	||
			next_state	== 	ROW1_ADDR 	|| 
			next_state	==	ROW2_ADDR)
			lcd_rs = 0;	//L: Instruction
		else
			lcd_rs = 1;	//H: Data
		end
	else
		lcd_rs = lcd_rs;
end

//---------------------------------------
// FSM: always3-2
always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
		lcd_data = 8'h00;
	else if(lcd_write_flag)
		begin
		//write lcd_data
		case(next_state)
		IDLE        	: 	lcd_data = 8'hxx;
		//LCD1602 init
		DISP_SET    	: 	lcd_data = 8'h38;		//Display mode: Set 16X2,5X7, 8 bits data
		DISP_OFF    	: 	lcd_data = 8'h08;		//Display off
		CLR_SCR     	: 	lcd_data = 8'h01;		//Clear LCD
		CURSOR_SET1		: 	lcd_data = 8'h06;		//Set Cursor
		CURSOR_SET2		: 	lcd_data = 8'h0C;		//Display on 
		//Display 1th line	
		ROW1_ADDR   	: 	lcd_data = 8'h80;
		ROW1_0      	: 	lcd_data = line_rom1[127:120];
......



不过最终还是搞定了,也许10ms,也许5ms就够了,没再尝试了,这些都不是问题的关键!!问题的关键在于:

(1) 背光竟然0~0.4V的时候可以,那岂不是1K电位器外加10K电阻就Perfect了???

(2) 屌炸天的Mini LCD1602还是挺好看的,外加Bingo最近出版的视频图像处理Mini套件,如下图所示:

clip_image009

clip_image011

偷偷告诉他加一句,在下一步计划中,这部分正是上面这个Mini版本的CD1602:

clip_image012

既然选择了FPGA,遍布于风雨兼程吗,一路走下去,做了个Logo玩玩,跟大家分享下,呵呵:

clip_image014