📄 111.cpp
字号:
#include <dos.h> //getvect(); setvect();
#include <conio.h> //kbhit();
#include <stdlib.h> //exit(0);
#include <stdio.h> //printf();
#ifdef __cplusplus
#define __CPPARGS
#else
#define __CPPARGS
#endif
#define S1 1 //从PA口选择播放的歌曲
#define S2 2
#define S3 4
#define S4 8
#define S5 16
#define S6 32
#define S7 64
#define S8 128
#define CTRL_8255 0x303 //8255控制口地址
#define PORTA 0x300 //8255芯片PA口地址
#define PORTB 0x301 //8255芯片PB口地址
#define CTRL_8253 0x307 //8253控制口地址
short int Music1[ ]={
//声明音阶的音乐频率
131,
147,
165,
175,
196,
220,
247,
262,
0
};
short int Music1_Delay[ ]={
//声明音阶的音乐延时
8,8,8,8,8,8,8,8
};
short int Music2[ ]= {
//声明歌曲“两个老虎”的音乐频率
262,294,330,262,
262,294,330,262,
330,349,392,
330,349,392,
392,440,392,349,330,262,
392,440,392,349,330,262,
294,196,262,
294,196,262,
0
};
short int Music2_Delay[] = {
//声明歌曲“两个老虎”的音乐延时
8,8,8,8,
8,8,8,8,
8,8,16,
8,8,16,
4,4,4,4,8,8,
4,4,4,4,8,8,
8,8,16,
8,8,16
};
short int Music3[ ]={
//声明歌曲“小蜜蜂”的音乐频率
392,330,330,
349,294,294,
262,294,330,349,
392,392,392,
392,330,330,
349,294,294,
262,330,392,392,
262,
0
};
short int Music3_Delay[ ]={
//声明歌曲“小蜜蜂”的音乐延时
4,4,8,
4,4,8,
4,4,4,4,
4,4,8,
4,4,8,
4,4,8,
4,4,4,4,
16
};
short int Music4[ ]={
//声明歌曲“小星星”的音乐频率
262,262,392,392,
440,440,392,
349,349,330,330,
294,294,262,
0
};
short int Music4_Delay[ ]={
//声明歌曲“小星星”的音乐延时
8,8,8,8,
8,8,16,
8,8,8,8,
8,8,16
};
short int Music5[ ]={
//声明歌曲“洋娃娃和小熊跳舞”的音乐频率
262,294,330,349,
392,392,392,349,330,
349,349,349,330,294,
262,330,392,
262,294,330,349,
392,392,392,349,330,
349,349,349,330,294,
262,330,262,
0
};
short int Music5_Delay[ ]={
//声明歌曲“洋娃娃和小熊跳舞”的音乐延时
4,4,4,4,
4,4,4,2,2,
4,4,4,2,2,
8,8,8,
4,4,4,4,
4,4,4,2,2,
4,4,4,2,2,
8,8,8
};
short int Music6[ ]={
//声明歌曲“友谊地久天长”的音乐频率
196,262,262,262,
330,294,262,294,
330,262,262,330,392,440,
440,392,330,330,
262,294,262,294,
330,262,220,220,196,262
};
short int Music6_Delay[ ]={
//声明歌曲“友谊地久天长”的音乐延时
8,16,4,8,
8,16,4,8,
8,16,4,8,8,16,
8,16,4,8,
8,16,4,8,
8,16,4,8,8,16
};
struct Music{
short int *Freq;
short int *TimeDelay;
}Music[5];
short int *ptrFreq; // 声明音频指针
short int *ptrTimeDelay; // 声明延时指针
void interrupt (*oldhandler)(__CPPARGS);
void interrupt chengyiping(__CPPARGS)
{
disable();
(*ptrTimedelay)--; // 延时点数减一
outportb(OCW2FROM,0x62); //发中断结束命令(OCW2),向从片8259发EOI命令即指定从片8259的ISR2复位
outportb(OCW2MAIN,0x20); //向主片8259发EOI命令,结束当前最高级中断服务
enable();
}
int Playing(void)
{
oldhandler = getvect(INTR); // 保存原中断向量
setvect(INTR, handler); // 装载新中断向量
outportb( CTRL_8255, 0x90 ); // 初始化8255
outportb( CTRL_8255, 0x0c ); // 置pc6=0 禁止8253通道2的gate引脚
outportb( CTRL_8255, 0x00 ); // 置pc0=0 禁止7408
outportb( CTRL_8253, 0xb6 ); // 初始化8253
int n = 0; //保存歌曲编号
short out = 0;
short int order = inportb( PORTA ); //接收从PA口得到的命令
short int norder = order;
switch (order)
{
case S1: n = 0;
break;
case S2: n = 1;
break;
case S3: n = 2;
break;
case S4: n = 3;
break;
case S5: n = 4;
break;
case S6: n = 5;
break;
}
ptrFreq = Music[n].Freq;
ptrTimeDelay = Music[n].TimeDelay;
int status;
//开始播放歌曲
while ( *ptrFreq && !kbhit())
{
void interrupt (*oldhandler)(__CPPARGS);
oldhandler=getvect(0x72); //获取原中断向量
setvect(0x72,handler); //设置新中断向量
enable();
status=inportb(0xa1);
outportb(0xa1,status&0xfb); //打开IRQ10(OCW1)
status=inportb(0x21);
outportb(0x21,status&0xfb); //打开IRQ2(OCW1)
outportb( 0x306, (unsigned char)(CLK / *ptrFreq % 256) );
// 先送低字节
outportb( 0x306, (unsigned char)(CLK / *ptrFreq / 256) );
// 再送高字节
// 以上置8253通道2 的计数初值
short int note= *ptrFreq; //从PB口显示当前音阶
switch (note)
{
case 262: out = 0xfe;
break;
case 294: out = 0xfd;
break;
case 330: out = 0xfb;
break;
case 349: out = 0xf7;
break;
case 392: out = 0xef;
break;
case 440: out = 0xdf;
break;
case 494: out = 0xbf;
break;
case 131: out = 0xfe;
break;
case 147: out = 0xfd;
break;
case 165: out = 0xfb;
break;
case 175: out = 0xf7;
break;
case 196: out = 0xef;
break;
case 220: out = 0xdf;
break;
case 247: out = 0xbf;
break;
}
outportb( PORTB, out); //置8255芯片PB口的当前值
outportb( CTRL_8255, 0x01 );
outportb( CTRL_8255, 0x0d ); // 开扬声器
while ( *pTimeDelay){}; //等待延时到
outportb( CTRL_8255, 0x0c );
outportb( CTRL_8255, 0x00 ); // 关闭扬声器
setvect(0x72,oldhandler);//恢复原中断向量
status=inportb(0xa1);
outportb(0xa1,status|0x04);//屏蔽IRQ10(OCW1)
status=inportb(0x21);
outportb(0x21,status|0x04);//屏蔽IRQ2
ptrFreq++; // 获取下一个音频
ptrTimeDelay++; // 获取下一个延时
} // 歌曲结束或按了任意键
outportb( PORTB,0xff ); //熄灭所有指示灯
outportb( CTRL_8255,0x0c );
outportb( CTRL_8255,0x00 ); // 再次关闭扬声器
setvect(INTR,oldhandler); // 恢复原中断向量
return 0;
}
void main(void)
{
printf("Now Playing Music!\n");
printf("Hit ESC key to exit:\n");//初始化歌曲相关信息数组
Music[0].Freq = Music1;
Music[0].TimeDelay = Music1_Delay;
Music[1].Freq = Music2;
Music[1].TimeDelay = Music2_Delay;
Music[2].Freq = Music3;
Music[2].TimeDelay = Music3_Delay;
Music[3].Freq = Music4;
Music[3].TimeDelay = Music4_Delay;
Music[4].Freq = Music5;
Music[4].TimeDelay = Music5_Delay;
Music[5].Freq = Music6;
Music[5].TimeDelay = Music6_Delay;
Playing();//调用播放歌曲子程序
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -