MIDI控制程式 Aduino平臺 容易遷移到STM8/STM32
阿新 • • 發佈:2018-12-13
/* 硬體連線: 5V : Arduino上的5V連線音效板的VCC GND : Arduino上的GND連線音效板上的GND D3 Arduino上的軟串列埠的TX引腳(D3引腳)連線音效板上的MIDI引腳 D4 : Arduino上的D4引腳連線音效板上的RESET引腳 */ //軟串列埠庫 #include <SoftwareSerial.h> SoftwareSerial mySerial(2, 3);//引腳2是RX(沒用到), 引腳3是TX byte note = 0; //音符變數,表示將要播放的音符,初始值是0,範圍是0-127 byte resetMIDI = 4; //數字引腳4,連線到VS1053的復位引腳 byte ledPin = 13; //MIDI通訊指示燈 int instrument = 0; //樂器號變數,初始值為0 void setup() { //設定硬串列埠波特率為57600bps,用於連線PC以顯示程式執行狀態 Serial.begin(57600); //設定用於MIDI通訊的軟串列埠,波特率為31250bps mySerial.begin(31250); //對VS1053進行復位:低電平持續100ms,後拉高並保持 pinMode(resetMIDI, OUTPUT); //復位引腳設定為輸出 digitalWrite(resetMIDI, LOW); //引腳電平拉低 delay(100); digitalWrite(resetMIDI, HIGH); //引腳電平拉高 delay(100); talkMIDI(0xB0, 0x07, 120); //0xB0 是通道訊息, 設定1通道音量接近最大 (127) } void loop() { //基本的MIDI樂器, GM1,參見VS1053手冊33頁 //================================================================= Serial.println("Basic Instruments"); talkMIDI(0xB0, 0, 0x00); //預設bank GM1 //改變不同的樂器,GM1總共有128種樂器,0~127 for(instrument = 0 ; instrument < 127 ; instrument++) { Serial.print(" Instrument: "); Serial.println(instrument, DEC); talkMIDI(0xC0, instrument, 0); //設定MIDI通道1的樂器為instrument //Play notes from F#-0 (30) to F#-5 (90): for (note = 30 ; note < 40 ; note++) { Serial.print("N:"); Serial.println(note, DEC); //Note on channel 1 (0x90), some note value (note), middle velocity (0x45): noteOn(0, note, 60); delay(50); //Turn off the note with a given off/release velocity noteOff(0, note, 60); delay(50); } delay(100); //Delay between instruments } //================================================================= //Demo GM2 / Fancy sounds //================================================================= Serial.println("Demo Fancy Sounds"); talkMIDI(0xB0, 0, 0x78); //Bank select drums 選擇打擊樂器 //For this bank 0x78, the instrument does not matter, only the note for(instrument = 30 ; instrument < 31 ; instrument++) { Serial.print(" Instrument: "); Serial.println(instrument, DEC); talkMIDI(0xC0, instrument, 0); //Set instrument number. 0xC0 is a 1 data byte command //Play fancy sounds from 'High Q' to 'Open Surdo [EXC 6]' for (note = 27 ; note < 87 ; note++) { Serial.print("N:"); Serial.println(note, DEC); //Note on channel 1 (0x90), some note value (note), middle velocity (0x45): noteOn(0, note, 60); delay(100); //Turn off the note with a given off/release velocity noteOff(0, note, 60); delay(100); } delay(100); //Delay between instruments } //Demo Melodic //================================================================= Serial.println("Demo Melodic? Sounds"); talkMIDI(0xB0, 0, 0x79); //Bank select Melodic //These don't sound different from the main bank to me //Change to different instrument for(instrument = 27 ; instrument < 87 ; instrument++) { Serial.print(" Instrument: "); Serial.println(instrument, DEC); talkMIDI(0xC0, instrument, 0); //Set instrument number. 0xC0 is a 1 data byte command //Play notes from F#-0 (30) to F#-5 (90): for (note = 30 ; note < 40 ; note++) { Serial.print("N:"); Serial.println(note, DEC); //Note on channel 1 (0x90), some note value (note), middle velocity (0x45): noteOn(0, note, 60); delay(50); //Turn off the note with a given off/release velocity noteOff(0, note, 60); delay(50); } delay(100); //Delay between instruments } } //傳送一個MIDI音符開訊息 //通道範圍0-15 void noteOn(byte channel, byte note, byte attack_velocity) { talkMIDI( (0x90 | channel), note, attack_velocity); } //傳送一個MIDI音符關訊息 void noteOff(byte channel, byte note, byte release_velocity) { talkMIDI( (0x80 | channel), note, release_velocity); } //播放一個音符 //不要檢視去看一看數值大於127或者小於127是什麼樣的 void talkMIDI(byte cmd, byte data1, byte data2) { digitalWrite(ledPin, HIGH); mySerial.write(cmd); mySerial.write(data1); //Some commands only have one data byte. All cmds less than 0xBn have 2 data bytes //有一些命令只有一個位元組。所有小於0xBn的命令有兩個資料位元組 //(sort of: http://253.ccarh.org/handout/midiprotocol/) if( (cmd & 0xF0) <= 0xB0) mySerial.write(data2); digitalWrite(ledPin, LOW); }