找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 4234|回復(fù): 14
打印 上一主題 下一主題
收起左側(cè)

51單片機(jī)要如何同時(shí)測(cè)定61個(gè)電子琴按鍵的力度(速度)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
各位好!

我是新手,請(qǐng)大家多關(guān)照,最近想設(shè)計(jì)一臺(tái)用STC單片機(jī)做的61鍵無(wú)線藍(lán)牙電子琴,用現(xiàn)成的廉價(jià)電子琴來(lái)改裝,打算直接掃描16X8行列的狀態(tài)加以處理,這部分程序已經(jīng)寫好測(cè)試妥當(dāng)了(附程序),由于這是一個(gè)有力度感的鍵盤,一個(gè)鍵有2個(gè)觸點(diǎn),通過(guò)測(cè)定觸點(diǎn)的接觸時(shí)間差計(jì)算出速度而換算為力度,原理是很簡(jiǎn)單,但實(shí)施起來(lái)很困難,怎樣也想不通,所以特地來(lái)請(qǐng)教各位高手,原理是:運(yùn)行單片機(jī)內(nèi)的計(jì)時(shí)器(向上),當(dāng)檢測(cè)到第一個(gè)接觸點(diǎn)時(shí),讀取定時(shí)器數(shù)值存入相應(yīng)的記憶1,等檢測(cè)到第二個(gè)接觸點(diǎn)時(shí), 再讀取定時(shí)器數(shù)值存入相應(yīng)的記憶2,兩個(gè)數(shù)字的差就是力度了。硬件上的設(shè)計(jì)確定一個(gè)琴鍵按下時(shí),第一觸點(diǎn)一定比第二觸點(diǎn)快,所以記憶2的數(shù)值一定比記憶1的數(shù)值大,問(wèn)題在于計(jì)數(shù)器溢出時(shí)就會(huì)是記憶2的數(shù)值一定比記憶1的數(shù)值小了,更大的問(wèn)題是如果時(shí)間再長(zhǎng)些,記憶2的數(shù)值又會(huì)比記憶1的數(shù)值大,變成無(wú)法分析而確定的難題了。不知道各位是否看過(guò)這方面的文獻(xiàn)介紹過(guò)解決這問(wèn)題的方法,現(xiàn)實(shí)是有力度的電子琴滿街都在賣,廠家肯定已經(jīng)解決問(wèn)題了,就是我這新手笨,想不通,特來(lái)請(qǐng)教大家。

SCANNER:
;MOV 38H, #0
;MOV 39H, #0
;CPL P1.2
SCANP2:              ; SHIFT P2 AND READ P0
MOV 32H, #8          ;8 BITS TO SHIFT
MOV 30H, #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, 30H
RRC A
MOV 30H, A
MOV P2, A            ;P2 ONE ROW LOW
LCALL DELAY4         ;MUST WAIT STABLE
MOV A, P0            ;READ FROM P0
CPL A
JZ SCANNEXT1           ;NO KEY PRESS FOUND, READP1
LCALL STOREDATA
SCANNEXT1:
;LCALL DELAY2
DJNZ 32H, SCANP2A
MOV P2, #11111111B   ;END OF SCANP2
;JMP SCANNER

SCANP3:              ; SHIFT P3 AND READ P0
MOV 32H, #8          ;8 BITS TO SHIFT
MOV 30H, #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, 30H
RRC A
MOV 30H, A
MOV P3, A            ;P2 ONE ROW LOW
LCALL DELAY4         ;MUST WAIT STABLE
MOV A, P0            ;READ FROM P0
CPL A
JZ SCANNEXT2           ;NO KEY PRESS FOUND, READP1
LCALL STOREDATA
SCANNEXT2:
;LCALL DELAY2
DJNZ 32H, SCANP3A
MOV P3, #11111111B   ;END OF SCANP
;LCALL DELAY5
JMP SCANNER

STOREDATA:           ;32H CONTAIN ROW NUMBER 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:
MOV A, 33H
;MOV P0, A
CLR C
RLC A
MOV 33H, A
JNC NEXTBIT ;NOT PRESSED
LCALL COUNTPOSITION
LCALL KEYMAP
LCALL SENTONEBYTE2
LCALL SENTTIMER
;LCALL DELAY5
NEXTBIT:
DJNZ 34H, STOREDATA1

