寫了兩個晚上才測試妥當,只要邏輯正確,其他可慢慢修改了,這東西難寫處在于io口幾乎用完,無法用LED燈檢查結果,另外運行時T1會中斷修改一些寄存器如DPL, 增加調試的困難,無論如何算是寫成了,就上載給大家參考了, 再謝yzwzfyz 總工。
;THIS IS FOR KEYBOARD TESTING
;32H FOR ROW COUNT LOOP
;33H FOR STORE SCAN DATA(MAY CONAIN FEW 0 THAT MEAN CONTACT)
;34H FOR LOOP
;35H FOR ADD TO ROW FORM 1-8 OR 9-16
;37H FOR LOOP CONVERT ROW NUMBER TO KEYNUMBER
;3AH FOR KEYNUMBER
FIRSTBUFFER EQU 80H
LASTBUFFER EQU 0FFH
BRT EQU 09CH
BRTLOAD EQU 226 ;226(18.432, 38400 SMOD=1) 241(18.432, 38400) 250(3.68, 38400) 247(11.0592, 38400), 251(18.432, 115200)
S2CON EQU 9AH ;S2SM0, S2SM1, S2SM2, S2REN, S2TB8, S2RB8, S2TI, S2RI
IE2 EQU 0AFH ;X, X, X, X, X, X, ESPI, ES2
S2BUF EQU 9BH
P4 EQU 0C0H
AUXR EQU 8EH
AUXR1 EQU 0A2H
WAKE_CLKO EQU 08FH
ORG 0000H
LJMP MAIN
ORG 0003H
LJMP EXT_INT0 ;EXTERNAL INTERRUPT0
ORG 000BH
LJMP TIMER_0 ;TIMER0 INTERRUPT
ORG 0013H
LJMP EXT_INT1 ;EXTERNAL INTERRUPT1
ORG 001BH
LJMP TIMER_1 ;TIMER_1 INTERRUPT
ORG 0023H
LJMP UART1 ;UART1 RECEIVED INTERRUPT
ORG 002BH
LJMP ADC
ORG 0033H
LJMP LVD
ORG 003BH
LJMP PCA
ORG 0043H
LJMP UART2 ;UART2 RECEIVED INTERRUPT
ORG 004BH
LJMP SPI
ORG 0100H ; PROGRAM SET
MAIN:
MOV P0, #0FFH
MOV P1, #0FFH
MOV P2, #0FFH
MOV P3, #0FFH
MOV P4, #0FFH
;MOV 97H, #00000101B ;SLOW DOWN
MOV WAKE_CLKO,#00000000B ;ENABLE BRT(=4),T1(=2) T0(=1) HAVE CLOCK OUTPUT BRT@P1.0 T1@P3.5 T0@P3.4
MOV BRT, #BRTLOAD ;RELOAD 1152000
MOV AUXR,#01011101B ;T0x12,T1x12,UART_M0x6,BRTRUN,S2SMOD,BRTx12,EXTRAM,S1BRS
;MOV AUXR1, #00010000B ;MOVE UART2 TO TX2=P4.3 RX2=4.2
MOV TMOD, #00010001B ;TIMER_1 AS MOD1 (16BIT COUNTER) ;TIMER_0 AS MOD 1 (16BIT COUNTER)
;GATE, C/T,M1,M0(T1) GATE, C/T,M1,MO(T0)
MOV PCON, #10000000B ;THIS DOUBLE THE BRT AND T0 T1 RATE
SETB ET1 ;ENABLE T1 INTERRUPT
SETB TR1 ;RUN T1
LCALL INITIAL_UART2 ;USE BRT AS SERIAL BAUD GENERATE FOR UART2
SETB EA ;ENAABLE ALL INTERRUPT
MOV P2, #10101010B ;SHOW START
LCALL CLEANRAM
MOV R0, #FIRSTBUFFER ;INIT THE BTYE TO SENT IN BUFFER POINTER
MOV R1, #FIRSTBUFFER ;INIT THE POINTER FOR BYTE CAN STORE IN BUFFER
SCANNER:
SCANP2: ; SHIFT P2 AND READ P0
MOV 32H, #8 ;8 BITS TO SHIFT
MOV 50H, #11111111B ;THIS BYTE FOR SHIFT AND OUTPUT TO P2
MOV 35H, #0 ;THIS WILL ADD TO ROW TO MAKE 0-7
CLR C
SCANP2A:
MOV A, 50H
RRC A
MOV 50H, A
MOV P2, A ;P2 ONE ROW LOW
LCALL DELAY4 ;MUST WAIT STABLE
MOV A, P0 ;READ FROM P0
CPL A
LCALL STOREDATA
SCANNEXT1:
DJNZ 32H, SCANP2A
MOV P2, #11111111B ;END OF SCANP2
SCANP3: ; SHIFT P3 AND READ P0
MOV 32H, #8 ;8 BITS TO SHIFT
MOV 50H, #11111111B ;THIS BYTE FOR SHIFT AND OUTPUT TO P2
MOV 35H, #8 ;THIS WILL ADD TO ROW TO MAKE 0-7
CLR C
SCANP3A:
MOV A, 50H
RRC A
MOV 50H, A
MOV P3, A ;P2 ONE ROW LOW
LCALL DELAY4 ;MUST WAIT STABLE
MOV A, P0 ;READ FROM P0
CPL A
LCALL STOREDATA
SCANNEXT2:
DJNZ 32H, SCANP3A
MOV P3, #11111111B ;END OF SCANP
NOP ;CHECK BUFFER AND SENT
MOV A, R0
XRL A, R1
JZ SCANNEREXIT ;R0 R1 EQUAL NO NEW BYTE
LCALL OUTBUFFER
SCANNEREXIT:
JMP SCANNER
PUTBUFFER:
MOV @R1, A
CJNE R1, #LASTBUFFER, NEXTR1
MOV R1, #FIRSTBUFFER
JMP PUTBUFFEREXIT
NEXTR1:
INC R1 ;POINT TO NEXT BUFFER
PUTBUFFEREXIT:
RET
OUTBUFFER:
MOV A, @R0
LCALL SENTONEBYTE2
CJNE R0, #LASTBUFFER, NEXTR0
MOV R0, #FIRSTBUFFER
JMP OUTBUFFEREXIT
NEXTR0:
INC R0 ;POINT TO NEXT BUFFER
OUTBUFFEREXIT:
RET
STOREDATA: ;32H CONTAIN ROW UMBER THAT CAUSE LOW
PUSH PSW
MOV 34H, #8 ;8 BIT TO SHIFT
MOV 33H, A ;A CONTAIN 8BITS WITH FEW HIGH(CAUSE BY KEYPRESS)
STOREDATA1:
LCALL COUNTPOSITION ;CODE BY SCANNER 4C 54 COUNT BY
LCALL KEYMAP ;RETURN KEYNUMBER A AFTER LOOKUP THE MAP 3D BD
MOV 3AH, A ;SAVE KEYNUMBER TO 3AH, 0-127 IS UPPER KEY, 128-255 IS LOWER KEY
MOV A, 33H
RLC A ;CHECK EACH BIT OF 33H SEE 0 OR 1 AND DECIDE WHERE TO GO
MOV 33H, A
JNC DOKEY1 ;CONTACT POINT NOT CONTACT GO NOTEOFF SUBROTINE
LCALL NOTEON ;NOTEON CHECK
JMP STOREDATANEXT
DOKEY1:
LCALL NOTEOFF ;NOTEOFFCHECK
STOREDATANEXT:
DJNZ 34H, STOREDATA1
DOKEYEXIT:
POP PSW
RET
NOTEON:
CLR TR1 ;TIMER1 STOP
MOV A, 3AH
RLC A ;CHECK UPPER OR LOWER
JC NOTEON1 ;LOWER KEY SO DO OUTPUT
;----------UPPER
MOV DPH, #0
MOV DPL, 3AH
MOVX A, @DPTR ;READ OLD DATA
JNZ NOTEONEXIT ;ALREADY CONTACTED, DO NOTHNG
MOV A, #1
MOVX @DPTR, A ;CONTACT JUST START, PUT 1 FOR COUNT UP BY TIMER EVERY 1MS
JMP NOTEONEXIT
;-----------------
NOTEON1:
MOV A, 3AH
ANL A, #01111111B ;MASKING BIT7
MOV DPH, #0
MOV DPL, A
MOVX A, @DPTR ;READ VELOCITY
JZ NOTEONEXIT ;UPPER KEY NOT YET CONTACTED, DO NOTHING
MOV 3BH, A ;SAVE VELOCITY
INC A
JZ NOTEONEXIT ;IF FFH THEN ZERO MEAN NOTE ALREADY OUTPUT, NEED WAIT FOR NOTEOFF, DO NOTHING
MOV A, #10010000B ;MIDI NOTEON CHANNEL1
LCALL PUTBUFFER ;SENT KEY NUMBER
MOV A, 3AH
ANL A, #01111111B ;MASKING BIT7
LCALL PUTBUFFER ;SENT KEY NUMBER
MOV A, 3BH
LCALL PUTBUFFER ;SENT VELOCITY
MOV A, 3AH
ANL A, #01111111B ;MASKING BIT7
MOV DPH, #0
MOV DPL, A
MOV A, #0FFH
MOVX @DPTR, A ;MARK AS FFH WAIT FOR RELEASE AND SENT NOTEOFF
NOTEONEXIT:
SETB TR1
RET
NOTEOFF:
CLR TR1
MOV A, 3AH
RLC A ;CHECK UPPER OR LOWER
JC NOTEOFFEXIT ;LOWER KEY SO DO NOTHING
NOP ;UPPER KEY RELEASE, CHECK 0FFH FOR SENT NOTEOFF
MOV DPH, #0
MOV DPL, 3AH
MOVX A, @DPTR ;READ OLD DATA
INC A
JNZ NOTEOFFEXIT ;IF FFH THEN ZERO MEAN NO NOTE OFF NEED, DO NOTHING
;--SENT NOTEOFF
MOV A, #10000000B ;MIDI NOTEON CHANNEL1
LCALL PUTBUFFER ;SENT KEY NUMBER
MOV A, 3AH
LCALL PUTBUFFER
MOV A, #0
LCALL PUTBUFFER
MOV DPH, #0
MOV DPL, 3AH
MOV A, #0
MOVX @DPTR, A ;MARK THAT KEY LOCATION 0 TO RECEIVED NEW CONTACT PRESS
NOTEOFFEXIT:
SETB TR1
RET
COUNTPOSITION:
PUSH PSW
MOV A, 32H ;ROW POSITION 1-8
ADD A, 35H ;IF P2 THEN ADD 0(REMAIN 1-8), IF P3 THEN ADD 8(BECOME 9-16)
MOV B, #8 ;8 CONTACT POINT FOR EACH ROW
MUL AB ;NUMBER 8,16,24,32,40.......128
CLR C
SUBB A, #8 ;MAKE A 0,8,16,24.....120
ADD A, 34H ;34H CONTAIN 1-8 COLUME NUMBER(EACH BIT OF 33H) FORM 1 TO 128
DEC A ;MAKE AS 0-127 SYSTEM
POP PSW
RET
KEYMAP:
MOV DPH, #10H
MOV DPL, #00H
MOVC A,@A+DPTR
RET
TIMER_1: ;USE FOR MICRO CLOCK 1MS 184, 30 ,100US=248 250
PUSH ACC
PUSH PSW
MOV 42H, #128
MOV DPH, #0
TIMERLOOP:
MOV DPL, 42H
MOVX A, @DPTR
JZ TIMER_1NEXT
CJNE A, #0FFH, TIMERLOOP1 ;NOTEOFF NEED
CPL P1.7
JMP TIMER_1NEXT
TIMERLOOP1:
CJNE A, #0FEH, TIMER_1A ;NOT YET MAX
JMP TIMER_1NEXT
TIMER_1A:
INC A
MOVX @DPTR, A
TIMER_1NEXT:
DJNZ 42H, TIMERLOOP
TIMER_1EXIT:
MOV TH1, #248
MOV TL1, #250
POP PSW
POP ACC
RETI
SENTONEBYTE2: ;A SENT OUT
PUSH ACC
MOV IE2, #00H ;DISABLE THE SECONDARY UART INTERRUPT, ES2=0
MOV S2BUF, A ;LOAD A TO BUFFER
MOV A, S2CON ;1111,1101, CLEAR SECONDARY UART TRANSIMIT INTERRUPT FLAG
ANL A, #0FDH
MOV S2CON, A
UART2WAIT:
MOV A, S2CON
ANL A, #02H ;0000,0010
CJNE A,#02H, UART2WAIT
MOV A, S2CON
ANL A, #0FDH ;1111,1101, CLEAR SECONDARY UART TRANSIMIT INTERRUPT FLAG
MOV S2CON, A
MOV IE2, #01H ;ENABLE THE SECONDARY UART INTERRUPT, ES2=1
NOP
NOP
POP ACC
RET
DELAY4:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
RET
EXT_INT0: ;IF P3.2 H2L COME HERE SET TIMER, ONLY FIRST H2L WILL ACT
RETI
TIMER_0: ;CHECK INPUT MIDI SIGNAL AT P3.2
RETI
EXT_INT1: ;USE FOR INFRA RED
RETI
INITIAL_UART2: ;USE FOR SENT MIDI DATA
MOV S2CON, #01010000B ;SET AS BAUD VERIABLE, NO ODD/EVEN CHECK
MOV IE2, #01H ;ENABLE UART2 INTERRUPT
RET
UART1:
RETI
ADC:
RETI
PCA:
RETI
LVD:
RETI
SPI:
RETI
UART2: ;NO READ
RETI
CLEANRAM:
MOV DPH,#0
MOV DPL, #0
CLEANRAM1:
MOV A, #0
MOVX @DPTR, A
INC DPL
MOV A, DPL
JNZ CLEANRAM1
CLEANRAMB:
MOV DPH,#1
MOV DPL, #0
CLEANRAMB1:
MOV A, #0
MOVX @DPTR, A
INC DPL
MOV A, DPL
JNZ CLEANRAMB1
RET
ORG 1000H ;KEY MAPPING CONVERT SCANNER NUMBER TO KEYBOARD PHYSICAL POSITION (MUSIC KEY 1-61)
;UPPER-KEY+128=LOWER-KEY
;OPTAIN UPPER CONTACT POINT'S SCAN CODE MANUALLY AND PUT KEYNUMBER AT SCAN CODE POSITION
;OPTAIN LOWER CONTACT POINT'S SCAN CODE MANUALLY AND PUT KEYNUMBER+128 AT SCAN CODE POSITION
; 00H 01H 02H 03H 04H 05H 06H 07H 08H 09H 0AH 0BH 0CH 0DH 0EH 0FH
; ---------------------------------------------------------------
DB 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H ;0 16 0F
DB 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H ;0 16 1F
DB 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H ;0 16 2F
DB 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H ;0 16 3F
DB 00H,00H,00H,00H,00H,00H,00H,00H,39H,3AH,3BH,3CH,3DH,00H,00H,00H ;0 80 4F
DB 0B9H,0BAH,0BBH,0BCH,0BDH,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H ;0 96 5F
DB 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H ;0 16 6F
DB 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H ;0 16 7F
DB 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H ;0 16 8F
DB 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H ;0 16 9F
DB 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H ;0 16 AF
DB 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H ;0 16 BF
DB 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H ;0 16 CF
DB 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H ;0 16 DF
DB 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H ;0 16 EF
DB 00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H,00H ;0 16 FF
END
|