⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 keyboard_band.txt

📁 这是一个电子琴的力度键盘程序
💻 TXT
📖 第 1 页 / 共 2 页
字号:
;这是一个电子琴的力度键盘程序,每个键有两个点,程序的要求就是测试出两个点之间的时间差,并转换成音量数值(0-7f,转换表未附)。请注意,这个程序是有版权的。请勿使用于商业用途。

; ***********************************************************************
; *              8051 Velocity Keyscan Software            *
; *                                    *
; *             (c) Richard Watts Associates 1991            *
; *                DavB & MarkP 22-05-91            *
; *              Updated SteveH 8-05-96            *
; ***********************************************************************
; This is for a keyboard with 88 keys with 12 scan lines and 16 return lines.
; Written for Evolution eKeys keyboard
; Switch pairs are read back in two cycles:
;     First  8 upper (early)
;    Second 8 lower (late)
; This version scans up the rows from P0.0 to P3.7

; This Software Implements Four State Machine For Each Key
;
;    State    Key Position    UpperKey    LowerKey
;    -----    ------------    --------    --------
;     [A]    Key Fully Up       Off           Off
;     [B]    Key Going Down       On           Off
;     [C]    Key Fully Down       On           On
;     [D]    Key Going Up       On           Off

;  Sequential Truth Table For Switch States
;
;  |-------|-----|----------------------|---------------|---------------|
;  | State | U L |     Action                | Counter State    | Message Xfer    |
;  |-------|-----|----------------------|---------------|---------------|
;  |   A   | 0 0 | Goto State [C]       | Min Counter   | Send Note On    |
;  |   A   | 0 1 | Goto State [B]       | Capture       |               |
;  |   A   | 1 0 | Nop                  |               |               | This is possible with upper and lower read on seperate cycles
;  |   A   | 1 1 | Nop                  |               |               |
;  |-------|-----|----------------------|---------------|---------------|
;  |   B   | 0 0 | Goto State [C]       | Compare       | Send Note On    |
;  |   B   | 0 1 | Nop                  |               |               |
;  |   B   | 1 0 | Illegal              |               | Send Error    |
;  |   B   | 1 1 | Goto State [A]       | Reset         |               |
;  |-------|-----|----------------------|---------------|---------------|
;  |   C   | 0 0 | Nop                  |               |               |
;  |   C   | 0 1 | Goto State [D]       |               |               |
;  |   C   | 1 0 | Illegal              |               | Send error    |
;  |   C   | 1 1 | Goto State [A]       | Reset         | Send Note Off    |
;  |-------|-----|----------------------|---------------|---------------|
;  |   D   | 0 0 | Nop                  |               |               |
;  |   D   | 0 1 | Nop                  |               |               |
;  |   D   | 1 0 | Illegal              |               | Send Error    |
;  |   D   | 1 1 | Goto State [A]       | Reset         | Send Note Off    |
;  |-------|-----|----------------------|---------------|---------------|
;
; Notes:
;    1) Keys Have Inverse Logic ie KeyUp = 1
;    2) Key Debounce Handled By 'loops' in state diagram
;    3) Error Condition Flags Upper Bus Defective
;
;    Output Format
;    Data is sent as handshaked single bytes on Port 0
;    A. Vel IC sets IRQ line from 1 to 0
;    B. Wait for Control IC to set ST9_ACK from 1 to 0.
;    C. Vel IC puts data on the bus, then sets IRQ from 0 to 1.
;    D. Wait for Control IC to set ST9_ACK from 0 to 1.
;
;    Data Byte Format
;    00-7F    Velocity value based on selected curve
;    98-F5    Note number lowest note = 20 (needs translation by reciever to make into MIDI note)
;    F6-FE    Velcoity curve number
;    Error Condition if MSB is set on 2 consecutive bytes.
;    With Byte 2 As Error number
;
;    Velocity Curve
;    There are 10 curves to choose from. When VEL_CURVE pin is set (0 to 1).
;    the curve number is incremented. Then Vel IC send curve num (F6-FE)
;    corresponding to vel curves 0-9.
;EXTRN    DATA    (RCAP2L, RCAP2H, T2CON)
;EXTRN    BIT    (TF2)

;;;;;;
;
; BYTE Registers
; 8052 Extensions
T2CON   DATA    0C8H
RCAP2L  DATA    0CAH
RCAP2H  DATA    0CBH
; T2CON
TF2     BIT     0CFH
;;;;;;




KEY_OUT_H_BITS    equ    11110000b    ; Used to set bits P3.4-7
KeyOut_H    equ    P3        ; Row Select lines 8-11 (P3.4-7)
KeyOut_L    equ    P1        ; Row Select lines 0-7
KeyIn_L        equ    P0        ; U0 U1 U2 U3 U4 U5 U6 U7 followed by L0 L1 L2 L3 L4 L5 L6 L7
KeyIn_H        equ    P2        ; U8 U9 U10 U11 U12 U13 U14 U15 followed by L8 L9 L10 L11 L12 L13 L14 L15
DataOut        equ    P0        ; Data sent on same port as keys read
ST9_ACK        equ    P3.3        ; Request Acknowledge From ST9
VEL_IRQ        equ    P3.1        ; Velocity interrupt to ST9
VEL_CURVE    equ    P3.2        ; Request new velcity curve