POP PSW
RET

SENTTIMER:
MOV A, 38H
LCALL SENTONEBYTE2
MOV A, 39H
LCALL SENTONEBYTE2

RET

KEYMAP:
MOV DPH, #10H
MOV DPL, #00H
MOVC A,@A+DPTR
RET

COUNTPOSITION:
;ROWxCOLxCOL
PUSH PSW
MOV A, 32H        ;1-8
ADD A, 35H        ;+0=old or +8=16LEFT8(0-7) SO 1=16
MOV 37H, A
MOV A, #0
COUNT1:
ADD A, #8
DJNZ 37H, COUNT1  ;A WILL BE 8,16,24,32,40.......128
CLR C
SUBB A, #8        ;MAKE A 0-120
ADD A, 34H        ;(1-8)  A=1 TO 128
DEC A             ;MAKE 0-127 SYSTEM
POP PSW
RET

STOREUPKEY: ;FIRST
RET

STOREDNKEY: ;SECOND
RET

TIMER_1:  ;USE FOR MICRO CLOCK 1MS 184, 30 ,100US=248 250
PUSH ACC
CPL P1.2
INC 38H   ;16BIT TIMER3
MOV A, 38H
JNZ TIMER3
CPL P1.5
INC 39H
MOV A, 39H
JNZ TIMER3
CPL P1.7
TIMER3:
MOV TH1, #248
MOV TL1, #250
POP ACC
RETI

SENTONEBYTE2:        ;A SENT OUT
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
RET

DELAY4:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
RET



評(píng)分

參與人數(shù) 1黑幣 +8 收起 理由
arthuryu + 8 贊一個(gè)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:7485 發(fā)表于 2018-2-13 19:08 | 只看該作者
你的這個(gè)思路存在一定的問(wèn)題。
1、當(dāng)單片機(jī)檢測(cè)到第一按鍵閉合時(shí),啟動(dòng)定時(shí)器,當(dāng)檢測(cè)到第二按鍵閉合時(shí)停止定時(shí)器,定時(shí)器的運(yùn)行數(shù)就是時(shí)間差,不需要計(jì)算。
2、你有這么多的IO嗎?你需要擴(kuò)展,或者需要模擬開關(guān)電路如cd4051之類的。

評(píng)分

參與人數(shù) 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

板凳
ID:283954 發(fā)表于 2018-2-13 21:59 | 只看該作者
你好!是一次過(guò)掃描16X8共128個(gè)接點(diǎn)的狀態(tài),先儲(chǔ)存在記憶區(qū),再讀取記憶區(qū)作處理,有琴鍵按下就向串口發(fā)出MIDI數(shù)據(jù)。再更新記憶區(qū),如果是沒有力度感的電子琴,那就很簡(jiǎn)單了,有力度感的就要記錄一個(gè)按鍵的兩個(gè)接點(diǎn)的接觸時(shí)間再作運(yùn)算,相當(dāng)麻煩。

評(píng)分

參與人數(shù) 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

地板
ID:123289 發(fā)表于 2018-2-14 16:41 | 只看該作者
你的構(gòu)思是正確的,精心安排一下是可以實(shí)現(xiàn)的。
1、建議你將力度安排為255級(jí),這樣一位就夠了。
2、時(shí)基要重新設(shè)計(jì)并制作,當(dāng)計(jì)數(shù)=255時(shí),設(shè)計(jì)為最慢的時(shí)間,比此時(shí)間更慢就不認(rèn)可。
3、第一個(gè)鍵后計(jì)數(shù)器設(shè)置為1.
4、當(dāng)計(jì)數(shù)器=0時(shí),不計(jì)數(shù)。
5、當(dāng)計(jì)數(shù)器<>0時(shí),每個(gè)時(shí)基+1
6、如此,第二個(gè)鍵時(shí),讀到0就作未按處理,不是0就計(jì)算速度(力度)。用過(guò)了清0。
要點(diǎn):設(shè)計(jì)適當(dāng)?shù)臅r(shí)基,即多久+1.
如果要分得更細(xì),則需增加計(jì)數(shù)器的位數(shù)。
回復(fù)

使用道具 舉報(bào)

5#
ID:123289 發(fā)表于 2018-2-14 16:43 | 只看該作者
當(dāng)然-1也可以,看你愛好。
回復(fù)

使用道具 舉報(bào)

6#
ID:283954 發(fā)表于 2018-2-14 17:56 | 只看該作者
yzwzfyz你好!
果然有好辦法,我這兩天試著自己想辦法,把計(jì)數(shù)器的值寫在記憶區(qū)的笨辦法,越寫越亂,快要放棄,但作為初學(xué)者,這種磨煉還是應(yīng)該的,現(xiàn)在有好辦法了,今晚應(yīng)該就能寫好了,多謝指教。
回復(fù)

使用道具 舉報(bào)

7#
ID:123289 發(fā)表于 2018-2-14 23:43 | 只看該作者
我看你是用匯編寫程序的,是真想學(xué)好單片機(jī)的,故點(diǎn)一下。
回復(fù)

使用道具 舉報(bào)

8#
ID:283954 發(fā)表于 2018-2-16 03:04 | 只看該作者
寫了兩個(gè)晚上才測(cè)試妥當(dāng),只要邏輯正確,其他可慢慢修改了,這東西難寫處在于io口幾乎用完,無(wú)法用LED燈檢查結(jié)果,另外運(yùn)行時(shí)T1會(huì)中斷修改一些寄存器如DPL, 增加調(diào)試的困難,無(wú)論如何算是寫成了,就上載給大家參考了, 再謝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

回復(fù)

使用道具 舉報(bào)

9#
ID:123289 發(fā)表于 2018-2-16 11:02 | 只看該作者
樓主果然聰明,一點(diǎn)就通,悟性好。未來(lái)不可限量。祝你春節(jié)快樂(lè)!
回復(fù)

使用道具 舉報(bào)

10#
ID:123289 發(fā)表于 2018-2-16 11:14 | 只看該作者
硬件上:你用了5個(gè)口,滿算是40個(gè)IO
你需要:61*2=122個(gè)口
建議用:4路掃描,乘以31個(gè)口。掃描路數(shù)越少,用時(shí)越短。這個(gè)程序主要矛盾是速度!
回復(fù)

使用道具 舉報(bào)

11#
ID:123289 發(fā)表于 2018-2-16 14:21 | 只看該作者
硬件IO的排列有講究。你需要用最短的掃描時(shí)間,捕捉到是哪個(gè)按鍵按下了。
所以同一個(gè)琴鍵是的兩個(gè)鍵,不要放在同一個(gè)P口上。
要點(diǎn):
1、不要用防彈動(dòng)程序,以節(jié)省時(shí)間,一次即認(rèn)可。
2、一次讀8個(gè)鍵,無(wú)鍵立即轉(zhuǎn)讀下8個(gè)鍵,如此,在無(wú)鍵的情況下,讀16次P口即可完成對(duì)所有鍵掃描。
3、如果有鍵,則再花點(diǎn)時(shí)間區(qū)分是哪個(gè)鍵,需要起動(dòng)哪個(gè)計(jì)時(shí)器。
4、另一種更好的方案是,用IO口中斷:
正常輪流掃四路通道,中斷后先查是哪個(gè)Px產(chǎn)生了中斷,再查掃描的是哪一路,就能確定是哪個(gè)鍵了。

回復(fù)

使用道具 舉報(bào)

12#
ID:123289 發(fā)表于 2018-2-16 14:28 | 只看該作者
時(shí)間中斷后,輪查122個(gè)計(jì)時(shí)器。為0的放棄,不為0的+1計(jì)時(shí)。
掃到第一路鍵(合理的安排是,61個(gè)第一路鍵放于前兩路掃描中;另61個(gè)第二路鍵放在后兩路掃描中)置1,掃到第二路鍵取對(duì)應(yīng)計(jì)時(shí)器值分析力度,用后清0.
回復(fù)

使用道具 舉報(bào)

13#
ID:123289 發(fā)表于 2018-2-16 14:29 | 只看該作者
真正的編程序,是你如何構(gòu)思方案。寫程序并不重要。

評(píng)分

參與人數(shù) 1黑幣 +8 收起 理由
arthuryu + 8 很給力!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

