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

📄 pckb.asm

📁 把PC键盘变成MIDi音符控制适配器电路单片机程序
💻 ASM
📖 第 1 页 / 共 3 页
字号:
		rjmp	GetChar	; yes,  do nothing for now						
KP_exit: rjmp	GetChar 	; code should never get here

;  get two digits; the ten's value comes first, then the one's value
KP_digit:	tst		KPvalue  
		brne	KP1digit
		mov		KPvalue,temp
		sbr		KPvalue, 0b10000000  ; the highest bit acts as a flag for 1st or 2nd digit 
		rjmp	GetChar
		
KP1digit:	;cli
		cbr		KPvalue,0b10000000
		mov		KPtemp,KPvalue   ; received 2nd digit, so multiply 1st digit by 10 and add 2nd
		lsl		KPvalue
		lsl		KPvalue
		lsl		KPvalue
		add		KPvalue, KPtemp
		add		KPvalue, KPtemp
		add		KPvalue, temp		;  max value 99 decimal in KPvalue
		mov		CurrentVoiceNumber, KPvalue
		clr		KPvalue
		rcall	ChangeVoice
		rjmp	GetChar
							
;************************************
;   DoNote   -  Turn a note off or on
;************************************						
DoNote:  
		sbrc	keyflags,OnOff_flag   ; if OnOff flag is set, then char is a MIDI note number to be played
		rcall	playMIDInote
		sbrs	keyflags,OnOff_flag  ; if OnOff flag is clear, then char is a playing MIDI note to be turned off
		rcall	TurnOffMIDInote
		rjmp	GetChar


;**************************************************************************************************************************
;  DECODE_DATA  -- subroutine to convert the scancode from the keyboard into a general category.
;   input: scancode (register value)   output = DecodeValue (register value)
;
;   DecodeValue < $40 (alphanumeric keys) == turn on or off MIDI note (depending on whether key is pressed down or released)
;   DecodeValue = $40 to $4b ( function keys)    == change voice or assign voice number to Fn key
;   DecodeValue = $80 to $8f  ( key pad)    == input a decimal number using keypad digits, then <enter>
;   DecodeValue = $c0 (SPACE key pressed)    == turn off all notes
;   DecodeValue = $f0 to $fe   ( special keys)    Each value between $f0 and $fe has its own handler code 
;   DecodeValue = $ff  == ignore this scancode
;
;**************************************************************************************************************************  
decode_data:
;   first check that Break flag is clear *** 
chkBreakFlag:
		sbrc	keyflags, Break_flag   ; the previous scancode was $f0 when break_flag is set
		rjmp	Break_set
;		sbrc	keyflags, E0_flag   ; the previous scancode was $f0 when break_flag is set
;		rjmp	Do_E0char
		
;   Break and Extended are clear, so do check the first three special conditions	
		cpi		scancode,$f0  ; 	$F0 =Breakcode  finger-off-the-key identifier
		brne	isLeftAltKey
		sbr		keyflags, (1<<Break_flag)  ; set Break flag  so that the next scancode will not be seen a keypress down	
		rjmp	setZero
	
isLeftAltKey: 
		cpi		scancode, $11
		brne	isCapsLock
		sbr		keyflags, (1<<Alt_flag)
		rjmp	setZero
		
isCapsLock:
		cpi		scancode, $58  ; caps lock key
		brne	isExtendedCode
		ldi		temp, CapsToggleValue
		eor		keyflags, temp

 ; Code to turn off / on Sustain Petal		
		nop
		sbrc	keyflags, Caps_flag
		rjmp	TurnOnSustain
		clr		SustainValue ; turn off sustain petal
		rcall	Sustain
		rjmp	setZero
TurnOnSustain:	
		ldi		temp,127
		mov		SustainValue,temp
		rcall	Sustain
		rjmp	SetZero

Sustain:
		ldi		TxData, MIDI_CONTROLLER_MSG
		rcall	PutMIDI
		ldi		TxData,64
		rcall	PutMIDI
		mov		TxData, SustainValue
		rcall	PutMIDI
		ret
		
isExtendedCode: ; check for E0 flag
		cpi		scancode,$e0  ;  $e0  extended char table
		brne	isE0set  ; scancode is not one of the three special cases
		sbr		keyflags,(1<<E0_flag) ; set E0 flag			
		rjmp	setZero	
	
isE0set: ; check if extended char scancode was previously sent
		sbrc	keyflags, E0_flag 	; test extended char flag 
		rjmp	Do_E0char		; determine the action to take for the extended keypress 
;-------------------------------------------------------------------------------------------------------------------	
;not shift, $E0, or $F0, and no flags are set;  so do a table lookup for a MIDI note key
isScan83:	cpi		scancode,$83
		brne	MIDIOnTableLookUp
		ldi		DecodeValue, $46
		rjmp	exit_decode
		
MIDIOnTableLookUp:
		out 	EEAR, scancode   ;Set the EEPROM's address
		sbi 	EECR, EERE        ;Send the Read strobe
		in		DecodeValue, EEDR           ;Put the data in the transmit register
		cpi		DecodeValue, $40
		brsh	exit_decode
		
		sbr		keyflags,(1<<OnOff_flag)  ; set the note on/off flag to turn note on
		rjmp 	exit_decode

