📄 lcd.asm
字号:
; IDX_PP
;
;
LCD_PrString:
_LCD_PrString:
RAM_PROLOGUE RAM_USE_CLASS_3
RAM_SETPAGE_IDX A
Loop_PrString:
mov A,[X] ; Get value pointed to by X
jz End_LCD_PrString ; Check for end of string
;LCD_writeData is known not to modify X so no need to perserve
call LCD_WriteData ; Write data to screen
inc X ; Advance pointer to next character
push X
pop X
jmp Loop_PrString ; Go get next character
End_LCD_PrString:
RAM_EPILOGUE RAM_USE_CLASS_3
ret
.ENDSECTION
.SECTION
;-----------------------------------------------------------------------------
; FUNCTION NAME: LCD_WriteData
;
; DESCRIPTION:
; Write a byte to the LCD's data register.
;
;-----------------------------------------------------------------------------
;
; ARGUMENTS:
; A contains byte to be written to LCD data register
;
; RETURNS: none
;
; SIDE EFFECTS:
; The A and X registers may be modified by this or future implementations
; of this function. The same is true for all RAM page pointer registers in
; the Large Memory Model. When necessary, it is the calling function's
; responsibility to perserve their values across calls to fastcall16
; functions.
;
; Currently only the page pointer registers listed below are modified:
; CUR_PP
;
LCD_WriteData:
_LCD_WriteData:
LCD_Write_Data: ; Do not use
_LCD_Write_Data: ; Do not use
RAM_PROLOGUE RAM_USE_CLASS_1
call LCD_Check_Ready ; Make sure controller is ready
; A is preserved in LCD_Check_Ready
push A ; Save copy of character
asr A ; Shift high nibble to right
asr A
asr A
asr A
and A,0Fh ; Mask off high nibble
call LCD_WDATA_Nibble ; Write Upper nibble
pop A ; Retrieve copy of character
and A,0Fh ; Mask off high nibble
nop
nop
nop
call LCD_WDATA_Nibble ; Write Lower nibble
RAM_EPILOGUE RAM_USE_CLASS_1
ret
.ENDSECTION
.SECTION
;-----------------------------------------------------------------------------
; FUNCTION NAME: LCD_Control
;
; DESCRIPTION:
; Write a byte to the LCD's control register.
;
;-----------------------------------------------------------------------------
;
; ARGUMENTS:
; A contains data to be written to LCD control register.
;
; RETURNS: none
;
; SIDE EFFECTS:
; The A and X registers may be modified by this or future implementations
; of this function. The same is true for all RAM page pointer registers in
; the Large Memory Model. When necessary, it is the calling function's
; responsibility to perserve their values across calls to fastcall16
; functions.
;
; Currently only the page pointer registers listed below are modified:
; CUR_PP
;
LCD_Control:
_LCD_Control:
RAM_PROLOGUE RAM_USE_CLASS_1
call LCD_Check_Ready ; Make sure controller is ready
; A is preserved in LCD_Check_Ready
push A ; Save copy of byte
asr A ; Shift Upper Nibble to right
asr A
asr A
asr A
and A,0Fh ; Mask off, just in case
call LCD_WCNTL_Nibble ; Write high nibble
pop A ; Restore copy of byte
and A,0Fh ; Mask off high nibble
nop
nop
nop
call LCD_WCNTL_Nibble ; Write Lower nibble
RAM_EPILOGUE RAM_USE_CLASS_1
ret
.ENDSECTION
.SECTION
;-----------------------------------------------------------------------------
; FUNCTION NAME: LCD_WCNTL_Nibble
;
; DESCRIPTION:
; Write a single nibble to the LCD's command register
;
;-----------------------------------------------------------------------------
;
; ARGUMENTS:
; A[3:0] Contains Nibble to be written to command register
;
; RETURNS: none
;
; SIDE EFFECTS:
; The A and X registers may be modified by this or future implementations
; of this function. The same is true for all RAM page pointer registers in
; the Large Memory Model. When necessary, it is the calling function's
; responsibility to perserve their values across calls to fastcall16
; functions.
;
; Currently only the page pointer registers listed below are modified:
; CUR_PP
;
LCD_WCNTL_Nibble:
RAM_PROLOGUE RAM_USE_CLASS_4
push A
RAM_SETPAGE_CUR >Port_4_Data_SHADE ; Set CUR_PP to LCD variable address
and [Port_4_Data_SHADE],~LCD_PORT_MASK
mov A,[Port_4_Data_SHADE]
mov reg[LCD_Port],A ; Reset control lines
pop A
and A,LCD_DATA_MASK ; Make sure no bogus data in MSN
or A,LCD_E ; Bring "E" Enable line high
or A,[Port_4_Data_SHADE] ; OR in bit 7 just
mov reg[LCD_Port], A ; Write data
mov [Port_4_Data_SHADE],A ; Keep shadow register in sync
nop
and A,(~LCD_PORT_MASK|LCD_DATA_MASK) ; Disable E signal and leave data on bus.
mov [Port_4_Data_SHADE],A ; Keep shadow register in sync
mov reg[LCD_Port],A
RAM_EPILOGUE RAM_USE_CLASS_4
ret
.ENDSECTION
.SECTION
;-----------------------------------------------------------------------------
; FUNCTION NAME: LCD_WDATA_Nibble
;
; DESCRIPTION:
; Write a single nibble to the LCD's DATA register
;
;-----------------------------------------------------------------------------
;
; ARGUMENTS:
; A[3:0] Contains Nibble to be written to data register
;
; RETURNS: none
;
; SIDE EFFECTS:
; The A and X registers may be modified by this or future implementations
; of this function. The same is true for all RAM page pointer registers in
; the Large Memory Model. When necessary, it is the calling function's
; responsibility to perserve their values across calls to fastcall16
; functions.
;
; Currently only the page pointer registers listed below are modified:
; CUR_PP
;
LCD_WDATA_Nibble:
RAM_PROLOGUE RAM_USE_CLASS_4
push A
RAM_SETPAGE_CUR >Port_4_Data_SHADE ; Set CUR_PP to LCD variable address
and [Port_4_Data_SHADE],~LCD_PORT_MASK
or [Port_4_Data_SHADE],LCD_RS ; Raise RS to signify a Data Write
mov A,[Port_4_Data_SHADE]
mov reg[LCD_Port],A
pop A
and A,LCD_DATA_MASK ; Make sure no bogus data in A[7:4]
or A,(LCD_E | LCD_RS) ; Bring "E" Enable line high
or A,[Port_4_Data_SHADE] ; Keep shadow in sync
mov reg[LCD_Port], A ; Write data
mov [Port_4_Data_SHADE],A ; Keep shadow in sync
NOP
and A,(~LCD_PORT_MASK|LCD_DATA_MASK|LCD_RS) ; Disable E signal and leave Data on bus
mov [Port_4_Data_SHADE],A ; keep shadow in sync
mov reg[LCD_Port],A
RAM_EPILOGUE RAM_USE_CLASS_4
ret
.ENDSECTION
.SECTION
;-----------------------------------------------------------------------------
; FUNCTION NAME: LCD_Check_Ready
;
; DESCRIPTION:
; Wait until LCD has completed last command.
;
;-----------------------------------------------------------------------------
;
; ARGUMENTS: none
;
; RETURNS: none
;
; SIDE EFFECTS:
; The A and X registers may be modified by this or future implementations
; of this function. The same is true for all RAM page pointer registers in
; the Large Memory Model. When necessary, it is the calling function's
; responsibility to perserve their values across calls to fastcall16
; functions.
;
; Currently only the page pointer registers listed below are modified:
; CUR_PP
;
; If LCD is not present, this routine may never return.
;
LCD_Check_Ready:
RAM_PROLOGUE RAM_USE_CLASS_4
push A ; Save Accumulator
RAM_SETPAGE_CUR >Port_4_Data_SHADE ; Set CUR_PP to LCD variable address
and [Port_4_Data_SHADE],~LCD_PORT_MASK ; Mask of all LCD bits
mov A,[Port_4_Data_SHADE]
mov reg[LCD_Port],A ; Zero LCD port bits
and [Port_4_DriveMode_0_SHADE],~LCD_DATA_MASK ; Clear out LCD mode bits.
mov A,[Port_4_DriveMode_0_SHADE]
M8C_SetBank1 ; Change port mode to read status
mov reg[LCD_PortMode0],A ; Setup LCD Port for reading
M8C_SetBank0
or [Port_4_Data_SHADE],LCD_RW ; Raise RW to signify Read operation
mov A,[Port_4_Data_SHADE]
mov reg[LCD_Port],A
NOP
LCD_RDY_LOOP:
or [Port_4_Data_SHADE], LCD_CNTL_READ ; Raise E to start cycle
mov A,[Port_4_Data_SHADE]
mov reg[LCD_Port],A
nop ; Wait 2 nops to make sure data is ready
nop
mov A,reg[LCD_Port]
; The code below is used to work around the async read issue with the ICE with the
; 25/26xxx family of devices. It will help to eliminate "Invalid memory reference"
; errors. It is not required when running without the ICE or when using any other
; family besides the 25/26xxx family. If not using the ICE or with any other family
; the ICE_PORT_SYNC flag should be set to 0.
IF(ICE_PORT_SYNC)
mov reg[ 0xfa], A
mov A, reg[0xfa]
ENDIF
push A
and [Port_4_Data_SHADE],(~LCD_PORT_MASK | LCD_RW) ; Lower E signal
mov A,[Port_4_Data_SHADE]
mov reg[LCD_Port],A
nop ; Add delay for the slowest part and the
nop ; fastest PSoC
nop
; Get the LSBs
or [Port_4_Data_SHADE],LCD_CNTL_READ ; Raise E to start cycle
mov A,[Port_4_Data_SHADE]
mov reg[LCD_Port],A
nop
nop
and [Port_4_Data_SHADE],(~LCD_PORT_MASK | LCD_RW) ; Lower E signal
mov A,[Port_4_Data_SHADE]
mov reg[LCD_Port],A
pop A
and A,LCD_READY_BIT ; Check busy
jnz LCD_RDY_LOOP ; If LCD still busy, read again
or [Port_4_DriveMode_0_SHADE],LCD_PORT_WRITE ; Revert Data bit to Write mode
mov A,[Port_4_DriveMode_0_SHADE]
M8C_SetBank1
mov reg[LCD_PortMode0],A ; Setup LCD Port for writing
M8C_SetBank0
pop A
RAM_EPILOGUE RAM_USE_CLASS_4 ; Restore Accumulator
ret
.ENDSECTION
.SECTION
;-----------------------------------------------------------------------------
; FUNCTION NAME: LCD_Start
; FUNCTION NAME: LCD_Init
;
; DESCRIPTION:
; Initialize LCD
;
;-----------------------------------------------------------------------------
;
; ARGUMENTS: none
;
; RETURNS: none
;
; SIDE EFFECTS:
; The A and X registers may be modified by this or future implementations
; of this function. The same is true for all RAM page pointer registers in
; the Large Memory Model. When necessary, it is the calling function's
; responsibility to perserve their values across calls to fastcall16
; functions.
;
; Currently only the page pointer registers listed below are modified:
; CUR_PP
;
; THEORY of OPERATION or PROCEDURE:
; REGISTERS ARE VOLATILE: THE A AND X REGISTERS MAY BE MODIFIED!
; This initialization is a bit long, but it should work for
; most 2 and 4 line LCDs.
;
LCD_Start:
_LCD_Start:
LCD_Init:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -