为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

midi键盘

2019-05-27 9页 doc 35KB 67阅读

用户头像

is_589748

暂无简介

举报
midi键盘用通用单片机制作MIDI键盘 作者:徐斌 MIDI是电子乐器的语言,随着MIDI的诞生,数字化电子乐器已经越来越多,MIDI的应用也越来越普遍,在电子乐队演奏,电子音乐制作等各个领域,发挥着越来越大的作用。随着计算机技术的发展,声卡已经成为普通计算机的标准设备,通过声卡的MIDI接口,可以连接各种各样的MIDI设备。连上专供输入的MIDI键盘,再配上相应的软件,计算机就可以完成电子琴的功能,甚至可以进行电子音乐的制作。由于 MIDI自身的特点,它形成的音乐易于进行后期制作,越来越为广大音乐工作者所喜爱,而MIDI键盘作为输入...
midi键盘
用通用单片机制作MIDI键盘 作者:徐斌 MIDI是电子乐器的语言,随着MIDI的诞生,数字化电子乐器已经越来越多,MIDI的应用也越来越普遍,在电子乐队演奏,电子音乐制作等各个领域,发挥着越来越大的作用。随着计算机技术的发展,声卡已经成为普通计算机的设备,通过声卡的MIDI接口,可以连接各种各样的MIDI设备。连上专供输入的MIDI键盘,再配上相应的软件,计算机就可以完成电子琴的功能,甚至可以进行电子音乐的制作。由于 MIDI自身的特点,它形成的音乐易于进行后期制作,越来越为广大音乐工作者所喜爱,而MIDI键盘作为输入最有效的工具,也越来越普及。 有些计算机音序软件支持用电脑键盘模拟琴键,可通过计算机键盘将音符输入计算机,有爱好者就用电脑键盘的控制芯片改装玩具电子琴,将其并接在计算机键盘上,称之为电脑琴,但这种控制芯片本身并不是为演奏音乐开发的,单音演奏还可以,在多个按键压下时会出错。本文将介绍如何用通用单片机实现MIDI键盘功能,并改装各种电子琴,与计算机连接,从而实现通过MIDI接口,把电脑变成真正的,可支持复音的电子琴。 一  MIDI信号及声卡的MIDI接口 MIDI 是一种异步串行通讯,其传输速率为31.25 K baud (每秒31250位),每个字节包括10 位,1个起始位,8个数据位,1个停止位,每个音符的开(或关)命令有3个字节,经计算,不到1mS即可传输一个音符的开关命令。MIDI的数据流是单向的,不进行应答,设备发送音乐信息时,不管接收设备的状态,而接收设备收到的信息,经校验正确的则执行,错误的就忽略——这样是由音乐本身的特点决定的,可以丢掉音符,但不能搞错节拍,实时性最优先。从物理层面上看,MIDI信号是电流传输的,5mA代表逻辑“0”,0mA代表逻辑“1”。MIDI设备连接时,必须将输出与另一设备的输入连接。 图1      典型的多个MIDI设备连接方式 计算机声卡的MIDI/GAME接口是15针的D型连接器,其中与MIDI相关的有: 1    +5V              +5 VDC 4    GND            地 12    MIDITXD        MIDI 输出    15    MIDIRXD        MIDI 输入    图 2    声卡上的 MIDI/GAME接口 二     单片机如何产生MIDI信号 本节介绍如何用目前在国内处于最主流地位的51系列单片机产生MIDI信号。实际上,这包含了两层意思 :1.如何产生符合 MIDI协议的串行数据。2.接口电路。 绝大多数51系列单片机都有串行通讯控制器(UART),配合合适的晶振,正确地设置UART的工作参数,就能够自动产生所需的串行数据。使用定时/计数器1(T/C1)作为波特率发生器。将串行口设置为方式1工作状态(10位异步收发,波特率由定时器控制),使用6MHz晶振,T/C1设为自动装入8位计数器状态(TMOD置为2xH),SMOD=1,TH=FFH,此时正好发生31.25K的串行通讯数据,适用于MIDI协议。 串口及定时/计数器初始化如下:(C语言例程,下同) void format(); { TMOD=0x21;    //T/C1工作于8位自动装入状态// TL1=0xff; TH1=0xff ;  // T/C1常数,确定波特率// SCON=0x50 ;      //设串口工作于方式1,// PCON=0x80 ;      //相当于SMOD=1;// TR1=1;            //T/C1开始计数// } MIDI协议中,每一次音符操作,命令包含3个字节,连续发送,依次为 “命令+通道号”,“音符”,“力度”。命令的第一个字节的最高位为1,通道为0-16,第二字节最高为位0,音符号为0-127,第三字节最高位为0,力度0-127。 发送一个音符命令:(参数 cc,kk,vv分别为“命令+通道号”,“音符号”,“力度”) void send(uchar cc,kk,vv) {  TR1=1;      //开计数器// SBUF=cc;    //写入寄存器// while(TI==0); //等待发送结束// TI=0;        //清发送标志// SBUF=kk; while(TI==0); TI=0; SBUF=vv; while(TI==0); TI=0; TR1=0; } MIDI命令简表 命令代码 (cc) 命令说明 数据kk含义及说明 数据vv含义及说明 8+ 通道号 关闭音符 对应的MIDI音符0-127 关闭音符的速度值 9+ 通道号 开启音符 对应的MIDI音符0-127 压下琴键的速度值(力度) A+ 通道号 触后压力 对应的MIDI音符0-127 对应音符的触后压力值 B+ 通道号 控制器 控制器号0-77 77-7F为通道模式信息 控制器值 C+ 通道号 音色切换 音色号 0-127 无该字节数据 D+ 通道号 通道压力 该通道全部键盘的触后压力 无该字节数据 E+ 通道号 弯音轮 弯音轮低位数据 弯音轮高位数据 F 系统普通信息、实时信息、及高级信息代码 忽略 忽略         前面已经介绍过,MIDI信号是单向的数据流,输出设备不管接收设备的状态,只是连续发出命令, 因此,MIDI键盘作为发送设备,只需输出,对于51单片机,其TXD即可作为MIDI信号的输出口,若不用转发别的MIDI设备信号,RXD实际上就没必要使用了。用51单片机的TXD脚,与声卡的MIDI-IN脚(15脚)相连,就可以很好的产生所需的MIDI信号,驱动声卡。这种连接方式并不是 MIDI协议中规定的标准的驱动方式,在MIDI协议中,采用了隔离传输的方式,两个设备不是共地的,本文介绍的电路,由于要从MIDI接口取电,必然形成共地的连接方式,这样,直接用单片机的高电平输出 5mA电流,低电平电流接近0,就能工作,但由于不是隔离传输,传输距离不能太长。 三  控制板电路 电路原理图如3所示。采用51系列单片机最小系统的标准电路,声卡 MIDI接口的1,4脚为供电输出,分别为 VCC、 GND ; 15脚为MIDI-IN,接单片机串行输出脚 TXD。单片机的P0,P2口用来扫描键盘,可提供8x8的键盘扫描能力。绝大多数的电子琴的键数小于64,这样的安排够用了。其他剩余的各脚,可用作工作参数预置,用来设置键值初值及所占MIDI通道号等。单片机采用89c51或其他兼容单片机,包括89s51,89f51,8751,97c51等。上拉电阻排选10kΩ, MIDI接口插头是15针的D型连接器,一般都标出了其引脚标号,按标号连接即可。给出的原理图及印制版图,都是完整的,可直接使用。 图3  单片机MIDI控制器电路图 图 4    控制部分印制板图  采用89c51或兼容单片机 四 用玩具琴键盘改装MIDI键盘 要分辨数十个按键的状态,最简单经济的方式就是采用矩阵式扫描键盘,其电路原理图如图5所示 图5    键盘的电路原理图 键盘以扫描方式工作,具体过程: 先由P0口发出段选通,每次选通一段,相应段选线被置为低电平,读P2口,被压下的键因与段选线接通,相应的端口输入为低电平,这样就完成了一段键盘(8个键)的状态读入过程,做8次循环,每次P0口的段扫移位一次,就完成了64个键的状态读入。由于乐器演奏时经常会有多个键同时压下的状态,若不加处理, 则可能出现几个段选通过按键短接在一起的情况,从而互相干扰导致逻辑不清,因此,在每个按键上串接二极管,用来阻隔无效的段选信号(高电平),使其不起作用, 这样就可完全分辨出每个键的状态, 而不会产生混乱。 乐器键盘的扫描与响应方式也有自己的特点,在扫描到键盘值后,与前一次的键盘状态比较,如不变,则不响应,有变化,则判断是被压下还是抬起,发出相应的MIDI命令,并纪录新的状态。 扫描8X8键盘的程序如下,程序中的key_number[i]是全局数组, 用来存贮按键状态,addition是全局变量,是设定该键盘第一个按键对应的MIDI音符的键值,全局数组和全局变量要在主程序中定义,程序中调用了前面给出的send(cc,kk,vv)函数: void scan_key() { uchar i,j,k,r,mmm,xu;  k=0xfe;            // k值为段选输出初值,第一位为0 for (i=0;i<8;i++) {  P2=0xff; P0=k;            //输出段选值 k=(k<<1)+1;        //段选标志左移,末位补1,为下一循环准备 mmm=0x01;        // 设按键查询指针初值 r=P2;            // 读入键值 P0=0xff;            //关闭段选输出 xu=r^key_number[i];        //查询键值是否改变,xu 为1的位为产生变化的按键 key_number[i]=r;        //新的键值存入数组 for (j=0;j<8;j++)          //作8次循环, 判断具体产生变化的键 { if((xu&mmm)!=0)        //用指针选择被测的键 {  if ((r&mmm)!=0)  //判断最终情况,以确定是被压下还是释放 {send(0x80+chnal,i*8+j+addition,40);}  //关闭声音,键值=i*8+j+addition else{send(0x90+chnal,i*8+j+addition,127);}  //开始发声
/
本文档为【midi键盘】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索