; WRITTEN BY: TOM SCARFF ; DATE: 29/11/2000 ; ITERATION: 1.0 ; FILE SAVED AS: key2midi.ASM ; FOR: PIC16F877 ; CLOCK: 4.00 MHz CRYSTAL ; INSTRUCTION CLOCK: 1.00 MHz T= luS ; PROGRAMME FUNCTION: To read 128 note keyboard ; and to transmit MIDI out. list p=16F877 ; list directive to define processor #include "p16f877.inc" ; processor specific variable definitions __CONFIG _CP_ALL & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _XT_OSC & _WRT_ENABLE_OFF & _LVP_OFF & _DEBUG_OFF & _CPD_OFF ; '__CONFIG' directive is used to embed configuration data within .asm file. ; The lables following the directive are located in the respective .inc file. ; See respective data sheet for additional information on configuration word. #DEFINE PAGE0 BCF 3,5 #DEFINE PAGE1 BSF 3,5 TEMP EQU 20 COUNT EQU 21 CHANA EQU 22 ;midi channel number minus 1 note equ 23 midich equ 24 dlyreg3 equ 25 NTEREG EQU 50 ;reserved for ;note register ;128 bytes ;addreses 64 - 192 ;******************************************************* ; START OF PROGRAM MEMORY ;******************************************************* ORG 0 goto INIT ;************************************* ; Delay Subroutine (770uS) ;************************************* delay3 movlw .255 movwf dlyreg3 dly3 decfsz dlyreg3 goto dly3 nop return ;****************************************** ; transmission complete subroutine ;***************+************************** txchar bsf STATUS,RP0 btfss TXSTA,1 ; test for end of transmission goto $-1 bcf STATUS,RP0 return ;******************************************* ; Initialization ;******************************************* INIT PAGE1 movlw 05h ; enable weak pull-up resistors movwf OPTION_REG ; and TMR0 set to 1:64=16mS MOVLW 6 MOVWF ADCON1 ;set port a as digital CLRF TRISA ;all pins outputs CLRF TRISD ;all pins outputs movlw 04h ; 0000 0100 movwf TRISE ; pin 2 input & pins 0,1 outputs MOVLW 0FFh MOVWF TRISB ;all pins inputs PAGE0 CALL SETBAUD ;set up usart movf PORTC,W ; read midich. switches andlw 0Fh movwf midich goto main ;********************************************************************* ; Clear bits 0-7, RAM 64-79, 16x8 Flag REGISTER ;********************************************************************* clearflags MOVLW .64 ; Start at .64 MOVWF FSR ; First address used in RAM MOVLW .00 ; Clear RAM MOVWF INDF LOOPIT INCF FSR,F CLRW MOVWF INDF ;max velocity MOVFW FSR ;copy position to w XORLW .79 ;have we reached the end BTFSS STATUS,Z ; GOTO LOOPIT ;no so next one please ;yes job done return ;********************************************************************** ; Scan RB0-7 inputs (8) and compare with INDF, 0 to 7 ;********************************************************************** key_det ;call delay3 incf note,F btfsc PORTB,0 goto flagoff0? btfss INDF,0 goto setflag0 goto cont1 flagoff0? btfsc INDF,0 goto clearflag0 goto cont1 setflag0 bsf INDF,0 call noteon goto cont1 clearflag0 bcf INDF,0 call noteoff ;----------------------- cont1 ;call delay3 incf note,F btfsc PORTB,1 goto flagoff1? btfss INDF,1 goto setflag1 goto cont2 flagoff1? btfsc INDF,1 goto clearflag1 goto cont2 setflag1 bsf INDF,1 call noteon goto cont2 clearflag1 bcf INDF,1 call noteoff ;----------------------- cont2 ;call delay3 incf note,F btfsc PORTB,2 goto flagoff2? btfss INDF,2 goto setflag2 goto cont3 flagoff2? btfsc INDF,2 goto clearflag2 goto cont3 setflag2 bsf INDF,2 call noteon goto cont3 clearflag2 bcf INDF,2 call noteoff ;----------------------- cont3 ;call delay3 incf note,F btfsc PORTB,3 goto flagoff3? btfss INDF,3 goto setflag3 goto cont4 flagoff3? btfsc INDF,3 goto clearflag3 goto cont4 setflag3 bsf INDF,3 call noteon goto cont4 clearflag3 bcf INDF,3 call noteoff ;----------------------- cont4 ;call delay3 incf note,F btfsc PORTB,4 goto flagoff4? btfss INDF,4 goto setflag4 goto cont5 flagoff4? btfsc INDF,4 goto clearflag4 goto cont5 setflag4 bsf INDF,4 call noteon goto cont5 clearflag4 bcf INDF,4 call noteoff ;----------------------- cont5 ;call delay3 incf note,F btfsc PORTB,5 goto flagoff5? btfss INDF,5 goto setflag5 goto cont6 flagoff5? btfsc INDF,5 goto clearflag5 goto cont6 setflag5 bsf INDF,5 call noteon goto cont6 clearflag5 bcf INDF,5 call noteoff ;----------------------- cont6 ;call delay3 incf note,F btfsc PORTB,6 goto flagoff6? btfss INDF,6 goto setflag6 goto cont7 flagoff6? btfsc INDF,6 goto clearflag6 goto cont7 setflag6 bsf INDF,6 call noteon goto cont7 clearflag6 bcf INDF,6 call noteoff ;----------------------- cont7 ;call delay3 incf note,F btfsc PORTB,7 goto flagoff7? btfss INDF,7 goto setflag7 goto cont8 flagoff7? btfsc INDF,7 goto clearflag7 goto cont8 setflag7 bsf INDF,7 call noteon goto cont8 clearflag7 bcf INDF,7 call noteoff cont8 ;call delay3 incf FSR,F return ;************************************************************************ ; Output MIDI NOTE-On data ;*********************************************************************** noteon movlw 090h ; Note-on ch.? addwf midich,W movwf TXREG ; send chazacter from W call txchar movf note,W movwf TXREG ; send character from W call txchar movlw 040h ; half velocity movwf TXREG ; send character from W call txchar return ;********************************************************************** ; Output MIDI Note-off data ;********************************************************************** noteoff movlw 080h ; Note-off ch.? addwf midich,W movwf TXREG ; send character from W call txchar movf note,W movwf TXREG ; send character from W call txchar movlw 040h ; half velocity movwf TXREG ; send character from W call txchar return ;******************************************************************** SETBAUD ; Set up USART bsf STATUS,RP0 ; goto page 1 movlw b'10001111' ; RC7 is RX input movwf TRISC ; RC0-3 is MIDI ch. sel. Sw. movlw 01h ; 31250 baud for MIDI movwf SPBRG movlw b'00100000' ; async tx 8 bit movwf TXSTA bcf STATUS,RP0 ; return to page 0 movlw b'10010000' ; async rx 8 bit movwf RCSTA RETURN ;********************************************************************** ; Main Programme Start ;********************************************************************** main call clearflags ;********************************************************************** ; Scan 128 keys with RD0-7, RA0-5 and RE0-1 all outputs (16) ; and RB0-7 inputs (8) 16x8=128 ;********************************************************************** scankey clrf TMR0 movlw 0FFh movwf note MOVLW .64 ; 64+16=>79 MOVWF FSR movlw 0FFh movwf PORTD movwf PORTA movwf PORTE bcf PORTD,0 call key_det bsf PORTD,0 movlw 0FFh movwf PORTD bcf PORTD,1 call key_det bsf PORTD,1 movlw 0FFh movwf PORTD bcf PORTD,2 call key_det bsf PORTD,2 movlw 0FFh movwf PORTD bcf PORTD,3 call key_det bsf PORTD,3 movlw 0FFh movwf PORTD bcf PORTD,4 call key_det bsf PORTD,4 movlw 0FFh movwf PORTD bcf PORTD,5 call key_det bsf PORTD,5 movlw 0FFh movwf PORTD bcf PORTD,6 call key_det bsf PORTD,6 movlw 0FFh movwf PORTD bcf PORTD,7 call key_det bsf PORTD,7 movlw 0FFh movwf PORTD movwf PORTA movlw 0FFh movwf PORTA bcf PORTA,0 call key_det bsf PORTA,0 movlw 0FFh movwf PORTA bcf PORTA,1 call key_det bsf PORTA,1 movlw 0FFh movwf PORTA bcf PORTA,2 call key_det bsf PORTA,2 movlw 0FFh movwf PORTA bcf PORTA,3 call key_det bsf PORTA,3 movlw 0FFh movwf PORTA bcf PORTA,4 call key_det bsf PORTA,4 movlw 0FFh movwf PORTA bcf PORTA,5 call key_det bsf PORTA,5 movlw 0FFh movwf PORTA movwf PORTE movlw 0FFh movwf PORTE bcf PORTE,0 call key_det bsf PORTE,0 movlw 0FFh movwf PORTE bcf PORTE,1 call key_det bsf PORTE,1 sw_dbnc movf TMR0,W ;call delay xorlw 00h btfss STATUS,Z goto sw_dbnc btfsc PORTE,2 goto scankey movf PORTC,W ; read midich. switches andlw 0Fh movwf midich goto scankey ;*********************************************************************************************** END