Menu

MIDI Input Example

Anonymous
2014-02-26
2014-11-02
  • Anonymous

    Anonymous - 2014-02-26

    Hi Gang,

    Here's a MIDI input example in Great Cow Basic. It's purpose is simply to respond to MIDI Start, Stop and Continue commands. This is more a demo than anything, but could indeed be used as-is to control digital recorders, sequencers, lights and whatever else is out there that responds to those signals.

    More importantly, it illustrates the use of the analog comparators, the USART and interrupts. And you get to see how to implement a circular queue. The code is very short and sweet for all that, and the circuit can be built up in minutes, it's so simple.

    Here's the code. The schematic follows in the next post.

    Thomas Henry

    ;Project 66
    ;A program to detect MIDI Start, Stop and Continue.
    
    ;----- Configuration
    
    #chip 16F88, 20                 ;PIC16F88 running at 20 MHz
    #config mclr=off                ;reset handled internally
    #config osc=hs                  ;use resonator
    
    ;----- Constants
    
    #define USART_BAUD_RATE 31250
    #define USART_BLOCKING 1
    #define start_LED   b'00010000' ;LED bit patterns
    #define cont_LED    b'01000000'
    #define stop_LED    b'10000000'
    #define dud         h'F9'       ;a never-used dummy MIDI value
    #define midi_start  h'FA'       ;MIDI status byte: Start
    #define midi_cont   h'FB'       ;MIDI status byte: Continue
    #define midi_stop   h'FC'       ;MIDI status byte: Stop
    
    ;----- Variables
    
    dim midi, head, tail, temp, current as byte
    dim queue(80)
    
    ;----- Program
    
    dir PortA in                    ;all inputs
    ANSEL = 0b11111111              ;and all analog
    dir PortB 0b00000100            ;B.2 is input
    
    head = 0                        ;initialize queue
    tail = 0
    
    CMCON = 0b00010101              ;set up comparator
    on interrupt Comp1Change call fetch ;enable interrupts
    
    do
      if head <> tail then          ;anything in queue?
        midi = queue(head)          ;get the byte
        head ++                     ;bump to next position
        if head > 80 then           ;or wrap around to start
          head = 0
        end if
    
        select case midi
          case midi_start           ;MIDI Start received
            PortB = start_LED       ;so turn on proper LED
          case midi_cont
            PortB = cont_LED        ;MIDI Continue received
          case midi_stop
            PortB = stop_LED        ;MIDI Stop received
        end select                  ;all other bytes ignored
      end if
    loop                            ;repeat forever
    
    ;----- Subroutines
    
    sub fetch
      if C2OUT = on then            ;comparator went high
        HSerReceive queue(tail)     ;read a byte in
        tail ++                     ;prep for next time
        if tail > 80 then           ;wrap around if needed
          tail = 0
        end if
      end if
    end sub
    
     

    Last edit: Anonymous 2014-02-27
  • Anonymous

    Anonymous - 2014-02-26

    And here's the schematic...

     

    Last edit: Anonymous 2014-02-27
  • polyconnect

    polyconnect - 2014-11-02

    nice. Thanks.
    Can you explain the basic theory of the queue ?

     

    Last edit: polyconnect 2014-11-03

Log in to post a comment.