我的MIDI键盘程序

发布者:沭阳小黄同志最新更新时间:2015-07-14 来源: 51hei关键字:MIDI  键盘程序 手机看文章 扫描二维码
随时随地手机看文章
#include //89s52头文件
#define io_74hc165_SH_LD   P1_0  //硬件设置
#define io_74hc165_CLK     P1_1
#define io_74hc165_SDA     P1_2
#define io_74hc164_SCK  P1_3
#define io_74hc164_SDA  P1_4
#ifndef RW_DEFINED
#define RW_DEFINED
void _snop_()
{
}
#endif
//Crystal at 12.0MHz 1MIPS
#define I2C_SDA P3_2                          // 将p3.2口模拟数据口,必须要这样。中断接受数据
#ifdef I2C_SCL
#else
#define I2C_SCL P1_6                          // 将p1.1口模拟时钟口,默认
#endif
#ifdef SlaveAddress
#else
#define SlaveAddress 0x02		  //地址
#endif
#ifdef MasterAddress
#else
#define MasterAddress 0x01		  //主机地址
#endif
#define delayNOP(); {_snop_();_snop_();_snop_();_snop_();};
unsigned char s_control;
unsigned char s_note;
unsigned char s_svel;
bit	nm;
bit   SystemError;                // 从机错误标志位
//--------------------------------------------------------------------------------------------------
// 函数名称: iic_start()
// 函数功能: 启动I2C总线子程序
//--------------------------------------------------------------------------------------------------
void iic_start(void)
{ 	EA=0;            //时钟保持高,数据线从高到低一次跳变,I2C通信开始
	I2C_SDA = 1;
	I2C_SCL = 1;
	delayNOP();      // 延时5us
	I2C_SDA = 0;
	delayNOP();
	I2C_SCL = 0;
}
//--------------------------------------------------------------------------------------------------
// 函数名称: iic_stop()
// 函数功能: 停止I2C总线数据传送子程序
//--------------------------------------------------------------------------------------------------
void iic_stop(void)
{
	I2C_SDA = 0;   	   //时钟保持高,数据线从低到高一次跳变,I2C通信停止
	I2C_SCL = 1;
	delayNOP();
	I2C_SDA = 1;
	delayNOP();
	I2C_SCL = 0;
	EA=1;
}
//--------------------------------------------------------------------------------------------------
// 函数名称: slave_ACK
// 函数功能: 从机发送应答位子程序
//--------------------------------------------------------------------------------------------------
void slave_ACK(void)
{
	I2C_SDA = 0;
	I2C_SCL = 1;
	delayNOP();
	I2C_SDA = 1;
	I2C_SCL = 0;
}
//--------------------------------------------------------------------------------------------------
// 函数名称: slave_NOACK
// 函数功能: 从机发送非应答位子程序,迫使数据传输过程结束
//--------------------------------------------------------------------------------------------------
void slave_NOACK(void)
{
	I2C_SDA = 1;
	I2C_SCL = 1;
	delayNOP();
	I2C_SDA = 0;
	I2C_SCL = 0;
}
//--------------------------------------------------------------------------------------------------
// 函数名称: check_ACK
// 函数功能: 主机应答位检查子程序,迫使数据传输过程结束
//--------------------------------------------------------------------------------------------------
void check_ACK(void)
{ 

	I2C_SDA = 1;      // 将p1.0设置成输入,必须先向端口写1
	I2C_SCL = 1;
	F0 = 0;
	if(I2C_SDA == 1)    // 若I2C_SDA=1表明非应答,置位非应答标志F0
		F0 = 1;
	I2C_SCL = 0;
}