14#
ID:283954 發(fā)表于 2018-2-16 16:57 | 只看該作者
我剛測(cè)定過(guò),空鍵時(shí)掃描一次的時(shí)間包括處理為1.584ms, 一鍵時(shí)是1.592ms, 五鍵同按是1.618ms, 一秒鐘能檢測(cè)到大概500次按鍵,以電子琴來(lái)說(shuō)速度可以了,這琴鍵按鈕是拆廠家成品電子琴來(lái)試的,是16X8的行列,16位兩個(gè)接口P2P3為輸出,8位為輸入P0, 所以得根據(jù)這樣的結(jié)構(gòu)編程, 我在寫的時(shí)候才發(fā)現(xiàn)就算沒有什么鍵按下還得逐個(gè)檢查記憶體的,因?yàn)橐槌?FFH再發(fā)出noteoff信號(hào),這里面有個(gè)憂慮就是擔(dān)心在檢查記憶體時(shí)產(chǎn)生時(shí)鐘中斷改變了DPL而讀錯(cuò),  所以開始時(shí)先關(guān)掉時(shí)鐘,檢查完再開時(shí)鐘,應(yīng)該會(huì)影響到時(shí)鐘進(jìn)位的精度。那個(gè)LCALL DELAY2 是個(gè)惡夢(mèng),不是防抖動(dòng)用的,原來(lái)STC單片機(jī)的輸出有滯后,在輸出0后,再回復(fù)1會(huì)滯后,造成誤讀,所以要延時(shí)讓輸出穩(wěn)定,這現(xiàn)象讓我花費(fèi)了一天時(shí)間才發(fā)現(xiàn)。關(guān)于用IO中斷,STC單片機(jī)好像沒有提供這個(gè)功能,無(wú)法實(shí)現(xiàn)。
這程序若可以用我就會(huì)制作一個(gè)電路板來(lái)試,可以的話就用來(lái)取代原來(lái)那臺(tái)電子琴的電路板,變成無(wú)線電子琴了。

評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 回帖助人的獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

15#
ID:283954 發(fā)表于 2018-2-20 15:02 | 只看該作者
過(guò)年前得高人指點(diǎn),得61鍵力度點(diǎn)子,經(jīng)二夜碼字,DIY電子琴看來(lái)得以誕生,又經(jīng)春節(jié)三日無(wú)事干,畫線路為樂(lè),得線路板設(shè)計(jì)一片,上載與電子愛好者共享:

這板子上右好幾個(gè)IC, 從右邊起:

1。第一個(gè)CPU專門掃描琴鍵用,掃好的碼本來(lái)通過(guò)UART輸出midi碼就可以讓音源發(fā)出聲音了,但標(biāo)準(zhǔn)MIDI的串口波特率是31250BPS,十個(gè)位元得等待320us, 會(huì)影響力度進(jìn)位時(shí)鐘t1的運(yùn)作,所以改用并口p1輸出到第二個(gè)CPU處理。

2。第二個(gè)CPU接收到第一個(gè)CPU送來(lái)的MIDI碼后,經(jīng)過(guò)分析處理后再送往UART2的藍(lán)牙模塊發(fā)送,由于市場(chǎng)上的藍(lán)牙模塊只支持38400的波特率,為了能同時(shí)支持標(biāo)準(zhǔn)的5pin midi 插口輸出,打算同時(shí)用UART1作標(biāo)準(zhǔn)31250輸出。

3.  充電模塊TP4056,由于采用18650鋰電池供電,得有充電裝置。

4.  穩(wěn)壓IC HT7833 讓電壓保持3.3V,另有HT7030電壓檢測(cè)IC,當(dāng)電池電壓小于3.0V時(shí)關(guān)閉HT7833,防止電池過(guò)度放電而損壞。

5。觸摸開關(guān)TTP223,通常DIY最難看的是部分是開關(guān)和按鈕,改用觸摸開關(guān)就好看許多。

6。USB MIDI CH345 IC 提供電腦接口,在不使用無(wú)線方式時(shí)可直接插入電腦使用,也同時(shí)為電池充電。

等過(guò)年后淘寶開店讓電路板公司打樣10片就能測(cè)試了。



評(píng)分

參與人數(shù) 1黑幣 +100 收起 理由
admin + 100 回帖助人的獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表