MIDI控制程序 Arduino平台 容易迁移到STM8/STM32

/*****************************************************************************************
硬件连接:
 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

    //播放音符,从 F#-0 (30) 到 F#-5 (90):
    for (note = 30 ; note < 40 ; note++) 
    {
      Serial.print("N:");
      Serial.println(note, DEC);
      
      //通道1开打开音符Note,力度为60
      noteOn(0, note, 60);
      delay(50);

      //通道1开关闭音符Note,力度为60
      noteOff(0, note, 60);
      delay(50);
    }

    delay(100); //乐器切换间隔
  }
  //=================================================================


  //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);
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值