StateA        equ    00000000b    ; State Definitions
StateB        equ    01000000b
StateC        equ    10000000b
StateD        equ    11000000b
LOWESTNOTE    equ    24        ; Lowest note = C 0
NOTE_0        equ    20        ; Initial note returned from velocity keys
NOTES        equ    88        ; 88 notes available
COUNTER        equ    200        ; Counter reload value
ROWS_L        equ    10        ; Number of rows on lower half of the keybed
ROWS_H        equ    12        ; Number of rows on upper half of the keybed
ROW_0        equ    07FFFh        ; Initial row select
NOTE_FLAG_    equ    7        ; Note data has MSB set
NOTE_FLAG    equ    080h        ; Note data has MSB set
NOTE_OFF    equ    0        ; Velocity value for note off
DEF_VEL_CURVE    equ    0        ; Default Velocity curve
VEL_CURVE_0    equ    0F6h        ; Initial Velocity curve
VEL_CURVES    equ    10        ; Number of velocity curves

DSEG AT 8
KeyInUpper:    ds    1        ; Store for current switch high
KeyInLower:    ds    1        ; Store for current switch low
RowIdx:        ds    1        ; Offset into RowSelectTab
VelCurve:    ds    1        ; Velocity Curve

ISEG AT 12
StackLocation:    ds    8

; Allow room for 88 notes
ISEG AT NOTE_0
CountersHIGH:    ds    NOTES    ; Bits 0-5 timer : Bits 6-7 KeyStatus
OldKeyStatUPPER: ds    NOTES/8 ; Storage for previous key state Upper
ISEG AT NOTE_0+80h
CountersLOW:    ds    NOTES    ; 8 bit captured timer value
OldKeyStatLOWER: ds    NOTES/8 ; Storage for previous key state Lower


; Register Usage
; [ACC]        General Purpose
; [B]        Bit addressable temp for key input
; [R0]        Points key counter HIGH : State flags
; [R1]        Points previous row status
; [R2]        Row Counter
; [R3]        Captured Timer HIGH
; [R4]        Captured Timer LOW
; [R5]        Temp timer LOW
; [R6]        Event timer HIGH
; [R7]        Event timer LOW
; [DPTR]    Nearly always points to Jump table start


; No Action In Jump Table ie Returns
NOACTION    MACRO
    db    022h,022h
ENDM

; Macro To Update State Of A Key
TestKey        MACRO    KeyNumber
        mov    a,@R0            ; Get previous key status
        mov    b,KeyInUpper
        mov    c,b.KeyNumber    ; Get Upper into [A.5]
        mov    ACC.5,c
        mov    b,KeyInLower
        mov    c,b.Keynumber    ; Get Lower into [A.4]
        mov    ACC.4,c
        acall    HandleState
ENDM

; Macro to select next scan row
NEXT_ROW    MACRO
        push    ACC
        mov    a,RowIdx        ;Get offset into row select
        movc    a,@a+dptr        ;Get value from RowSelectTab
        orl    KeyOut_H,#KEY_OUT_H_BITS
        anl    KeyOut_H,a
;        mov    KeyOut_H,a
        inc    RowIdx
        mov    a,RowIdx        ;Get offset into row select
        movc    a,@a+dptr        ;Get value from RowSelectTab
        mov    KeyOut_L,a
        inc    RowIdx
        pop    ACC
ENDM

; Write value in [ACC] to [DataOut]
; This uses a polling method to wait for serial ready.
TX        MACRO
        LOCAL    WaitAckClr, WaitAckSet
        jnb    ST9_ACK,$        ;Ensure ST9 has finished reading previous byte
        clr    VEL_IRQ            ;Generate IRQ on the ST9
        jb    ST9_ACK,$        ;Wait for ST9 to respond to IRQ & set ACK low
        mov    DataOut,a        ;Put data on the bus
        setb    VEL_IRQ            ;Flag data is ready to read.
        ENDM

CSEG AT    0
USING    0
VEL_A:
        ljmp    ProgSt            ; Reset
        ljmp    ProgSt            ; Power Down Interupt
        db    'R-W-A'
        ljmp    ProgSt            ; TF0
        db    'R-W-A'
        ljmp    ProgSt            ; IE1
        db    'R-W-A'
        ljmp    ProgSt            ; TF1
        db    'R-W-A'
        ljmp    ProgSt            ; Serial
        db    'R-W-A'
; Timer 2 used to update SW counter
; [r6] is decremented when [r7]=1, so timer has offset of 1
; code which reads the timer takes this into account

        clr    TF2            ; Reset Timer 2 IRQ
        djnz    r7,ExitIRQ
        dec    r6
        anl    AR6,#00111111b
