|
很多人都有谈到1602 LCM的使用方法,但站在一个初学者的角度来说,除了这些方法,还有很多初学者需要知道的,比如你当时的一些想法及其它的一些细节。我是一个AVR的初学者,也是偶然进入马老师专栏后,看到有足够的技术支持之后才开始学AVR的(之前本来想学PIC)。
我的学习环境很简单:电脑一台:通过关系把公司的一块坏主板拿回家修好(其实是看到了主板的5,6个电解电容账了觉得还有得救,果然一换了就好了),显视器也是七拼八凑的(LCD屏+别人给的底座+直接从主机上接12V电源供电).
从 www.iccavr.com上购的"AVR仿真器AVR下载线二合一工具"(365元) ,M16贴片封装1PCS(13元,本来要的是DIP的,他寄错了,只能自已腐蚀PCB做成DIP型式的好操作),TS1602 LCM(20元, www.iccavr.com一直下不了说明书,链接不成功).DC5V 1A电源(自已做的,市场有外壳,装一下就OK) 这就是全部家当了。
在不了解AVR内部结构和指令系统情况下,我选择了用汇编来写程序。现在谈谈LCM的使用经历:
1。找相关的说明书,按说明书把1602的16根线接好,要注意引脚名称要以LCM本身标的为准。
2。了解一下1602的原理,最基本的要知道以下几点:16个引脚分别做什么用的,13组指令粗略了解一下,写与读的操作时序一定要看懂记在心里。
3。最后了解LCM的驱动步骤,现把说明书的COPY下来:
;1----延时15ms
;2----写指令38H(写入之前不用检测Busy信号)
;3----延时5ms
;4----再次写入38H指令(写入之前不用检测Busy信号),至于为什么要重复写入现在不清楚,而且下面还要写一次.
;5----延时5ms
;4----再次写入38H指令(写入之前不用检测Busy信号)
;5----检测Busy信号;
;6----写指令38H,此条指令是将LCD显示模块设置为8位数据线,双行,5X7点阵显示
;7----检测Busy信号;
;8----写指令08H,关闭显示
;9----检测Busy信号;
;10---写指令01H,显示清屏
;以后写入光标等的控制指令.
按照上面说的,对初学者其实不太好理解,其实LCM启动方式有两种:一种是自启动(冷启动),另一种就是指令启动(热启动)。加在LCM上的电源时序变化符合自动启动的特性时(时序图就不画了),则LCM会自动执行以下工作:
1。自动清屏
2。自动功能设置:设成8位,显示1行,5X7字型
3。自动设置显示屏为关,不闪烁。
4。字符进入模式为I/D=1,S=0,即光标右移1格,AC值加1,字符不动。
另外要说明的是一般的LCM都能自启动,而说明书所讲其实属于指令启动的模式。对于自启动的话,可以按以下步骤:
1。按照你的LCM和MCU的实际连接,定义好RS,R/W,E及DB0-DB7。
2。LCM初始化:
A 判断LCM是否忙(稍后讲如何检测),不忙时对LCM写入功能设置的指令(8BIT还是4BIT,单行还是双行显示,5X10还是5X7的字型)
B 判断LCM是否忙,不忙时对LCM写入显示屏开关控制指令(显示屏开还是关,光标要不要出现,如果出现的话要不要闪烁)
C 判断LCM是否忙,不忙时对LCM写入字符进入模式 设置指令(字符进入时,光标不动,左移还是右移,AC加1还是减1,字符不动,左移还是右移)
A,B,C完成后,LCM初始化就完成了。接下来要显示东西了。
3。设置字符显示的位置,可以查DDRAM地址与显示位置映射图,如在第一行第四列显示,即它的地址为0x03,但因为DDRAM地址设置指令规定DB7必须为1,所以最终写入指令寄存器的应该是0b10000000+0b00000011=0b10000011.设置时也是先判断LCM是否忙,不忙才对LCM写入这个地址。注意这里依然是对IR(指令寄存器的操作)
4。设置要显示的字符,这里是唯一对数据寄存器的操作。设置时也是先判断LCM是否忙,不忙才对LCM写入这个字符的ASCII码。到这里,完成了字符的显示。
如何检测LCM是否忙?在设置好读取的状态下,对DB7进行检测,测得DB7=0时就表是不忙了。
如何设置读的状态?这就要结合LCM读的时序了,首先让RS=0,对IR(指令寄存器操作),然后让R/W=1,告诉LCM我要的读操作。R/W=1再经过(TSP1)最小30NS,然后让E=1,此时最好不要马上测DB7,因为E=1后,要经TD(最大100ns)DB上的数据才稳定。加入个NOP再读是最可靠的。
LCM内部可以看作两组寄存器,一个是指令寄存器,一个是数据寄存器,由RS来控制。对LCM判忙是对指令寄存器的读的操作,功能设置,显示方式设置是在对
指令寄存器写的操作。对于数据寄存器也有读写操作。如要显视字符,就把对应的ASCII写入数据寄存器中。是写的操作。
另外,写操作时,也是在E由1变为0时,LCM才会将数据打入数据寄存器中。所以要确保在E=1至E=0这一时段,你的DB数据是正确恒定的。
只要明白了LCM的原理,写LCM的驱动可以很灵活。如我以下这个程序,就没有按说明书的格式来写的。显示依然是稳定的。
;******************************************************
;ts1620 lcd diaplay
;第一行第11列显视"F"
;*******************************************************
.include "m16def.inc"
;定义程序中使用的变量名(在寄存器空间)
.equ RS = PD5
.equ RW =PD6
.equ E = PD7
;DB0-DB7 接PC0-PC7,所以JTAG功能要取消掉
.def temp = r16
.def value =r17
;中断向量区定义,flash程序空间$000-$029
.org $000
rjmp reset
nop
reti
.org $002A
reset:
;-----------I/O初始化------------
ldi temp,0xff
out ddrd,temp
;---------堆栈位置设置-----------
ldi r16,high(ramend)
out sph,r16
ldi r16,low(ramend)
out spl,r16
;-------------------------
rcall lcm_int
rcall lcm_clr
ldi value ,0b11001010 ;设置初始显视的地址
rcall write_ir ;写入控制字
LDI value ,0x46 ;设置要显示的数
rcall write_dr ;显视字符
loop:
rjmp loop
;***********************************************************
;=============== LCM初始化 ===============================
lcm_int:
;设置显示模式:数据长度,双行或单行显示,5X10或5X7字型
LDI value ,0b00111000 ;设置显示模式:8位2行5x7点阵
rcall write_ir ;写入控制字
;------------------------------------------------------------
;显示器开关,光标是否出现,是否闪烁
LDI value ,0b00001110 ;显示器开、光标开、光标允许闪烁
rcall write_ir ;写入控制字
;------------------------------------------------------------
;字符进入模式。光标是否移动,移动方向,AC变化,字符变化
LDI value ,0b00000110 ;光标右移1格,AC加1,字符不动
rcall write_ir ;写入控制字
;-----------------------------------------------------------
;显示光标移位
;ldi value,0b00010000
;rcall enable
RET
;=============================================================
;=============================判忙===========================
Busycheck:
ldi temp,0x00
out ddrc,temp
checkagain:
cbi portd,RS;RS=0,选择IR
SBI portd,RW;RW=1 ;写操作
SBI portd,E ;准备读
nop ;延时一下
in temp, pinc
cbi portd,e;下降沿出现,DR数据DB0-DB7出现
sbrc temp,7
rjmp checkagain
ldi temp ,0xff
out ddrc,temp
RET
;==================================================================
;============写入控制命令的到IR寄存器中===========
write_ir:
rcall Busycheck
cbi portd,RS ;RS=0,选择IR
cbi portd,RW ;RW=0 ;写操作
cbi portd,E ;E=0 准备
out portc,value ;选送上数据
SBI portd,E ;准备好数据
nop ;让数据稳定一点
cbi portd,E ;下降沿出现,数据被锁进IR里
RET
;==================================================
;================写数据到DR寄存器中======================
write_dr:
rcall Busycheck ;判忙
SBI portd,RS ;RS=1,选择DR
cbi portd,RW ;RW=0 ;写操作
cbi portd,E ;E=0 准备
out portc,value ;选送上数据
sbi portd,E ;准备好数据
nop ;让数据稳定一点
cbi portd,e
RET ;下降沿出现,数据被锁进DR里
;====================================================
;========清屏,让光标回到左上角=======================
lcm_clr:
ldi value,0b00000001 ;清屏并光标复位
rcall write_ir ;写入控制字
ret
;================================================= |
阿莫论坛20周年了!感谢大家的支持与爱护!!
如果想吃一顿饺子,就得从冰箱里取出肉,剁馅儿,倒面粉、揉面、醒面,擀成皮儿,下锅……
一整个繁琐流程,就是为了出锅时那一嘴滚烫流油的热饺子。
如果这个过程,禁不住饿,零食下肚了,饺子出锅时也就不香了……《非诚勿扰3》
|