;  Break flag is set - this means the previous scancode was $f0 (a key release)
;     This scancode is either the Extended sentinel ($e0) or the number of the key being released, which is either a shift or message key.
;     If the key being released is a shift key, clear the shift flag, set DecodeValue to zero and exit.
;     if the released key has an extended code, then the clear the break and the extended flags, set DecodeValue to zero and exit.
Break_set:
		cbr		keyflags,(1<<Break_flag) ; clear Break flag
		
 ;		If scancode is E0, then reset Break flag so that the next scancode is recognized as the last of an extended release sequence
;		instead of a normal keypress down.		
isE0:	cpi		scancode, $e0	; extended key press sentinel
		brne	isE0flagOn
		sbr		keyflags,(1<<Break_flag)
		sbr		keyflags,(1<<E0_flag) ; set extended flag		
		rjmp	setZero
isE0flagOn:		;  if the E0flag is on then this scancode is the extended character number that is being released.  Just clear flags.
		sbrs	keyflags, E0_flag   ; Extended flag on?
		rjmp	isAltflagOn		
		cbr		keyflags,(1<<Break_flag) ; yes, clear Break flag
		cbr		keyflags,(1<<E0_flag) ; clear extended flag
		rjmp	setZero	
		
isAltflagOn:
		sbrs	keyflags, Alt_flag
		rjmp	TableLookUp2 ;no, a note key is being released.  Determine the note and send MIDI note off message.
		cbr		keyflags,(1<<Alt_flag) ; clear Alt flag
		rjmp	setZero	
				
TableLookUp2:				;  find the offset of the note to be turned off
		out 	EEAR,scancode	;Set the EEPROM's address
		sbi 	EECR,EERE        ;Send the Read strobe
		in		DecodeValue ,EEDR           ;Put the data in the transmit register
		cpi		DecodeValue, $40
		brsh	setZero
		cbr		keyflags,(1<<OnOff_flag)  ;clear the note on/off flag to turn note off
		rjmp	exit_decode
setZero:  
		clr		DecodeValue
exit_decode: 				; subroutine single exit point
		ret
		
; *********************************************************************
;  previous scancode was $e0, so this is an extended character code
;  Program will come here when an extended key is pressed, not released
;**********************************************************************
Do_E0char:
		cbr		keyflags,(1<<E0_flag)  ; clear the E0 flag
		cpi 	scancode,$72  ; up arrow  LOWER the octave range
		brne	isDownArrow
		mov		temp, OctaveOffset
		cpi		temp,$7f - 12	; 12 is number of semitones in an octave
		brsh	setZero 		
		subi	temp,-12		; add (by subtracting minus number) one octave (12 semitones)
		cpi		temp,$7f		; $7f is max note number
		brsh	setZero 		; branch is same or higher (unsigned)		
		mov		OctaveOffset,temp
		rjmp	setZero
	
isDownArrow:
		cpi 	scancode,$75	; down arrow
		brne	isLeftArrow
		mov		temp, OctaveOffset
		cpi		temp,12  		; can't send a MIDI note on message note value that is less than zero
		brlo	setZero  		; branch is same or higher (unsigned)
		subi	temp,12		; number of semitone notes in a octave
		mov		OctaveOffset,temp
		rjmp		setZero
		
isLeftArrow:
		cpi 	scancode,$6b	; left arrow - change voice to previous in sequence
		brne	isRightArrow	
		mov		temp, CurrentVoiceNumber
		dec		temp
		andi	temp, 0b01111111
		mov		CurrentVoiceNumber, temp
		rcall	ChangeVoice
		rjmp	setZero
		
isRightArrow:
		cpi 	scancode,$74	; right arrow  - change voice to next in sequence
		brne	isRightAlt			
		mov		temp, CurrentVoiceNumber
		inc		temp
		andi	temp, 0b01111111
		mov		CurrentVoiceNumber, temp		
		rcall	ChangeVoice
		rjmp	setZero
		
isRightAlt:
		cpi 	scancode,$11	; right Alt key 
		brne	isRightCntrl
		sbr		keyflags, (1 << Alt_Flag)
		rjmp	setZero

isRightCntrl:
		cpi 	scancode,$14	; right Control key 
		brne	isInsert
		rjmp	setZero
		
isInsert:
		cpi 	scancode,$70	; Insert key 
		brne	isHomeKey
		rjmp	setZero
		
isHomeKey:
		cpi 	scancode,$6c	; Home key 
		brne	isDeleteKey
		rjmp	setZero

isDeleteKey:
		cpi 	scancode,$71	; Delete key 
		brne	isEndKey
		rjmp	setZero
	
isEndKey:
		cpi 	scancode,$69	; End key 
		brne	isPageUp
		rjmp	setZero
	
isPageUp:
		cpi 	scancode,$7d	; PageUp key 
		brne	isPageDown
		rjmp	setZero
				
isPageDown:
		cpi 	scancode,$7a	; PageDown key 
		brne	isKPenter
		rjmp	setZero
				
isKPenter:
		cpi 	scancode,$5a	; KeyPad Enter key 
		brne	isKPdivide
		rjmp	setZero
						
isKPdivide:
		cpi 	scancode,$5a	; KeyPad divide key 
		brne	isExtOther
		rjmp	setZero					

isPrtScrFirst:
		cpi 	scancode,$12	; First extended byte of PrintScreen key
		brne	isPrtScrSecond
		rjmp	setZero
		
isPrtScrSecond:
		cpi 	scancode,$7c	; second extended byte of PrintScreen key
		brne	isExtOther		; same as Keypad multiply  
		rjmp	setZero
		
isExtOther: 
		rjmp	setZero
; ***** end of Decode_Data subroutine *******************


;.include "PCkb2.asm"


; *********************************************************************************************

⌨️ 快捷键说明

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