前两天忙里偷闲(一直在复习考研),从同学那里搞了个1602C LCD玩,费了点事,但终于搞好了。心情愉快啊,呵呵!
程序真的不难,网上资料也挺多的。不过没有经验的话,可能也要搞上一会儿。
在51上编程不方便在于,程序运行没有什么显示,不能像在Dos/Windows下可以在程序里面加上一些调试的代码——特别是加了外电路以后,没有示波器这类东东,有时候操作1602C的时序不对,LCD就没有反应,很让人头疼!
这里有几份网上的关于1602C的资料,如果有需要可以下载来看看
这个资料不错,它上面有讲1602C的启动过程,不过代码是用AVR的C语言写的
这是网上的一份比较常见的资料,后面有用51汇编写的程序,完全可以使用!
这是一份英文资料,上面有讲如何使用一个174移位寄存器来实现用只使用三条或两条引脚来驱动LCD。他用的Hitachi 44780和我们的1602C基本是一样的。
电路很简单,按照网上给的接法自己找个51的端口接好就行了。
我使用的是现成的一个51学习板(使用的AT89S52),又引出了几个端口。
我没有把端口引线和LCD焊到一起。原来用面包板作为媒介,但它的接触不可靠;后来用了一个排针的插口加上一个40针的引脚(原来打算自己焊一个51的最小系统板时做的),这才连接可靠。
下面是我写的程序(在KeilC下使用MCS-51汇编编写):
;一个简单的1602C LCD的驱动
;程序实现了在LCD的第一行第一个字符位置开始显示“Hello World”字符串
;R7被用作WRITE_STRING过程的计数器,没有作现场保护
;V0 EQU P3.4,后来直接接低电平(对比度最高)了,就没再用
RS EQU P3.5
;低电平发送指令,高电平发送数据
RW EQU P3.6
;低电平写数据,高电平读状态
E EQU P3.7
LCD_PORT EQU P0
;我把LCD的数据口接到了P0上了
BF EQU LCD_PORT.7
;忙标志位,但我没有判断标志位成功,所以还没有用
STRING: DB 'Hello World!',0
;作为要显示的数据
ORG 0000H
START:
ACALL INIT_LCD
;初始化
MOV A,#0H
ACALL SEND_ADDR
;通过A寄存器发送位置地址,00h是第一行第一个字符位置
ACALL WRITE_STRING
;写字符串,直接读取STRING,到0停止
SETB RW
AJMP $
;************************************
WRITE_STRING:
;Output a String which defined in STRING
;*************************************
; PUSH AR7
MOV DPTR,#STRING
MOV R7,#00
WRITE_STRING_LOOP:
MOV A,R7
MOVC A,@A+DPTR
JZ WRITE_STRING_END;如果ACC==0, 说明字符串完了,则停止循环
ACALL WRITE_TEXT
INC R7
JNZ WRITE_STRING_LOOP
WRITE_STRING_END:
; POP AR7
RET
;************************************
EXECCMD:
;Execute an Instruction
;************************************
CLR RS
CLR RW
CLR E
;E由高到低——下降沿,执行指令
ACALL DELAY
SETB E
;后面的测试代码没有成功
; ACALL DELAY
; SETB E
; SETB RW
;EXECCMD_TEST_BF:
; MOV LCD_PORT,#0FFH
; CLR E
; NOP
; SETB E
; JB BF,EXECCMD
RET
;*************************************
WRITE_TEXT:
;USE Register A TO TRANSMIT CHARS
;发送要显示的数据
;*************************************
SETB RS
;RW is default to 0
; CLR RW
MOV LCD_PORT,A
CLR E
ACALL DELAY
SETB E
CLR RS
RET
;*************************************
INIT_LCD:
;INITIALIZING LCD MODULE
;初始化LCD模块
;*************************************
;应该等待至少15毫秒
ACALL DELAY
SETB E
CLR RS;
CLR RW;
; SETB V0
;这部分是许多文章上建议的附加的启动过程,但我试了,
;不加也是可以的——可能是为了防止高速芯片初始化错误吧
;Optional{
; MOV LCD_PORT,#38H
; ACALL EXECCMD
; ACALL DELAY
; MOV LCD_PORT,#38H
; ACALL EXECCMD
; ACALL DELAY
; MOV LCD_PORT,#38H
; ACALL EXECCMD
; ACALL DELAY
;}
;SET DISPLAY MODE
;设置显示模式
ACALL CLEAR_LCD;MOV LCD_PORT,#01H
MOV LCD_PORT,#00111000B;#38H
ACALL EXECCMD
;Optional{可加可不加
; MOV LCD_PORT,#08H;Turn off the Display
; ACALL EXECCMD
;}
;CURSOR RETURNS TO HOME
;光标回到初始位置
MOV LCD_PORT,#02H;#0000 0010B
ACALL EXECCMD
;光标每次自动向右移位
MOV LCD_PORT,#06H;#00000110B
ACALL EXECCMD
;DISPLAY ON,CURSOR OFF
;显示开,不显示光标
MOV LCD_PORT,#0CH ;#00001100B
ACALL EXECCMD
ACALL CLEAR_LCD;MOV LCD_PORT,#01H
RET
;*************************************
SEND_ADDR:
;发送光标地址
;*************************************
ORL A,#80H;OR 1000 0000B,地址的最高位必须为1
MOV LCD_PORT,A
ACALL EXECCMD
RET
;*************************************
CLEAR_LCD:
;CLEAR LCD
;LCD清屏
;*************************************
MOV LCD_PORT,#01H
ACALL EXECCMD
RET
DELAY:
MOV R6,#064H;100*200*1us=20ms,我使用的是20Mhz的晶振
DELAY_1:
MOV R5,#0C8H
DELAY_2:
DJNZ R5,DELAY_2
DJNZ R6,DELAY_1
RET
END
用户25591 2008-2-29 11:25
用户1271842 2006-12-14 12:10
You're welcome
用户62680 2006-12-12 09:30
Good. thx for share. daniel
用户1053025 2006-12-11 11:18
用户46055 2006-11-16 10:25
你将frequence默认值不是10,单位为GHz,将10改为你想要的数值,单位点击后可以改为MHz,KHz,Hz等.
用户48589 2006-11-11 16:21
好
用户54773 2006-11-2 11:50