// MIDI Controller // Andrew Rogers // Scott Stroupe /******************************************** * MIDI Specifications * * Status Byte: 0x80 - 0xFF * - Voice Byte: 0x80 - 0xEF * Message Byte: 0x00 - 0x7F * * MIDI serial data rate: 31.25 kHz +/- 1% * - 1 start bit * - 1 stop bit * - 8 data bits * ********************************************/ #include#include // Upper 4-bit segment of status byte // "COMMAND" // (there are other, but we only use these) #define NOTE_ON 0x90 #define NOTE_OFF 0x80 // Lower 4-bit segment of status byte // "CHANNEL" // (0-F correspond to 1-16) #define CHANNEL_1 0x00 #define CHANNEL_2 0x01 // Other MIDI definitions #define MIDI_MAX 0x7F // 127 #define MIDI_MIN 0x00 // 0 #define MIDDLE_C 0x3C // Boolean definitions #define TRUE 1 #define FALSE 0 #define MSG_SIZE 3 // Global variables unsigned char sendingMIDI; unsigned char packet[MSG_SIZE]; unsigned char nextByte; void serialDataHandler ( void ) interrupt 4 using 2 { // handle outgoing MIDI data -- never any incoming data if (TI) { sendingMIDI = TRUE; TI = FALSE; if (nextByte >= MSG_SIZE) { sendingMIDI = FALSE; return; } SBUF = packet[nextByte]; nextByte++; } // else ignore the interrupt -- shouldn't be receiving } void startNote(unsigned char note, unsigned char channel, unsigned char velocity) { while (sendingMIDI) { /* loop */ } packet[0] = NOTE_ON | channel; packet[1] = note; packet[2] = velocity; nextByte = 0; TI = TRUE; } void stopNote(unsigned char note, unsigned char channel, unsigned char release) { while (sendingMIDI) { /* loop */ } packet[0] = NOTE_OFF | channel; packet[1] = note; packet[2] = release; nextByte = 0; TI = TRUE; } void initializeMIDI() { // set up RS-232 controller to handle MIDI output SCON |= 0x50; // 0101 0000 b PCON |= 0x80; // 1000 0000 b TMOD = 0x20; // 0010 0000 b TH1 = 252; // baud rate = 31.25 kHz; w/ext clk @ 24 MHz TR1 = 1; // run the timer IE = 0x90; // Enable serial interrupt (4) EA = TRUE; sendingMIDI = FALSE; } void main() { // play notes 0-127 in succession, then back down long i, note; initializeMIDI(); while (1) { for(note = 0; note <= MIDI_MAX; note++){ startNote(note, CHANNEL_1, MIDI_MAX); for (i = 0; i < 20000; i++); stopNote(note, CHANNEL_1, MIDI_MAX); for (i = 0; i < 20000; i++); } for(note = MIDI_MAX - 1; note >=0; note--){ startNote(note, CHANNEL_1, MIDI_MAX); for (i = 0; i < 20000; i++); stopNote(note, CHANNEL_1, MIDI_MAX); for (i = 0; i < 20000; i++); } } }