📄 5-13s.asm
字号:
;PROGRAM : 5-13S.ASM (5-13S.PRJ) BY STEVEN
;FUNCTION: I2C SLAVE MODE DEMO PROGRAM (SLAVE) 2002.DEC.07.
;MASK OPTION: I2C FUNCTION SHOULD BE ENABLE
#INCLUDE HT46R23.INC
.CHIP HT46R23
;--------------------------------------------------------------------
MY_DATA .SECTION 'DATA' ;== DATA SECTION ==
DEL1 DB ? ;DELAY LOOP COUNT 1
DEL2 DB ? ;DELAY LOOP COUNT 2
DEL3 DB ? ;DELAY LOOP COUNT 3
DC_FLAG DBIT ;LCD DATA/COMMAND FLAG
RX_FLAG DBIT ;RECEIVED NEW DATA FLAG
COUNT DB ? ;UNIVERSAL COUNTER
KEY_COUNT DB ? ;ROW COUNTER USED IN READ_KEY
KEY DB ? ;KEY CODE REGISTER
KEY_PS DB ? ;KEY CODE REGISTER
MY_CURSOR DB ? ;KEY IN CURSOR ADDRESS
IN_CURSOR DB ? ;RECEIVED CURSOR ADDRESS
RX_DATA DB ? ;BUFFER FOR RECEIVED DATA
TX_DATA DB ? ;BUFFER FOR TRANSMITTED DATA
STACK_A DB ? ;STACK BUFFER FOR ACC
STACK_PSW DB ? ;STACK FOR STATUS
;--------------------------------------------------------------------
LCD_CONTR EQU PA ;DEFINE LCD CONTROL PORT
LCD_CONTRC EQU PAC ;DEFINE LCD CONTROL PORT CON. REG.
LCD_DATA EQU PB ;DEFINE LCD DATA PORT
LCD_DATAC EQU PBC ;DEFINE LCD DATA PORT CON. REG.
LCD_EN EQU LCD_CONTR.0 ;DEFINE EN CONTROL PIN
LCD_RW EQU LCD_CONTR.1 ;DEFINE RW CONTROL PIN
LCD_RS EQU LCD_CONTR.2 ;DEFINE RS CONTROL PIN
LCD_READY EQU LCD_DATA.7 ;DEFINE READY BIT OF LCD
KEY_PORT EQU PB ;DEFINE KEY PORT
KEY_PORTC EQU PBC ;DEFINE KEY PORT CONTROL REG.
ID_PORT EQU PC ;DEFINE ID SETTING PORT
ID_PORTC EQU PCC ;DEFINE ID PORT CONTROL REG.
HCF EQU HSR.7 ;DEFUNE HCF
HAAS EQU HSR.6 ;DEFINE HAAS
SRW EQU HSR.2 ;DEFUNE SRW
RXAK EQU HSR.0 ;DEFINE RXAK
HEN EQU HCR.7 ;DEFUNE HEN
HTX EQU HCR.4 ;DEFINE HTX
TXAK EQU HCR.3 ;DEFINE TXAK
MY_CODE .SECTION AT 0 'CODE' ;== PROGRAM SECTION ==
ORG 00H ;HT-46RXX RESET VECTOR
JMP START
ORG 10H ;HT-46XX H-BUS INTERRUPT VECTOR
JMP I2C_INT
START:
CLR LCD_CONTRC ;CONFIG LCD_CONTR AS OUTPUT MODE
SET ID_PORTC ;CONFIG ID_PORT AS INPUT MODE
MOV A,38H ;FUNCTION SET: 8-BIT,2-LINE,5X10 DOTS
CALL WLCMC
MOV A,0CH ;ON/OFF CONTR: DISPLAY ON,CURSOR BLINKING OFF
CALL WLCMC
MOV A,06H ;ENTRY MODE : INCREMENT,DISPLAY NOT SHIFT
CALL WLCMC
MOV A,01H ;CLEAR DISPLAY
CALL WLCMC
MOV A,80H ;SET LINE ONE, POSITION 0
MOV MY_CURSOR,A
MOV A,0C0H ;SET LINE TWO, POSITION 0
MOV IN_CURSOR,A
SET EMI ;ENABLE GLOBAL INTERRUPT
SET EHI ;ENABLE I2C INTERRUPT
RLA ID_PORT ;READ SLAVE ADDRESS SETTING
MOV HADR,A ;SET SLAVE ADDRES
MOV A,10000000B
MOV HCR,A ;ENABLE I2C FUNCTION
CLR RX_FLAG ;CLEAR RECEIVED DATA FLAG
MAIN:
SZ RX_FLAG
CALL DISPLAY_RX_DATA
CALL READ_KEY ;READ KEYPAD
MOV A,16
XOR A,KEY
SZ Z ;KEY PRESSED ?
JMP MAIN ;NO, RE-READ KEYPAD
MOV A,KEY
MOV KEY_PS,A ;RESERVE KEY CODE
WAIT:
CALL READ_KEY ;CHECK KEYPAD RELEASED
MOV A,16
XOR A,KEY
SNZ Z ;IS KEY RELEASED?
JMP WAIT ;NO,WAIT KEY RELEASE
CALL DELAY ;FOR DE-BOUNCING WHEN KEY RELEASE
MOV A,MY_CURSOR ;SET CURSOR ADDRESS
CALL WLCMC
MOV A,KEY_PS
SUB A,10 ;CONVERT TO ASCII CODE
SZ C
ADD A,40H-30H-9
ADD A,30H+10
MOV TX_DATA,A
CALL WLCMD ;DISPLAY KEY IN DATA
INC MY_CURSOR
MOV A,MY_CURSOR
XOR A,80H+20+1 ;20x2 LCD
SNZ Z ;REACH LAST POSITION OF LINE 1?
JMP MAIN ;NO
MOV A,80H ;RESET LCD ADDRESS
CALL WLCMC
MOV A,20
MOV DEL1,A
MOV A,20H ;CLEAR LINE 1
CALL WLCMD
SDZ DEL1
JMP $-2
MOV A,80H
MOV MY_CURSOR,A ;RESET LCD ADDRESS
JMP MAIN ;READ NEXT KEY
;********************************************************************
; DISPLAY RECEIVED DATA PROCEDURE
;********************************************************************
DISPLAY_RX_DATA PROC
MOV A,IN_CURSOR ;SET CURSOR ADDRESS
CALL WLCMC
MOV A,RX_DATA ;COPY TO RX_DATA BUFFER
CALL WLCMD ;DISPLAY KEY IN DATA
CLR RX_FLAG
INC IN_CURSOR
MOV A,IN_CURSOR
XOR A,0C0H+20+1 ;20x2 LCD
SNZ Z ;REACH LAST POSITION OF LINE 2
RET ;NO
MOV A,0C0H ;YES, RESET LCD ADDRESS
CALL WLCMC
MOV A,20
MOV DEL1,A
MOV A,20H ;CLEAR LINE 2
CALL WLCMD
SDZ DEL1
JMP $-2
MOV A,0C0H
MOV IN_CURSOR,A ;RESET LCD ADDRESS
RET
DISPLAY_RX_DATA ENDP
;********************************************************************
; I2C INTERRUPT SERVICE ROUTINE
;********************************************************************
I2C_INT PROC
MOV STACK_A,A ;PUSH ACC
MOV A,STATUS
MOV STACK_PSW,A ;PUSH STATUS
SNZ HAAS ;HAAS = 1?
JMP DATA_RT ;NO, JUMP DATA RECEIVED/TRANSMITTED PROCESSING
SNZ SRW ;ADRESS MATCH! TX MODE?
JMP RX_MODE ;NO, JUMP TO RX MODE
TX_MODE:
SET HTX ;SET TX MODE
MOV A,TX_DATA
MOV HDR,A ;WRITE DATA TO HDR
SET TX_DATA
JMP END_I2C_INT
RX_MODE:
CLR HTX ;SET RX MODE
CLR TXAK ;ACKNOWLEDGE
MOV A,HDR ;DUMMY READ FROM HDR
JMP END_I2C_INT
DATA_RT:
SNZ HTX ;TX MODE?
JMP DATA_RX ;NO, JUMP TO DATA RX MODE
DATA_TX:
SZ RXAK ;RXAK = 0? CONTINUE DATA READ?
JMP WITH_ACK ;YES!
NO_ACK:
CLR HTX
CLR TXAK
MOV A,HDR ;DUMMY READ FORM HDR
JMP END_I2C_INT
WITH_ACK:
MOV A,TX_DATA
MOV HDR,A ;WRTIE TO HDR
SET TX_DATA
JMP END_I2C_INT
DATA_RX:
MOV A,HDR ;SET CURSOR ADDRESS
MOV RX_DATA,A ;COPY TO RX_DATA BUFFER
SET RX_FLAG
END_I2C_INT:
MOV A,STACK_PSW
MOV STATUS,A ;POP PSW
MOV A,STACK_A ;POP ACC
RETI
I2C_INT ENDP
;********************************************************************
; LCD DATA/COMMAND WRITE PROCEDURE
;********************************************************************
WLCMD PROC
SET DC_FLAG ;SET DC_FLAG=1 FOR DATA WRITE
JMP WLCM
WLCMC:
CLR DC_FLAG ;SET DC_FLAG=0 FOR COMMAND WRITE
WLCM:
SET LCD_DATAC ;CONFIG LCD_DATA AS INPUT MODE
CLR LCD_EN ;CLEAR ALL LCD CONTROL SIGNAL
CLR LCD_RW
CLR LCD_RS
SET LCD_RW ;SET RW SIGNAL (READ)
NOP ;FOR TAS
SET LCD_EN ;SET EN HIGH
NOP ;FOR TDDR
WF:
SZ LCD_READY ;IS LCD BUSY?
JMP WF ;YES, JUMP TO WAIT
CLR LCD_DATAC ;NO, CONFIG LCD_DATA AS OUTPUT MODE
MOV LCD_DATA,A ;LATCH DATA/COMMAND ON PB(LCD DATA BUS)
CLR LCD_EN ;CLEAR ALL LCD CONTROL SIGNAL
CLR LCD_RW
CLR LCD_RS
SZ DC_FLAG ;IS COMMAND WRITE?
SET LCD_RS ;NO, SET RS HIGH
SET LCD_EN ;SET EN HIGH
NOP
CLR LCD_EN ;SET EN LOW
RET
WLCMD ENDP
;********************************************************************
; SCAN 4x4 MATRIX ON KEY PORT AND RETURN THE CODE IN KEY REGISTER
; IF NO KEY BEEN PRESSED, KEY=16.
;********************************************************************
READ_KEY PROC
MOV A,11110000B
MOV KEY_PORTC,A ;CONFIG KEY_PORT
SET KEY_PORT ;INITIAL KEY PORT
CLR KEY ;INITIAL KEY REGISTER
MOV A,04
MOV KEY_COUNT,A ;SET ROW COUNTER
CLR C ;CLEAR CARRY FLAG
SCAN_KEY:
RLC KEY_PORT ;ROTATE SCANNING BIT
SET C ;MAKE SURE C=1
SNZ KEY_PORT.4 ;COLUMN 0 PRESSED?
JMP END_KEY ;YES.
INC KEY ;NO, INCREASE KEY CODE.
SNZ KEY_PORT.5 ;COLUMN 1 PRESSED?
JMP END_KEY ;YES.
INC KEY ;NO, INCREASE KEY CODE.
SNZ KEY_PORT.6 ;COLUMN 2 PRESSED?
JMP END_KEY ;YES.
INC KEY ;NO, INCREASE KEY CODE.
SNZ KEY_PORT.7 ;COLUMN 3 PRESSED?
JMP END_KEY ;YES.
INC KEY ;NO, INCREASE KEY CODE.
SDZ KEY_COUNT ;HAVE ALL ROWs BEEN CHECKED?
JMP SCAN_KEY ;NO, NEXT ROW.
END_KEY:
RET
READ_KEY ENDP
;********************************************************************
; Delay about DEL1*10mS
;********************************************************************
DELAY PROC
MOV A,6
MOV DEL1,A ;SET DEL1 COUNTER
DEL_1: MOV A,30
MOV DEL2,A ;SET DEL2 COUNTER
DEL_2: MOV A,110
MOV DEL3,A ;SET DEL3 COUNTER
DEL_3: SDZ DEL3 ;DEL3 DOWN COUNT
JMP DEL_3
SDZ DEL2 ;DEL2 DOWN COUNT
JMP DEL_2
SDZ DEL1 ;DEL1 DOWN COUNT
JMP DEL_1
RET
DELAY ENDP
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -