; PROGRAM: MIDILITE.SRC ; Midi routine for controlling a lighting system from a keyboard, via ; the merged file, "LITECTRL.SRC" (Michael H. Whitco, 3-27-95). ; The midi communications routine is taken from Parallax PIC Application ; note: "Receiving RS-232 Serial Data", and is converted to 31.25K baud. ; Michael H. Whitco 3-28-95 ; This program receives a byte of serial data to control lights ; connected to port rb. The receiving baud rate is determined by the ; value of the constant bit_K and the clock speed (8.0 MHz) of the PIC. bit_K = 13 ;constant for received bit length. fast_led = ra.1 ;fast sequence indicator serial_in = ra.2 ;serial communication input count0 = 08h ;Assign label to register 08h for pattern hold time. count1 = 09h ;Assign label to register 09h " " " " . count2 = 0Ah ;Assign label to register 0Ah " " " " timer = 0Bh ;Assign label to register 0Bh for debounce time. ; Variable storage above special-purpose registers. org 8 delay_cntr ds 1 ;Counter for serial delay routines bit_cntr ds 1 ;Number of received bits rcv_byte ds 1 ;The received byte speed ds 1 ;sequence rate variable ; Org 0 sets ROM origin to beginning for program. org 0 device pic16c56,xt_osc,wdt_off,protect_off reset start ; Set up I/O ports. start mov speed,#07Fh clrb fast_led begin1 mov !ra, #00000100b ;Use ra.2 for serial input(pin 1). mov !rb, #0 ;Output to LEDs. clr rb ;!! clear any register which supports light sequences too! :start_bit snb serial_in ;Detect start bit(Use sb for 22k resistor input) jmp :start_bit ;No start bit yet? Keep watching. call start_delay1 ;Wait one-half bit time to the middle ;of the start bit. jb Serial_in,:start_bit ;If the start bit is still good, ;continue. Otherwise, resume waiting. ;(use jnb for 22k resistor input). mov bit_cntr, #8 ;Set the counter to receive 8 data bits clr rcv_byte ;Clear receive byte to prepare for new data. :receive call bit_delay ;Wait one bit time. movb c,Serial_in ;Put the data bit into carry. ;(use /Serial_in for 22k resistor input). rr rcv_byte ;Rotate carry bit into receive byte. djnz bit_cntr,:receive ;Not eight bits yet? Get next bit. call bit_delay ;Wait for stop bit. and rcv_byte,#11110000b ;mask off low nibble cje rcv_byte,#090h,begin2 ;is this a "note on" code? goto begin1:start_bit ;Receive next byte. ;********************** Receive the note value ****************************** begin2 :start_bit snb serial_in jmp :start_bit call start_delay2 jb Serial_in,:start_bit mov bit_cntr, #8 clr rcv_byte :receive call bit_delay movb c,Serial_in rr rcv_byte djnz bit_cntr,:receive call bit_delay ;check midi note values to determine if valid, and their function cje rcv_byte,#84,faster ;enabled via the highest note. cje rcv_byte,#36,pattern12 ;all lights on steady. cjb rcv_byte,#60,begin1 ;notes below middle C or above cja rcv_byte,#71,begin1 ;the next higher C are invalid. ;************* LITECTRL cje rcv_byte,#60,pattern0 cje rcv_byte,#61,pattern1 cje rcv_byte,#62,pattern2 cje rcv_byte,#63,pattern3 cje rcv_byte,#64,pattern4 cje rcv_byte,#65,pattern5 cje rcv_byte,#66,pattern6 cje rcv_byte,#67,pattern7 cje rcv_byte,#68,pattern8 cje rcv_byte,#69,pattern9 cje rcv_byte,#70,pattern10 cje rcv_byte,#71,pattern11 ;+++++++ pattern0 clrb 3.0 ;register 3, bit 0 is status register carry bit. ;(must clear before rotating register) mov rb,#00010001b ;Bits to be rotated :continue call delay ;delay before changing rl rb ;Shift the bit pattern to the left jmp :continue ;+++++++ pattern1 clrb 3.0 mov rb,#00010001b :continue call delay rr rb jmp :continue ;+++++++ pattern2 clrb 3.0 mov rb,#10010010b :continue call delay rl rb ;Shift the bit pattern to the right jmp :continue ;++++++++ pattern3 clrb 3.0 mov rb,#10010010b :continue call delay rr rb jmp :continue ;++++++++ pattern4 clrb 3.0 mov rb,#11001100b :continue call delay rl rb jmp :continue ;++++++++ pattern5 clrb 3.0 mov rb,#11001100b :continue call delay rr rb jmp :continue ;++++++++ pattern6 clrb 3.0 mov rb,#11100111b :continue call delay rl rb jmp :continue ;++++++++ pattern7 clrb 3.0 mov rb,#11100111b :continue call delay rr rb jmp :continue ;++++++++ pattern8 clrb 3.0 mov rb,#10010010b :continue call delay rl rb jmp :continue ;++++++++ pattern9 clrb 3.0 mov rb,#10010010b :continue call delay rr rb jmp :continue ;++++++++ pattern10 clrb 3.0 mov rb,#10110010b :continue call delay rl rb jmp :continue ;++++++++ pattern11 clrb 3.0 mov rb,#10110010b :continue call delay rr rb jmp :continue ;+++++++ pattern12 mov rb,#11111111b forever jmp forever ;******************************* utilities ********************************** ; This delay loop takes four instruction cycles per loop, plus eight ; instruction cycles for other operations (call, mov, the final djnz, and ret). ; These extra cycles become significant at higher baud rates. The values for ; bit_K in the table take the time required for additional instructions into ; account. bit_delay mov delay_cntr,#bit_K :loop nop djnz delay_cntr, :loop ret ; This delay loop is identical to bit_delay above, but provides half the delay ; time. start_delay1 mov delay_cntr,#7 :loop nop djnz delay_cntr, :loop ret start_delay2 mov delay_cntr,#10 :loop nop djnz delay_cntr, :loop ret faster mov speed,#007h ;increases the rate of sequencing. setb fast_led ;indicator for fast sequencing jmp begin1 delay mov count2,speed ;store the sequence rate variable wait1 mov count1,#0FFh wait2 mov count0,#0FFh :loop djnz count0,:Loop ;Decrement count0 until it reaches zero djnz count1,wait2 ;Decrement count1, & go back to "wait2" djnz count2,wait1 ;user presetable counter ret