📄 lcd_12864.asm
字号:
;********************************************************************************
;* *
;* File : 实验板12864LCD.ASM *
;* Function : LCM驱动练习,内含简体汉字库。 *
;* Date : 2006-10-01 *
;* Version : 1.0 *
;* *
;* Author : 开关电源 hongtusy@163.com *
;* Company : 电子信息技术咨询网 http://www.itsn.cn *
;* *
;****************************描述与记事******************************************
;实验板的AVR程序,驱动12864LCM(可显示4行,每行8个汉字)模块显示实验练习。
;说明:RS高显示/低指令输入 RW高读/低写 EN高读数据/下降沿写数据
;记事:本程序旨在对LCD驱动的理解与演示,程序适合初学者使用。
;具体电路可参照使用指南里的说明。为16×16的点阵汉字。
;使用器件:ATMEGA8535,可更换。 使用默认的片内RC振荡器,1MHz。
;接线定义:PD4,5,6 为RS,R/W,EA。数据位为PC口。
;使用的开关:SW1-1~8.SW2-1,2,3.SW2-5为背光开关。 SW3-8为系统复位端。
;PSB脚为串并行模式选择。SW2-7为高并行模式,SW2-8为低串行模式。
;从0x60单元开始的64个字节单元为显存,存放显示的内容。
;********************************************************************************
.include "8535def.inc" ;定义头文件。
.org 0x0000 ;指定开始地址。
rjmp reset ;转移到“RESET”句。
.org 0x0030
;---------------定义堆栈指针---------
reset: ldi r21,high(ramend)
out sph,r21
ldi r21,low(ramend)
out spl,r21
;---------------设置口方向------------
ldi r16,0xff ;加载立即数作数据方向参数。
out ddrd,r16 ;PD口为输出,作为LCM的控制端,只使用PD4,5,6共3位。
out ddrc,r16 ;PC口为输出,作为LCM的数据端
ldi r16,0x00
out ddrb,r16 ;PB口为输入,作为按键直接输入。低电平表示输入。
;---------------------------------------
star: rcall londel ;长延迟,以LCD上电稳定。
rcall lcd_init ;LCD初始化
rcall lcd_begin ;给LCD显存置初值
rcall display_lcd ;调显示子程序
ldi r17,0x80 ;光标停留在0x80位置。
rcall write_code ;第1行光标位置有0x80,0x81...0x8f,第2行光标位置有0xc0,0xc1...0xcf.
loop: rjmp loop
;***********************************************
;函 数 名: lcd_begin
;功 能: 将ROM中的64个字节的数据搬至RAM的显示缓冲区中。
;输入参数: /
;输出参数: /
;描 述: 此12864LCD使用的是ST7920为驱动芯片。可以显示ASCII码的前128个值,此时为半字宽,数据为8位,
;即输入的8位数据的最高位为0,范围为0x00~0x7f,比如0x00为空格,0x61为小写字母a,0x7e为~。
;若最高位为1,则可以显示汉字,且此时为一个字宽,两个字节代表一个汉字。起始数据为0x8000,代表一个字的空格,
;0x8001代表汉字“啊”,0xffff代表汉字“翰”。
;也可以使用自定义字库或显示图片等。
;***********************************************
lcd_begin: ldi r16,64 ;共64个字节。
ldi zh, high(Table_1<<1); 初始化Z指针,实际就是r30和r31两个寄存器,就是要搬运的数据包的首地址
ldi zl, low(Table_1<<1)
ldi xh,0 ;确定内存的首地址。
ldi xl,0x60 ;从RAM的0x0060开始
here: lpm r17,z+ ;取出程序存储器(ROM)中Z指针(r31:r30)指向的数据
st x+,r17 ;间接存数到x指定的RAM单元,并x自加一。
dec r16
brne here
ret
;***********************************************
;函 数 名: lcd_Init
;功 能: 初始化1602LCD
;输入参数: /
;输出参数: /
;描 述: /
;***********************************************
lcd_init: cbi portd,7 ;RS=0,低电平复位,然后变高后可以正常工作。也可以直接接高电平或NC不用。
rcall del
sbi portd,7 ;RS=1,开始工作
ldi r17,0x01 ;清除屏幕
rcall write_code ;写命令
ldi r17,0b00000011 ;光标回到原点
rcall write_code ;写命令
ldi r17,0b00000111 ;设定,光标右移,位址加一
rcall write_code ;写命令
ldi r17,0b00001111 ;显示状态开关,整体显示,光标显示,光标位置反白
rcall write_code ;写命令
ldi r17,0b00010111 ;光标向右移动
rcall write_code ;写命令
ldi r17,0b00111011 ;功能设定,8位数据口,基本指令集
rcall write_code ;写命令
;ldi r17,0b01000000 ;设定CGRAM位址(列)
;rcall write_code ;写命令
;ldi r17,0b10000000 ;设定DDRAM位址(行)
;rcall write_code ;写命令
ret
;***********************************************
;函 数 名: display_lcd
;功 能: 独立的LCD显示程序,用户将显存内容更新后,只要调用此程序即可更新显示。
;输入参数: /
;输出参数: /
;描 述: 将显存(0x60~0x7f的32个字节单元)的内容更新显示一遍,用时估计2mS.
;在写一个字符前,先设定显示的位置地址,然后再写数据。系统可以自动地址加一的。
;***********************************************
display_lcd:ldi r17,0x80 ;第一行起始地址,0b10000000B=0x80.即DDRAM位址。
rcall write_code ;写命令
clr r27 ;清除X寄存器高字节
ldi r26,0x60 ;将X寄存器低字节设置成0x60
ldi r16,0x10 ;一行共16个字符,此处是先减一后判断的,所以要0x10.
dis1: ld r17,x ;用x间接从内部RAM取数到I/O寄存器
rcall write_data ;写数据
inc r26 ;加1
dec r16 ;减1
brne dis1 ;不为0转移
;-----------
ldi r17,0x90 ;第二行,DDRAM位址。
rcall write_code ;写命令
ldi r16,0x10 ;一行共16个字符
dis2: ld r17,x ;间接从内部RAM取数到I/O寄存器
rcall write_data ;写数据
inc r26 ;加1
dec r16 ;减1
brne dis2 ;不为0转移
;-----------
ldi r17,0x88 ;第三行,DDRAM位址。
rcall write_code ;写命令
ldi r16,0x10 ;一行共16个字符
dis3: ld r17,x ;间接从内部RAM取数到I/O寄存器
rcall write_data ;写数据
inc r26 ;加1
dec r16 ;减1
brne dis3 ;不为0转移
;-----------
ldi r17,0x98 ;第四行,DDRAM位址。
rcall write_code ;写命令
ldi r16,0x10 ;一行共16个字符
dis4: ld r17,x ;间接从内部RAM取数到I/O寄存器
rcall write_data ;写数据
inc r26 ;加1
dec r16 ;减1
brne dis4 ;不为0转移
;-----------
ret
;--------写数据----------------
;---r17为数据------
write_data: out portc,r17 ;数据送出
sbi portd,4 ;RS=1,数据
cbi portd,5 ;R/W=0,写
cbi portd,6 ;EN=0,使能,产生一个下降沿。
rcall del ;小延迟
sbi portd,6 ;除能
ret
;--------写指令----------------
;---r17为命令/地址------
write_code: out portc,r17 ;命令送出
cbi portd,4 ;RS=0,指令
cbi portd,5 ;R/W=0,写
cbi portd,6 ;EN=0,使能,产生一个下降沿。
rcall del ;小延迟
sbi portd,6 ;除能
ret
;-------------短延迟程序--------------
del: ldi r18,0x0ff
Loop1: dec r18
brne Loop1
nop
ret
;-----------长延迟程序-----------
londel: ldi r19,0x2f
Loop2: rcall del
dec r19
brne Loop2
ret
;-------------------------------
Table_1:
.db "我们都是一家人,何必争来斗去呢?!祝你一帆风顺! ITSN-AVR "
;---------------END--------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -