; WRITTEN BY: TOM SCARFF ; DATE: 22/10/2002 ; ITERATION: 1.1 ; FILE SAVED AS: cc_onoff.ASM ; MODIFICATION: ; ; FOR: PIC16F877 ; CLOCK: 4.00 MHz CRYSTAL ; INSTRUCTION CLOCK: 1.00 MHz T= luS ; PROGRAMME FUNCTION: To read MIDI in and detect CC 111 to 118 ; and to transmit it to 8 (relay) outs. ; Record Mode reads switches and sends CC 111 to 118 ; to midi out and operates relays. list p=16F877 ; tells the assembler which PIC #include "p16F877.inc" ; general register file ;******************************** ; Constant Assignments ;******************************** RCIF equ 05h BORROW equ 0h ;******************************** ; Variable Assignment Addresses ;***t**************************** ; 20h Start of General purpose registers select EQU 21h output EQU 22h dlyreg2 equ 23h dlyreg3 equ 24h drum equ 25h val1 equ 26h val2 equ 27h rcvreg equ 28h midich equ 29h count equ 2Ah none_eq equ 2Bh temp1 equ 2Ch note equ 2Dh base_addr equ 2Eh temp equ 2Fh flags equ 30h ctrller equ 31h ; 7fh end of data area ;************************************ ; PROGRAMME Reset Point ;************************************ org 00 ; reset vector goto init ;************************************ ; Switch Debounce Delay 255mS ;************************************ sw_dbnc movlw .20 ; Delay routine variable movwf dlyreg2 debnce call delay3 decfsz dlyreg2 goto debnce return ;************************************* ; Delay Subroutine (1 mS) ;************************************* delay3 movlw .165 movwf dlyreg3 dly3 decfsz dlyreg3 goto dly3 movlw .165 movwf dlyreg3 dly4 decfsz dlyreg3 goto dly4 nop return ;****************************************** ; Receive Data subroutine ;****************************************** rxdata btfss PIR1,RCIF ; test for incoming data goto $-1 movf RCREG,W movwf rcvreg return ;****************************************** ; transmission complete subroutine ;***************+************************** txchar bsf STATUS,RP0 btfss TXSTA,1 ; test for end of transmission goto $-1 bcf STATUS,RP0 return ;****************************************** ; Output MIDI Controller data (Off) ;****************************************** control_off movf midich,W addlw 0B0h ; Control Change ch. from midich movwf TXREG ; send character from W call txchar movf ctrller,W andlw 07Fh movwf TXREG ; send character from W call txchar clrw ; controller off movwf TXREG ; send character from W call txchar return ;****************************************** ; Output MIDI Controller data (On) ;****************************************** control_on movf midich,W addlw 0B0h ; Control Change ch. from midich movwf TXREG ; send character from W call txchar movf ctrller,W andlw 07Fh movwf TXREG ; send character from W call txchar movlw .127 ; controller on movwf TXREG ; send character from W call txchar return ;******************************************************** ; Switch on the TTL output ;******************************************************** relay_on movlw 00h subwf select,W btfsc STATUS,Z goto sel0 movlw 01h subwf select,W btfsc STATUS,Z goto sel1 movlw 02h subwf select,W btfsc STATUS,Z goto sel2 movlw 03h subwf select,W btfsc STATUS,Z goto sel3 movlw 04h subwf select,W btfsc STATUS,Z goto sel4 movlw 05h subwf select,W btfsc STATUS,Z goto sel5 movlw 06h subwf select,W btfsc STATUS,Z goto sel6 movlw 07h subwf select,W btfsc STATUS,Z goto sel7 movlw 08h subwf select,W btfsc STATUS,Z goto sel8 movlw 09h subwf select,W btfsc STATUS,Z goto sel9 movlw .10 subwf select,W btfsc STATUS,Z goto sel10 movlw .11 subwf select,W btfsc STATUS,Z goto sel11 movlw .12 subwf select,W btfsc STATUS,Z goto sel12 movlw .13 subwf select,W btfsc STATUS,Z goto sel13 movlw .14 subwf select,W btfsc STATUS,Z goto sel14 movlw .15 subwf select,W btfsc STATUS,Z goto sel15 movlw .16 subwf select,W btfsc STATUS,Z goto sel16 movlw .17 subwf select,W btfsc STATUS,Z goto sel17 movlw .18 subwf select,W btfsc STATUS,Z goto sel18 movlw .19 subwf select,W btfsc STATUS,Z goto sel19 movlw .20 subwf select,W btfsc STATUS,Z goto sel20 movlw .21 subwf select,W btfsc STATUS,Z goto sel21 movlw .22 subwf select,W btfsc STATUS,Z goto sel22 movlw .23 subwf select,W btfsc STATUS,Z goto sel23 return sel0 bsf PORTA,0 ; switch on TTL o/p PORTA return sel1 bsf PORTA,1 ; switch on TTL o/p PORTA return sel2 bsf PORTA,2 ; switch on TTL o/p PORTA return sel3 bsf PORTA,3 ; switch on TTL o/p PORTA return sel4 bsf PORTA,4 ; switch on TTL o/p PORTA return sel5 bsf PORTA,5 ; switch on TTL o/p PORTA return sel6 bsf PORTE,0 ; switch on TTL o/p PORTE return sel7 bsf PORTE,1 ; switch on TTL o/p PORTE return sel8 bsf PORTD,0 ; switch on TTL o/p PORTD return sel9 bsf PORTD,1 ; switch on TTL o/p PORTD return sel10 bsf PORTD,2 ; switch on TTL o/p PORTD return sel11 bsf PORTD,3 ; switch on TTL o/p PORTD return sel12 bsf PORTD,4 ; switch on TTL o/p PORTD return sel13 bsf PORTD,5 ; switch on TTL o/p PORTD return sel14 bsf PORTD,6 ; switch on TTL o/p PORTD return sel15 bsf PORTD,7 ; switch on TTL o/p PORTD return sel16 bsf PORTB,0 ; switch on TTL o/p PORTB return sel17 bsf PORTB,1 ; switch on TTL o/p PORTB return sel18 bsf PORTB,2 ; switch on TTL o/p PORTB return sel19 bsf PORTB,3 ; switch on TTL o/p PORTB return sel20 bsf PORTB,4 ; switch on TTL o/p PORTB return sel21 bsf PORTB,5 ; switch on TTL o/p PORTB return sel22 bsf PORTB,6 ; switch on TTL o/p PORTB return sel23 bsf PORTB,7 ; switch on TTL o/p PORTB return ;******************************************************** ; Switch off the TTL output ;******************************************************** relay_off movlw 00h subwf select,W btfsc STATUS,Z goto seloff0 movlw 01h subwf select,W btfsc STATUS,Z goto seloff1 movlw 02h subwf select,W btfsc STATUS,Z goto seloff2 movlw 03h subwf select,W btfsc STATUS,Z goto seloff3 movlw 04h subwf select,W btfsc STATUS,Z goto seloff4 movlw 05h subwf select,W btfsc STATUS,Z goto seloff5 movlw 06h subwf select,W btfsc STATUS,Z goto seloff6 movlw 07h subwf select,W btfsc STATUS,Z goto seloff7 movlw 08h subwf select,W btfsc STATUS,Z goto seloff8 movlw 09h subwf select,W btfsc STATUS,Z goto seloff9 movlw .10 subwf select,W btfsc STATUS,Z goto seloff10 movlw .11 subwf select,W btfsc STATUS,Z goto seloff11 movlw .12 subwf select,W btfsc STATUS,Z goto seloff12 movlw .13 subwf select,W btfsc STATUS,Z goto seloff13 movlw .14 subwf select,W btfsc STATUS,Z goto seloff14 movlw .15 subwf select,W btfsc STATUS,Z goto seloff15 movlw .16 subwf select,W btfsc STATUS,Z goto seloff16 movlw .17 subwf select,W btfsc STATUS,Z goto seloff17 movlw .18 subwf select,W btfsc STATUS,Z goto seloff18 movlw .19 subwf select,W btfsc STATUS,Z goto seloff19 movlw .20 subwf select,W btfsc STATUS,Z goto seloff20 movlw .21 subwf select,W btfsc STATUS,Z goto seloff21 movlw .22 subwf select,W btfsc STATUS,Z goto seloff22 movlw .23 subwf select,W btfsc STATUS,Z goto seloff23 return seloff0 bcf PORTA,0 ; switch off TTL o/p PORTA return seloff1 bcf PORTA,1 ; switch off TTL o/p PORTA return seloff2 bcf PORTA,2 ; switch off TTL o/p PORTA return seloff3 bcf PORTA,3 ; switch off TTL o/p PORTA return seloff4 bcf PORTA,4 ; switch off TTL o/p PORTA return seloff5 bcf PORTA,5 ; switch off TTL o/p PORTA return seloff6 bcf PORTE,0 ; switch off TTL o/p PORTE return seloff7 bcf PORTE,1 ; switch off TTL o/p PORTE return seloff8 bcf PORTD,0 ; switch off TTL o/p PORTD return seloff9 bcf PORTD,1 ; switch off TTL o/p PORTD return seloff10 bcf PORTD,2 ; switch off TTL o/p PORTD return seloff11 bcf PORTD,3 ; switch off TTL o/p PORTD return seloff12 bcf PORTD,4 ; switch off TTL o/p PORTD return seloff13 bcf PORTD,5 ; switch off TTL o/p PORTD return seloff14 bcf PORTD,6 ; switch off TTL o/p PORTD return seloff15 bcf PORTD,7 ; switch off TTL o/p PORTD return seloff16 bcf PORTB,0 ; switch off TTL o/p PORTB return seloff17 bcf PORTB,1 ; switch off TTL o/p PORTB return seloff18 bcf PORTB,2 ; switch off TTL o/p PORTB return seloff19 bcf PORTB,3 ; switch off TTL o/p PORTB return seloff20 bcf PORTB,4 ; switch off TTL o/p PORTB return seloff21 bcf PORTB,5 ; switch off TTL o/p PORTB return seloff22 bcf PORTB,6 ; switch off TTL o/p PORTB return seloff23 bcf PORTB,7 ; switch off TTL o/p PORTB return ;****************************************** ; initalise software ;****************************************** init bcf STATUS,RP0 ;page 0 clrf PORTA clrf PORTB clrf PORTC clrf PORTD clrf PORTE bsf STATUS,RP0 MOVLW 6 MOVWF ADCON1 ;set port A as digital CLRF TRISA ;all pins outputs movlw 0FFh movwf TRISB ;all pins inputs CLRF TRISD ;all pins outputs movlw 04h ; 0000 0100 movwf TRISE ; bit 2 i/p bcf STATUS,RP0 ; return to page 0 ; Set up USART bsf STATUS,RP0 ; goto page 1 movlw b'10001111' ; RC7 is RX input movwf TRISC ; RC0-3 i/p MIDI Ch. 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 clrf PORTA ; set all outputs to '0000 0000' clrf PORTB clrf PORTD movlw 04h ; 0000 0100 movwf PORTE movf PORTC,W ; read midich. switches andlw 0Fh movwf midich goto start ;********************************************** ; Main ;*********************************************** start0 call sw_dbnc start btfss PORTE,2 ; read record mode switch goto record bcf PORTC,4 ; turn off record LED call rxdata ; is it status? movf rcvreg,W andlw 80h sublw 80h btfss STATUS,Z goto start midich? movf rcvreg,W ; correct MIDI Ch.? andlw 0Fh subwf midich,W btfss STATUS,Z goto start noteon? movf rcvreg,W andlw 0F0h sublw 0B0h ; is it controller? btfsc STATUS,Z goto cc_value goto start ;------------------------------------------------ cc_value call rxdata ; check controller value range1 movf rcvreg,W andlw 0F0h sublw 111h ; is it controller 111? btfsc STATUS,Z goto cc_on_off? movf rcvreg,W andlw 0F0h sublw 112h ; is it controller 112? btfsc STATUS,Z goto cc_on_off? movf rcvreg,W andlw 0F0h sublw 113h ; is it controller 113? btfsc STATUS,Z goto cc_on_off? movf rcvreg,W andlw 0F0h sublw 114h ; is it controller 114? btfsc STATUS,Z goto cc_on_off? movf rcvreg,W andlw 0F0h sublw 115h ; is it controller 115? btfsc STATUS,Z goto cc_on_off? movf rcvreg,W andlw 0F0h sublw 116h ; is it controller 116? btfsc STATUS,Z goto cc_on_off? movf rcvreg,W andlw 0F0h sublw 117h ; is it controller 117? btfsc STATUS,Z goto cc_on_off? movf rcvreg,W andlw 0F0h sublw 1111h ; is it controller 118? btfsc STATUS,Z goto cc_on_off? goto start ;------------------------------------------------- cc_on_off? movf rcvreg,W movwf select ; range 111h to 118h movlw 111h ; minus 111h = subwf select,F ; convert select to 0 to 7 call rxdata; controller value 0 or 1? movf rcvreg,F btfss STATUS,Z goto relay_on? goto relay_off? runstat1 call rxdata ; status or note? movf rcvreg,W andlw 80h sublw 80h btfss STATUS,Z goto range1 ; if in running status goto midich? relay_on? call relay_on goto runstat1 relay_off? call relay_off goto runstat1 ;********************************************** ; Record Mode Operation ;********************************************** record call sw_dbnc bsf PORTC,4 ; turn on record LED btfsc PORTE,2 goto start0 movf PORTB,W movwf temp movf PORTB,W xorwf flags,W btfss STATUS,Z goto check0 movf PORTB,W xorwf flags,W btfss STATUS,Z goto check1 movf PORTB,W xorwf flags,W btfss STATUS,Z goto check2 movf PORTB,W xorwf flags,W btfss STATUS,Z goto check3 movf PORTB,W xorwf flags,W btfss STATUS,Z goto check4 movf PORTB,W xorwf flags,W btfss STATUS,Z goto check5 movf PORTB,W xorwf flags,W btfss STATUS,Z goto check6 movf PORTB,W xorwf flags,W btfss STATUS,Z goto check7 goto record ;--------------------- check0 btfss PORTB,0 goto off_0 movlw 00h movwf select call relay_on movlw .111 movwf ctrller call control_on goto record off_0 movlw 00h movwf select call relay_off movlw .111 movwf ctrller call control_off goto record ;------------------------ check1 btfss PORTB,1 goto off_1 movlw 01h movwf select call relay_on movlw .112 movwf ctrller call control_on goto record off_1 movlw 01h movwf select call relay_off movlw .112 movwf ctrller call control_off goto record ;------------------------ check2 btfss PORTB,2 goto off_2 movlw 02h movwf select call relay_on movlw .113 movwf ctrller call control_on goto record off_2 movlw 02h movwf select call relay_off movlw .113 movwf ctrller call control_off goto record ;------------------------ check3 btfss PORTB,3 goto off_3 movlw 03h movwf select call relay_on movlw .114 movwf ctrller call control_on goto record off_3 movlw 03h movwf select call relay_off movlw .114 movwf ctrller call control_off goto record ;------------------------ check4 btfss PORTB,4 goto off_4 movlw 04h movwf select call relay_on movlw .115 movwf ctrller call control_on goto record off_4 movlw 04h movwf select call relay_off movlw .115 movwf ctrller call control_off goto record ;------------------------ check5 btfss PORTB,5 goto off_5 movlw 05h movwf select call relay_on movlw .116 movwf ctrller call control_on goto record off_5 movlw 05h movwf select call relay_off movlw .116 movwf ctrller call control_off goto record ;------------------------ check6 btfss PORTB,6 goto off_6 movlw 06h movwf select call relay_on movlw .117 movwf ctrller call control_on goto record off_6 movlw 06h movwf select call relay_off movlw .117 movwf ctrller call control_off goto record ;------------------------ check7 btfss PORTB,7 goto off_7 movlw 07h movwf select call relay_on movlw .118 movwf ctrller call control_on goto record off_7 movlw 07h movwf select call relay_off movlw .118 movwf ctrller call control_off goto record ;------------------------ end