; File MIDISEND.ASM ; Assembly code for a --XX10MHzXX-- 4MHz PIC16F84 microcontroller ; ; ; Description: Send a midi message once every second ; Adapted from code by: Ross Bencina found at http://www.audiomulch.com/midipic/ ; by: Josh Harle ; Last Modified: 9/3/2006 ; ; CPU configuration processor 16f84 include ;========================================================================== ; ; Configuration Bits ; ;========================================================================== _CP_ON EQU H'000F' _CP_OFF EQU H'3FFF' _PWRTE_ON EQU H'3FF7' _PWRTE_OFF EQU H'3FFF' _WDT_ON EQU H'3FFF' _WDT_OFF EQU H'3FFB' _LP_OSC EQU H'3FFC' _XT_OSC EQU H'3FFD' _HS_OSC EQU H'3FFE' _RC_OSC EQU H'3FFF' __CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF & _RC_OSC ; variables temp equ H'1F' xmit equ H'1D' i equ H'1C' j equ H'1B' k equ H'1A' ; Program org 0 ; start at address 0 start: movlw B'00000000' tris PORTA ; init port A as output MOVLW b'00000000' ; All outputs. tris PORTB bsf PORTB, 0x07 ; turn on led bsf PORTA, 0x02 ; init midi out pin state mainloop: call secdelay movlw 0x90 ; note on, channel 1 movwf xmit call sendmidi movlw 0x3C ; middle C movwf xmit call sendmidi movlw 0x7F ; velocity 127 movwf xmit call sendmidi call secdelay movlw 0x80 ; note off, channel 1 movwf xmit call sendmidi movlw 0x3C ; middle C movwf xmit call sendmidi movlw 0x7F ; velocity 127 movwf xmit call sendmidi goto mainloop ; sendmidi transmits one midi byte on RA2 ; at 10mhz there are 80 instructions per midi bit ; JOSH: so at 4mhz there should be 32 instructions per midi bit ; ; xmit contains byte to send ; * this should be rewritten to support variable delays for ; * different clock speeds sendmidi: startb: bcf PORTA, 0x02 ; start bit ; movlw D'24' ; delay 73 clocks: 2 + (23 * 3 + 1 * 2) movlw D'8' ; delay 25 clocks: 2 + (23 * 3 + 1 * 2) movwf temp ; | loop1: decfsz temp,f ; | goto loop1 ; end delay movlw D'8' movwf j sendloop: ; executes 5 instuctions before setting bit rrf xmit,f btfsc STATUS, C goto send1 ; remember midi bits are opposite from our representation send0: nop bcf PORTA, 0x02 ;send a 0 bit goto endloop send1: bsf PORTA, 0x02 ;send a 1 bit nop nop endloop: ; ; movlw D'23' ;delay 70 instructions 2 + (22 * 3 + 1 * 2) movlw D'7' ;delay 22 instructions 2 + (6 * 3 + 1 * 2) movwf temp ; | loop2: decfsz temp,f ; | goto loop2 ; end delay decfsz j,f ; goto sendloop stopb: nop nop nop nop nop bsf PORTA, 0x02 ; stop bit ;movlw D'26' ; delay 79 clocks: 2 + (25 * 3 + 1 * 2) nop ; JOSH ed to add extra op nop ; JOSH ed to add extra op movlw D'26' ; delay 29 clocks: 2 + (9 * 3 + 1 * 4) movwf temp ; | loop3: decfsz temp,f ; | goto loop3 ; end delay return ; secdelay delays for one second @ 10Mhz ( 2500 000 instructions ) ; kloop = (2 + 254 * 3 + 1 * 2) = 766 ; jloop = 2 + kloop * 255 + (3 * 254 + 1 * 2) = 196096 ; iloop = 2 + jloop * 13 + (3*254 + 1*2) = 2550014 = 1.02 seconds ; JOSH ; secdelay delays for one second @ 4Mhz ( 1000000 instructions ) ; kloop = (2 + 254 * 3 + 1 * 2) = 766 ; jloop = 2 + kloop * 255 + (3 * 254 + 1 * 2) = 196096 ; iloop = 2 + jloop * 5 + (3*254 + 1*2) = 981246 ; x = secdelay: ;movlw D'13' movlw D'5' movwf i iloop: movlw D'255' movwf j jloop: movlw D'255' movwf k kloop: decfsz k,f goto kloop decfsz j,f goto jloop decfsz i,f goto iloop return end