ExitIrq:    reti


db        '88-Note Velocity Keyscan Processor : '
db        '(c) Evolution Electronics Ltd. : May 91 : '
db        'Version 1.6 : 22-Apr-04 : '


;----------------------------------------------------
;*****        REAL CODE STARTS HERE        *****
;----------------------------------------------------

ProgSt:        mov    IE,#0            ; Kill interupts
        mov    PSW,#0            ; For Emulator Restart
        mov    SP,#StackLocation-1    ; Set up stack pointer
        mov    KeyIn_L,#0FFh        ; Config Key return lines as Input
        mov    KeyIn_H,#0FFh        ; Config Key return lines as Input
        mov    P3,#0FFh        ; Set VEL_IRQ high, set other port bits as Input
        mov    VelCurve,#DEF_VEL_CURVE    ; Set initial velocity curve

        mov    r0,#OldKeyStatUpper    ; Assume previous keys off
        mov    r2,#NOTES/8
InitOldKeyUpper:mov    @r0,#0FFh
        inc    r0
        djnz    r2,InitOldKeyUpper

        mov    r0,#OldKeyStatLower    ; Assume previous keys off
        mov    r2,#NOTES/8
InitOldKeyLower:mov    @r0,#0FFh
        inc    r0
        djnz    r2,InitOldKeyLower

        mov    r0,#CountersHIGH    ; Set all Keys To StateA
        mov    r1,#CountersLOW
        mov    r2,#NOTES

InitStateA:    mov    @r0,#StateA
        mov    @r1,#0
        inc    r0
        inc    r1
        djnz    r2,InitStateA

        mov    r6,#0
        mov    r7,#0

; Serial Mode 2 : 9 bits data : 375 kBits/sec
        mov    PCON,#80h        ;Double Baud rate
        mov    SCON,#10010000b        ;Serial Mode 2
        mov    T2CON,#00000100b    ;Setup timer 2
        mov    RCAP2H,#HIGH (0 - COUNTER)
        mov    RCAP2L,#LOW  (0 - COUNTER)

;        setb    TI            ;Enable serial XMIT
        mov    IE,#10100000b        ;Start timer2
;        setb    VEL_IRQ            ;Setting IRQ low triggers interrupt on ST9, so start with it high

;*****    Main Program Loop

ScanAllKeys:    acall    IncVelCurve        ;Is there a request for a new velocity curve
        mov    dptr,#RowSelectTab
        mov    RowIdx,#0        ;Init offset into RowSelectTab
        NEXT_ROW            ;Select Initial row
        mov    r2,#ROWS_L/2        ;Init row counter, 2 rows read on each pass
        mov    r1,#OldKeyStatUpper    ;+(NOTES/8)-1

        ;Capture timer so all notes in chord have same vel
CaptureTimer:    mov    a,r6
        mov    AR4,r7
        cjne    a,AR6,CaptureTimer
        mov    r3,a
        dec    r4            ; Allow for offset

; Check Next 8 Keys
; This Code Expanded Inline For Speed , e' spaghetti moltissimo
ScanUpr_L:    mov    a,KeyIn_L        ; Sample new key state upper
        NEXT_ROW            ; Advance row
        anl    AR1,#01111111b
        xch    a,@r1            ; Save new : get old
        xrl    a,@r1            ; check for changes
        jnz    ScanLwr_L        ; Capture lower if not same

        mov    a,KeyIn_L        ; Sample new key state lower
;        NEXT_ROW            ; Advance row
        mov    KeyInLower,a
        orl    AR1,#10000000b
        xch    a,@r1            ; Save new : get old
        xrl    a,@r1            ; check for changes
        jnz    ProcKeys_L        ; Process switches if not the same
        jmp    Ready4Next_L

ScanLwr_L:    mov    a,KeyIn_L        ; Capture lower if upper different
;        NEXT_ROW            ; Advance row
        orl    AR1,#10000000b
        mov    @r1,a

ProcKeys_L:    mov    KeyOut_H,#0FFh        ; Deselect rows during event processing
        mov    KeyOut_L,#0FFh
        
        mov    a,@r1            ; Get key in values to process
        mov    KeyInLower,a
        anl    AR1,#01111111b
        mov    a,@r1
        mov    KeyInUpper,a

        mov    a,r1            ; Calculate key address
        add    a,#-OldKeyStatUpper    ; from Row pointer
        swap    a            ; Multiply by 8
        rr    a
        add    a,#CountersHIGH
        mov    r0,a

        TestKey    0            ; Go check keys
        inc    r0            ; Next Key
        TestKey    1
        inc    r0
        TestKey    2
        inc    r0
        TestKey    3
        inc    r0
        TestKey    4
        inc    r0
        TestKey    5
        inc    r0
        TestKey    6
        inc    r0
        TestKey    7

        mov    dptr,#RowSelectTab    ;Reset [dptr] back to RowSelectTab
        jnb    ST9_ACK,$        ;Ensure ST9 has finished reading previous byte

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -