;[LCD.c]LCD驱动-----------------------------------------------------------*
;本文件包含:                                                              *
;    (1)LCDcommand:执行LCD命令                                            *
;    (2)LCDinit:初始化LCD(HD44780)                                        *
;    (3)LCDshow:在LCD(HD44780)显示屏上显示数据                            *
;硬件连接:                                                                *
;    在SD-HC08实验板上,有与LCD连接的两排插孔:                             *
;    (1)LCD若接上排插孔:                                                  *
;       LCD的数据线(DB0-7),控制线RS,R/W,E分别与MCU的PTB0-7,PTC0-2连接     *
;    (2)LCD若接下排插孔:                                                  *
;       可自行定义LCD与MCU的连接                                          *
;-------------------------------------------------------------------------*
  INCLUDE 'MC9S08AW60.inc'        ;该头文件包含寄存器及相关位定义
  INCLUDE 'GeneralFun.inc'        ;该头文件包括延时函数

  ;寄存器及相关位定义
  LCDdata:    equ  PTAD        ;LCD显示数据或指令传送口
  LCDdataD:   equ  PTADD       ;LCD数据口方向寄存器
  LCDctrl:    equ  PTCD        ;LCD控制信号传送口
  LCDctrlD:   equ  PTCDD       ;LCD控制口方向寄存器
  RS:         equ  0           ;LCD寄存器选择信号(PTC0)
  RW:         equ  1           ;LCD读写信号(PTC1)
  E:          equ  2           ;LCD使能信号(PTC2)
  
  ;声明外部函数   
    XDEF  LCDshow              ; 在LCD(HD44780)显示屏上显示数据
    XDEF  LCDinit              ;初始化LCD(HD44780) 
    XDEF  LCDcommand           ;执行A中的LCD命令       
;LCDshow:在LCD(HD44780)显示屏上显示数据----------------*
;功能:在LCD(HD44780)显示屏上显示HX所指向的32个数据     *
;入口:HX = 待显示数据的首地址                          *
;出口:无                                               *
;堆栈深度:2 + 1 + 1 + 9 = 13                           *
;内部调用:LCDinit,LCDcommand                           *
;------------------------------------------------------*
LCDshow:
    PSHA           ;保护A
    AIS  #-1       ;开辟1个字节的临时变量
    ;1. LCD初始化
    JSR  LCDinit
    ;2. 显示第1行16个字符
    ;2.1设置显示首地址
    BCLR RS,LCDctrl    ;RS,R/W = 00(写的是指令)
    BCLR RW,LCDctrl
    LDA  #%10000000     ;后7位为DD RAM地址($00)
    JSR  LCDcommand
    ;2.2写16个数据到DD RAM
    LDA  #16               ;[SP+1]初始 = 16(1行显示个数)
    STA  1,SP
    BSET RS,LCDctrl       ;RS,R/W = 10(写的是数据)
    BCLR RW,LCDctrl
LCDshow_1:
    LDA  ,X                ;取待显示的数据
    JSR  LCDcommand        ;向DD RAM写入数据
    AIX  #1                ;指向下一个待显示的数据
    DBNZ 1,SP,LCDshow_1    ;若16个数据没写完则继续
    ;3. 显示第2行16个字符
    ;3.1设置显示首地址
    BCLR RS,LCDctrl    ;RS,R/W = 00(写的是指令)
    BCLR RW,LCDctrl
    LDA  #%11000000     ;后7位为DD RAM地址($40)
    JSR  LCDcommand
    ;3.2写16个数据到DD RAM
    LDA  #16               ;[SP+1]初始 = 16(1行显示个数)
    STA  1,SP
    BSET RS,LCDctrl       ;RS,R/W = 10(写的是数据)
    BCLR RW,LCDctrl
LCDshow_2:
    LDA  ,X                ;取待显示的数据
    JSR  LCDcommand        ;向DD RAM写入数据
    AIX  #1                ;指向下一个待显示的数据
    DBNZ 1,SP,LCDshow_2    ;若16个数据没写完则继续
    AIS  #1    ;释放临时变量
    PULA       ;恢复A
 RTS
 
;LCDinit:初始化LCD(HD44780)----------------------------*
;功能:初始化LCD(HD44780),设置显示方式,输入方式,并清屏  *
;入口:无                                               *
;出口:无                                               *
;堆栈深度:2 + 3 + 4 = 9                                *
;内部调用:LCDcommand                                   *
;------------------------------------------------------*
LCDinit:
    PSHH    ;保护H
    PSHX    ;保护X
    PSHA    ;保护A
    LDA  #%11111111     ;定义数据口(PTA0-7)为输出
    STA  LCDdataD
    LDA  LCDctrlD       ;定义控制口(PTC0-2)为输出
    ORA  #%00000111
    STA  LCDctrlD
    ;设置指令
    BCLR RS,LCDctrl    ;RS,R/W = 00
    BCLR RW,LCDctrl
    ;1. 功能设置
    LDA  #%00111000
         ;||||||||____ 可设任意值(0/1)
         ;||||||______ F  = 0,5*7点阵模式
         ;|||||_______ N  = 1,2行显示
         ;||||________ DL = 1,8位数据总线
         ;|||_________ 固定为001
    JSR  LCDcommand
    ;2. 显示开关控制
    LDA  #%00001000
         ;||||||||____ B = 0,不闪烁
         ;|||||||_____ C = 0,关光标显示
         ;||||||______ D = 0,关显示
         ;|||||_______ 固定为00001
    JSR  LCDcommand
    ;3.清屏
    LDA  #%00000001     ;清DD RAM内容,光标回原位,清AC
    JSR  LCDcommand
    LDHX #$0200         ;等待清屏完毕,时间 > 1.6ms
    JSR  DelayHX
    ;4.输入方式设置
    LDA  #%00000110
         ;||||||||____ 显示不移动,光标左移(A = 1)
         ;|||||||_____ 数据读写操作后,AC自动增1
         ;||||||______ 固定为000001
    JSR  LCDcommand
    ;5.光标或画面移位设置
    LDA  #%00010100
         ;||||||||____ 可设任意值(0/1)
         ;||||||______ 光标右移一个字符位,AC自动加1
         ;||||________ 固定为0001
    JSR  LCDcommand
    ;6. 显示开关控制
    LDA  #%00001100
         ;||||||||____ B = 0,不闪烁
         ;|||||||_____ C = 0,关光标显示
         ;||||||______ D = 1,开显示
         ;|||||_______ 固定为00001
    JSR  LCDcommand
    PULA               ;恢复HX、A
    PULX
    PULH
 RTS
 
;LCDcommand:执行A中的LCD命令---------------------------*
;功能:执行A中的LCD命令,并延时                          *
;入口:A:存放指令或数据                                 *
;出口:无                                               *
;堆栈深度:2 + 2 = 4                                    *
;------------------------------------------------------*
LCDcommand:
    PSHX                ;保护X
    PSHH                ;保护H
    ;1.等待 > 40us
    LDHX  #$10
    JSR   DelayHX
    ;2.数据送到LCD的数据线上
    STA   LCDdata
    ;3.给出E信号的下降沿,使数据写入LCD
    BSET  E,LCDctrl
    NOP
    NOP
    NOP
    BCLR  E,LCDctrl
    ;4.等待 > 40us
    LDHX  #$10
    JSR   DelayHX
    PULH                ;恢复H
    PULX                ;恢复X
 RTS