//--------------------------------------------------------------------------------------------------
// 函数名称: IICSendByte
// 入口参数: ch
// 函数功能: 发送一个字节
//--------------------------------------------------------------------------------------------------
void IICSendByte(unsigned char ch)
{
	unsigned char idata n=8;     // 向I2C_SDA上发送一位数据字节,共八位
	while(n--)
	{
		if((ch&0x80) == 0x80)    // 若要发送的数据最高位为1则发送位1
		{
			I2C_SDA = 1;    // 传送位1
			I2C_SCL = 1;
			delayNOP();
			I2C_SDA = 0;
			I2C_SCL = 0;
		}
		else
		{
			I2C_SDA = 0;    // 否则传送位0
			I2C_SCL = 1;
			delayNOP();
			I2C_SCL = 0;
		}
		ch = ch<<1;    // 数据左移一位
	}
}
//--------------------------------------------------------------------------------------------------
// 函数名称: IICreceiveByte
// 返回接收的数据
// 函数功能: 接收一字节子程序
//--------------------------------------------------------------------------------------------------
unsigned char IICreceiveByte(void)
{
	unsigned char idata n=8;    // 从I2C_SDA线上读取一上数据字节,共八位
	unsigned char tdata=0;
	while(n--)
	{
		I2C_SDA = 1;
		I2C_SCL = 1;
		tdata = tdata<<1;    // 左移一位,或_crol_(temp,1)
		if(I2C_SDA == 1)
			tdata = tdata|0x01;    // 若接收到的位为1,则数据的最后一位置1
		else
			tdata = tdata&0xfe;    // 否则数据的最后一位置0
		I2C_SCL=0;
	}
	return(tdata);
}

bit IICwaitACK()
{ //10us不属于超时
unsigned char i=0;
bit j=0;
I2C_SDA=1;//输入状态
while (i!=10)
{
	if (I2C_SCL==1) //先SCL=1 SDA=0后SCL=0 SDA=1
	{
		j=1;
		break;
	}
	i++;
}

return j;

}[page]
//--------------------------------------------------------------------------------------------------
// 函数名称: slavesenddata
// 入口参数: control,note and vel
// 函数功能: 发送MIDI信息在IIC总线上
//--------------------------------------------------------------------------------------------------
//保证Simple.不使用标准I2C协议。 发送从机地址,等ACK,再发送发送3byte数据,等ACK.It 's very simple.
void slavesenddata(unsigned char control,unsigned char note,unsigned char svel)
{
EA=0;
IT0=0; //外中断0为 下降沿触发 设定成低电平出发的话 容易导致 误触发
EX0=0; //开外部中断0
iic_start();
SystemError=1;
IICSendByte(SlaveAddress);//发送地址
if (IICwaitACK()) //等主机的回应
{
IICSendByte(control);
IICSendByte(note);
IICSendByte(svel);
if (IICwaitACK()) //等主机的回应
{
SystemError=0;
}
}
iic_stop();
IT0=1; //地址不对就不去管了
EX0=1; //开中断继续
EA=1;
}
void initial_i2c()
{
IT0=1; //外中断0为 下降沿触发 设定成低电平出发的话 容易导致 误触发
EX0=1; //开外部中断0
EA=1;
}
void recvint0() interrupt 0 using 2
{
unsigned char mAddress=0;
EA=0;
IT0=0; //
EX0=0; //关中断防止干扰
//slave_ACK();
mAddress=IICreceiveByte();
if (mAddress==MasterAddress)
	{
		slave_ACK();
		s_control=IICreceiveByte();
		s_note=IICreceiveByte();
		s_svel=IICreceiveByte();
		nm=1; //提示主程序有新的消息,请注意查收~
	}
else
	{//延时,不能这样退出去引发中断
//ACK占用两个周期,接受数据占用10个周期。延够时了就跑
		delayNOP();
		delayNOP();
		delayNOP();
		delayNOP();
		delayNOP();
		delayNOP();
		delayNOP();
		delayNOP();
	}
IT0=1; //地址不对就不去管了
EX0=1; //开中断继续
EA=1;
} 

//下面是引脚的连接以及相关必要的宏定义
//Crystal at 12MHz
#ifdef io_74hc165_SH_LD
#else
#define io_74hc165_SH_LD   P1_0  //默认设置
#endif
#ifdef io_74hc165_CLK
#else
#define io_74hc165_CLK     P1_1
#endif
#ifdef io_74hc165_SDA
#else
#define io_74hc165_SDA     P1_2
#endif
#define io_74hc165_SH_HIGH io_74hc165_SH_LD=1;
#define io_74hc165_SH_LOW io_74hc165_SH_LD=1;
#ifdef io_74hc164_SCK
#else
#define io_74hc164_SCK  P1_3
#endif
#ifdef io_74hc164_SDA
#else
#define io_74hc164_SDA  P1_4
#endif
#define IO_74HC164_SCK_HIGH      io_74hc164_SCK = 1 ;
#define IO_74HC164_SCK_LOW       io_74hc164_SCK = 0 ;
#define IO_74HC164_SDA_INPUT     io_74hc164_SDA
//使用165来接受键盘数据。两片作为164输出。
#define uint8	unsigned char
#define uchar	unsigned char
#define uint unsigned int
uchar keytype=2;
//#define keytype 2
#define blacklist_time 240
uchar kbtime=0; //记录时间,占2个字节
uchar keynumber[2][7]; //记录键位,占14个字节
uchar blacklist[7];
//uchar code seg[]={"admin"};
/*0->NoTouch Response
1->Very Soft Touch Response
2->Soft Touch Response
3->Medium Touch Response
4->Hard Touch Response
5->Very Hard Touch Response
*/
 uchar code vel[5][251]=
{
{//Very Soft
127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,126,126,125,124,124,123,122,122,121,120,120,119,118,118,117,116,116,115,114,114,113,112,112,111,110,110,109,108,108,107,106,106,105,104,104,103,102,102,101,100,100,99,98,98,97,96,96,95,94,94,93,92,92,91,90,90,89,88,88,87,86,86,85,84,84,83,82,82,81,80,80,79,78,78,77,
76,76,75,74,74,73,72,72,71,70,70,69,
68,68,67,66,66,65,64,64,63,62,62,61,
60,60,59,58,58,57,56,56,55,54,54,53,
52,52,51,50,50,49,48,48,47,46,46,45,
44,44,43,42,42,41,40,40,39,38,38,37,
36,36,35,34,34,33,32,32,31,30,30,29,
28,28,27,26,26,25,24,24,23,22,22,21,
20,20,19,18,18,17,16,16,15,14,14,13,
12,12,11,10,10,9,8,8,7,6,6,5,
4,4,3,2,2,1,0
}
,
{//Soft
127,127,127,127,127,127,127,127,127,
127,127,127,127,127,127,127,127,127,
127,127,127,127,127,127,127,127,127,
127,127,127,127,127,127,127,127,126,
125,125,124,124,123,122,122,121,121,
120,120,119,118,118,117,117,116,115,
115,114,114,113,112,112,111,111,110,
110,109,108,108,107,107,106,105,105,
104,104,103,102,102,101,101,100,100,
99,98,98,97,97,96,95,95,94,94,93,92,
92,91,91,90,90,89,88,88,87,87,86,85,
85,84,84,83,82,82,81,81,80,80,79,78,
78,77,77,76,75,75,74,74,73,72,72,71,
71,70,70,69,68,68,67,67,66,65,65,64,
64,63,62,62,61,61,60,60,59,58,58,57,
57,56,55,55,54,
54,53,52,52,51,51,50,50,49,48,48,47,
47,46,45,45,44,44,43,42,42,41,41,40,
40,39,38,38,37,37,36,35,35,34,34,33,
32,32,31,31,30,30,29,28,28,27,27,26,
25,25,24,24,23,22,22,21,21,20,20,19,
18,18,17,17,16,15,15,14,14,13,12,12,
11,11,10,10,9,8,8,7,7,6,5,5,
4,4,3,2,2,1,1,0
}
,
{//Medium
127,127,127,127,127,127,127,127,127,
126,126,125,125,124,124,123,123,122,
122,121,121,120,120,119,118,118,117,
117,116,116,115,115,114,114,113,113,
112,112,111,111,110,110,109,108,108,
107,107,106,106,105,105,104,104,103,
103,102,102,101,101,100,100,99,98,98,
97,97,96,96,95,95,94,94,93,93,92,92,
91,91,90,90,89,88,88,87,87,86,86,85,
85,84,84,83,83,82,82,81,81,80,80,79,
78,78,77,77,76,76,75,75,74,74,73,73,
72,72,71,71,70,70,69,68,68,67,67,66,
66,65,65,64,64,63,63,62,62,61,61,60,
60,59,58,58,57,57,56,56,55,55,54,54,53,
53,52,52,51,51,50,50,49,48,48,47,47,
46,46,45,45,44,44,43,43,42,42,41,41,
40,40,39,38,38,37,37,36,36,35,35,34,
34,33,33,32,32,31,31,30,30,29,28,28,
27,27,26,26,25,25,24,24,23,23,22,22,
21,21,20,20,19,18,18,17,17,16,16,15,
15,14,14,13,13,12,12,11,11,10,10,9,
8,8,7,7,6,6,5,5,4,4,3,3,
2,2,1,1,0
}
,
{//Hard
100,99,99,98,98,98,97,97,96,96,96,95,
95,94,94,94,93,93,92,92,92,91,91,90,
90,90,89,89,88,88,88,87,87,86,86,86,
85,85,84,84,84,83,83,82,82,82,81,81,
80,80,80,79,79,78,78,78,77,77,76,76,
76,75,75,74,74,74,73,73,72,72,72,71,
71,70,70,70,69,69,68,68,68,67,67,66,
66,66,65,65,64,64,64,63,63,62,62,62,
61,61,60,60,60,59,59,58,58,58,57,57,
56,56,56,55,55,54,54,54,53,53,52,52,
52,51,51,50,50,50,49,49,48,48,48,47,
47,46,46,46,45,45,44,44,44,43,43,
42,42,42,41,41,40,40,40,39,39,38,38,
38,37,37,36,36,36,35,35,34,34,34,33,
33,32,32,32,31,31,30,30,30,29,29,28,
28,28,27,27,26,26,26,25,25,24,24,24,
23,23,22,22,22,21,21,20,20,20,19,19,
18,18,18,17,17,16,16,16,15,15,14,14,
14,13,13,12,12,12,11,11,10,10,10,9,
9,8,8,8,7,7,6,6,6,5,5,4,
4,4,3,3,2,2,2,1,1,0,0
}
,
{//Very Hard
92,92,91,91,91,90,90,90,89,89,88,88,
88,87,87,87,86,86,85,85,85,84,84,84,
83,83,82,82,82,81,81,81,80,80,80,79,
79,78,78,78,77,77,77,76,76,75,75,75,
74,74,74,73,73,72,72,72,71,71,71,70,
70,70,69,69,68,68,68,67,67,67,66,66,
65,65,65,64,64,64,63,63,62,62,62,61,
61,61,60,60,59,59,59,58,58,58,57,57,
57,56,56,55,55,55,54,54,54,53,53,52,
52,52,51,51,51,50,50,50,49,49,48,48,
48,47,47,47,46,46,45,45,45,44,44,44,
43,43,42,42,42,41,41,41,40,40,40,39,
39,38,38,38,37,37,37,36,36,35,
35,35,34,34,34,33,33,32,32,32,31,31,
31,30,30,29,29,29,28,28,28,27,27,27,
26,26,25,25,25,24,24,24,23,23,22,22,
22,21,21,21,20,20,20,19,19,18,18,18,
17,17,17,16,16,15,15,15,14,14,14,13,
13,12,12,12,11,11,11,10,10,10,9,9,
8,8,8,7,7,7,6,6,5,5,5,4,
4,4,3,3,2,2,2,1,1,1,0,0
}
};

 uchar count_begin[7][7]; //记录按键时间,占49个字节
//在钢琴上压键时间大于500mS可以几乎认为是没有力度了啊
//VIO

//VIO程序开始。
void v_74hc164WriteData_f( uint8 Dat )           //向74HC164写一个字节的内容
{                                                   //即可并行输出该字节
    uint8 i = 0 ;
       uint8 SendData = Dat ;
       for( i = 8 ; i > 0 ; i-- )
       {
                IO_74HC164_SCK_LOW
                 SendData <<= 1 ;
                IO_74HC164_SDA_INPUT = CY ;
                IO_74HC164_SCK_HIGH
       }
}

uchar v_74hc165ReadData_f()
{
   uchar i,c=0x00;
   for (i=0;i<8;i++)
   {
    c<=1;    //0000 0010
    if(io_74hc165_SDA)
    {c=c|0x01;}
    io_74hc165_CLK=0;  //下降沿有效
    io_74hc165_CLK=0;
    io_74hc165_CLK=1;
    //进位
   }
   return c;
}
//VIO结束
/*
74HC1651 BIT1~8 KB DATA 1~8
74HC1652 BIT1~8 KB DATA 9~16
74HC5952 BIT1~8 KB CS 1~8
*/

void initial_clock()
{ 
	TMOD=0x00;
	TH0=0x10;
	TL0=0xC1;
	PCON=0x80;
}

/*
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
系统普通信息、实时信息、及高级信息代码
忽略
忽略
*/[page]
void initial_keyboard() //初始化键盘
{
		v_74hc164WriteData_f(0x00);//关掉后排段选
		v_74hc164WriteData_f(0x00);//关掉前排段选
}
//keynumber[0]定义为第一排
//keynumber[1]定义为第二排
void scan_key()
{
uchar ts=0; //开始的时间
uchar kb_cs; // 段选
uchar i=0;
uchar j=0; //循环变量
uchar outa=0;
uchar outb=0;
uchar csp;
uchar lkb,hkb;
uchar atime;
uchar temp;//临时
kb_cs=0x01; //00000001 00000010
while (i!=8)
	{
		ts=kbtime;
		v_74hc164WriteData_f(0x00);//关掉前排段选
		v_74hc164WriteData_f(kb_cs);//输出后排段选
		//高在前,低在后
		//以下代码输出下排力度检测的信号
		io_74hc165_SH_HIGH //拉高并行置数
		outa=v_74hc165ReadData_f(); //读入输出
		io_74hc165_SH_LOW //拉低并行置数
		//结束,以下代码输出前排检测开关的信号
		initial_keyboard();//保险点
		v_74hc164WriteData_f(kb_cs); //输出前排段选
		v_74hc164WriteData_f(0x00); //关掉后排段选
		csp=0x01;//初始化指针
		io_74hc165_SH_HIGH //拉高并行置数
		outb=v_74hc165ReadData_f(); //读入输出
		io_74hc165_SH_LOW //拉低并行置数
		initial_keyboard();//全部关掉
		//与原来的键值进行比较~
		lkb=outb^keynumber[0][i]; //前排与原来的键值比较
		hkb=outa^keynumber[1][i]; //后排与原来的键值比较
		// 1&1=1 1&0=0 0&1=0 0&0=0
		// 1^1=0 1^0=0 0^1=0 0^0=0所以用来做比较。有变化的就输出1
		keynumber[0][i]=outb; //前排,记录下新的键值
		keynumber[1][i]=outa; //后排
		//原理:在琴键下面有两个开关,顺序为K1,K2。按照顺序接通。只能两个全导通/两个全关断,或者只有K1导通。在K1导通的时候lkb&csp发生变化并且在前排键上也发生变化
		//所以程序会在一个2维数组中记录闭合的时间,然后继续扫过去。等到第二次扫到这组键的话
			while(j!=8)
				{
					if ((lkb&csp)!=0) // 前排触点是否有变化
						{  if ((outb&csp)!=0)
							{
								//前排的按键按下了
								count_begin[i][j]=ts;
							}
							else
							{//前排键松开了就复原黑名单
								temp=0x01;
								temp=temp<blacklist_time)
								{
									//超时了
								temp=0x01;
								temp=temp<blacklist_time)
								{
									//超时了
								temp=0x1;
								temp=temp<

全部源码下载地址:http://www.51hei.com/f/mdid.rar
编译后约占用1K ROM。效率够高~
不过这个最后还要和主控ATmega8通信。
还是半成品。

 

 

 

做键盘也是要技术的。做电子琴更要技术。哇哈哈哈! 本程序的正式版本请看:http://www.51hei.com/mcu/1636.html

89S52单片机的Flash ROM为8KByte.内存为256Byte.

PS:程序本来是分块设计的。为了发上网就用cpp处理了下。include 全部被替换掉了。

关键字:MIDI  键盘程序 引用地址:我的MIDI键盘程序

上一篇:用电脑远距离控制的开关制作
下一篇:利用PLL(LM567)做频率解调的实例

推荐阅读最新更新时间:2024-03-16 14:25

C51 INT0中断方式键盘扫描程序
//中断方式键盘扫描程序,P1.0接二极管,P3.2 按键接INT0中断输入。按一次键P1.0翻转一次。 #include reg52.h void delay(unsigned int x); sbit led=P1^0; main() { IT0=1; EA=1; EX0=1; while(1) { } } void delay(unsigned int x) { unsigned int i; for(i=0;i x;i++) { } } void int0() interrupt 0 { EX0=0; //关中断, led=~led; delay(30000); IE0=0; //
[单片机]
MSP430单片机的4X4矩阵键盘C语言程序
#include msp430x24x.h #define uchar unsigned char #define uint unsigned int uchar table ={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; void delay(unsigned int i) //延时子程序 { while(i--); } uchar keyvalue() { uchar key; uchar np10,np11,np12,np13; P1DIR=0x0f; //第一排 P1OUT=~BIT3; delay(10); np10=P1IN&BIT4; if(np10==0
[单片机]
AVR扩展4*4矩阵键盘的CVAVR程序
// 8位LED动态显示按键值 // 芯片 ATMEGA16L // 时钟 4MHz 内部 // 采用系统自带延时程序 #include mega16.h #include delay.h void leddisplay(); // 数码管显示 unsigned char keyin(void); // 键盘扫描 unsigned char ledxs ={16,16,16,16,16,16,0,0}; // 数码管显示缓冲区 flash unsigned char tab ={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39
[单片机]
简单的键盘读写程序
仿真电路如下: 电路说明: 键盘由P1口引出,123是列线,4567是行线。P2和P3口的LED是检测按键的。 程序如下: #include reg51.h #include stdio.h #define uchar unsigned char uchar key; delay (void) { unsigned int i=1000; while(i--); } output (void) { switch(key) { case 0: P2=0xfe; break; case 1: P2=0xfd; break; case 2: P2=0xfb; break; case 3: P2=0xf7;
[单片机]
简单的<font color='red'>键盘</font>读写<font color='red'>程序</font>
PS2键盘51测试程序2
// PS2键盘测试程序2 // 功能:1602显示PS2键盘第1类按键的键值,显示单个按键字母小写及数字和标点,不考虑组合键。 // 指示灯: 接收按键值 P30(run) 取反。 键盘上电P31亮,接收按键值,P31灭。 #include reg52.h sbit PS2CLK=P3^3; // PS2时钟 sbit PS2DATA=P3^4; // PS2数据 sbit RUN=P3^0; // 运行标志指示灯 sbit P31=P3^1; // 运行标志指示灯 #define lcd_bus P0 // 数据总线 sbit rs =P2^0; //数据&指令选择,H:写数据,L:写指令 sbit rw
[单片机]
4X4键盘矩阵键盘程序
//按键跟按键的扫描结果满足如下关系: // 按键 扫描结果(result) 按键 扫描结果 // K10 0XE7 K18 0XB7 // K11 0XEB K19 0XBB // K12 0XED K20 0XBD // K13 0XEE K21 0XBE // K14 0XD7 K22 0X77 // K15 0XDB K23 0X7B // K16 0XDD K24 0
[单片机]
中断法键盘扫描c程序
/* 程序效果:按下按键,蜂鸣器响,数码管有相应的键值 显示,按下E键继电器关,按下C键继电器开。 这与上一程序的功能相同,比上一程序简洁 但理解相对困难些。 运行平台:51hei单片机学习板 */ #include reg52.h //头文件 #include intrins.h #define uchar unsigned char //宏定义 #define uint unsigned int sbit jdq=P3^5; //位声明,驱动继电器管脚 sbit fmq=P3^4; //位声明,驱动蜂鸣器管脚 code uchar table ={0x3f,0x06,0x5b,//数码管显示的数值 0x4f,0x66,0x6
[单片机]
基于CPLD的MIDI音乐播放器的设计
  大规模可编程逻辑器件CPLD和FPGA是当今应用最广泛的两类可编程逻辑器件,电子设计工程师利用它可以在办公室或实验室设计出所自己所需要的专用芯片和专用产品,从而大大缩短了产品上市时间,降低了开发成本。此外,可编程逻辑器件还具有静态可重复编程和动态在系统重构的特性,使得硬件的功能可以像软件一样通过编程来修改,这样就极大的提高了电子系统设计的灵活性和通用性。    1 工作原理   MIDI音乐是Windows下的一种合成音乐,由于它通过记谱的方式来记录一段音乐,因此与wave 音乐相比,它可以极大的减少存储容量。MIDI音乐的基本原理:组成乐曲的每一个音符的频率值(音调)及其持续的时间(音长)是乐曲能连续演奏的两个基本数据,因
[电源管理]
基于CPLD的<font color='red'>MIDI</font>音乐播放器的设计
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved