单片机演奏音乐仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- /********本程序中,FOSC=11.0592M*********/
- #include<reg51.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- struct music_type{
- uchar tone;
- uchar delay;
- };
- /**********F调3个8度7音阶的音高参数**********/
- uint code tonetab[]={
- 64216,64360,64489,64603,64654,64752,64837, //低音1~7
- 64876,64948,65012,65042,65095,65144,65186, //中音1~7
- 65206,65242,65274,65289,65315,65340,65361 //高音1~7
- };
- //曲谱,每个音符含两项数据,第1项为音高,第2项为节拍(以1/4拍为单位)
- /**************康定情歌乐谱***************/
- struct music_type code songtab[]={
- 3+7,0x02,5+7,0x02,6+7,0x02,6+7,0x01,5+7,0x01,6+7,0x03,3+7,0x01,2+7,0x04,
- 3+7,0x02,5+7,0x02,6+7,0x02,6+7,0x01,5+7,0x01,6+7,0x03,3+7,0x06,
- 3+7,0x02,5+7,0x02,6+7,0x02,6+7,0x01,5+7,0x01,6+7,0x03,3+7,0x01,2+7,0x04,
- 5+7,0x02,3+7,0x02,2+7,0x01,3+7,0x01,2+7,0x01,1+7,0x01,2+7,0x02,6+0,0x06,
- 6+0,0x02,2+7,0x06,5+7,0x02,3+7,0x06,2+7,0x01,1+7,0x01,6+0,0x06,
- 5+7,0x02,3+7,0x02,2+7,0x01,3+7,0x01,2+7,0x01,1+7,0x01,2+7,0x02,6+0,0x06,
- //
- 3+7,0x01,2+7,0x01,3+7,0x01,5+7,0x01,6+7,0x01,5+7,0x01,1+14,0x01,6+7,0x01,
- 5+7,0x01,3+7,0x01,5+7,0x04,6+7,0x02,
- 1+14,0x02,2+14,0x01,3+14,0x01,2+14,0x01,1+14,0x01,6+7,0x01,1+14,0x01,
- 5+7,0x08,
- 5+7,0x01,3+7,0x01,5+7,0x04,6+7,0x02,
- 1+14,0x02,2+14,0x01,3+14,0x01,1+14,0x01,6+7,0x01,5+7,0x02,
- 5+7,0x02,2+7,0x02,3+7,0x01,5+7,0x01,3+7,0x01,2+7,0x01,
- 1+7,0x01,6,0x01,1+7,0x06,
- 3+7,0x01,2+7,0x01,1+7,0x02,2+7,0x03,3+7,0x01,
- 5+7,0x02,6+7,0x01,1+14,0x01,6+7,0x02,5+7,0x02,
- 5+7,0x01,3+7,0x01,2+7,0x02,3+7,0x01,5+7,0x01,3+7,0x01,2+7,0x01,
- 1+7,0x01,2+7,0x01,6,0x04,1+7,0x02,
- 2+7,0x03,3+7,0x01,1+7,0x01,2+7,0x01,1+7,0x02,6,0x01,
- 1+7,0x01,6,0x01,5,0x05,
- //
- 3+7,0x01,2+7,0x01,3+7,0x01,5+7,0x01,6+7,0x01,5+7,0x01,1+14,0x01,6+7,0x01,
- 5+7,0x01,3+7,0x01,5+7,0x04,6+7,0x02,
- 1+14,0x02,2+14,0x01,3+14,0x01,2+14,0x01,1+14,0x01,6+7,0x01,1+14,0x01,
- 5+7,0x08,
- 5+7,0x01,3+7,0x01,5+7,0x04,6+7,0x02,
- 1+14,0x02,2+14,0x01,3+14,0x01,1+14,0x01,6+7,0x01,5+7,0x02,
- 5+7,0x02,2+7,0x02,3+7,0x01,5+7,0x01,3+7,0x01,2+7,0x01,
- 1+7,0x01,6,0x01,1+7,0x06,
- 3+7,0x01,2+7,0x01,1+7,0x02,2+7,0x03,3+7,0x01,
- 5+7,0x02,6+7,0x01,1+14,0x01,6+7,0x02,5+7,0x02,
- 5+7,0x01,3+7,0x01,2+7,0x02,3+7,0x01,5+7,0x01,3+7,0x01,2+7,0x01,
- 1+7,0x01,2+7,0x01,6,0x04,1+7,0x02,
- 2+7,0x03,3+7,0x01,1+7,0x01,2+7,0x01,1+7,0x02,6,0x01,
- 1+7,0x01,6,0x01,5,0x05,
- 0,0x00
- };
- /*********端口及变量定义**********/
- sbit SPEAKER = P3^7;
- uchar tlow1,thig1;
- /*******软件延时,约n*10us******/
- void delay10us(unsigned char n){
- do{
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- }while(--n);
- }
- /*******软件延时,约n ms******/
- void delayms(unsigned int n){
- do {
- delay10us(131);
- }while(--n);
- }
- main () {
- uchar i,j;
- EA=1;ET0=1;
- TMOD=0X01;
- while(1){
- i=0;
- while(songtab[i].delay!=0){
- if(songtab[i].tone==0)TR0=0; //音高数据为0
- else{ //音高数据不为0
- //用定时器参数控制T1的振荡频率,即音高
- thig1=TH0=tonetab[songtab[i].tone-1]/256;
- tlow1=TL0=tonetab[songtab[i].tone-1]%256;
- TR0=1;
- }
- //控制音符的持续时间,即节拍
- for(j=0;j<songtab[i].delay;j++){
- delayms(200);
- }
- i++; //下一个音符
- }
- TR0=0; //停止演奏
- delayms(1000); //一遍完成后等待
- }
- }
- /*******定时器1中断,控制蜂鸣器发声频率*******/
- void t0 () interrupt 1{
- TH0=thig1;TL0=tlow1;
- SPEAKER = !SPEAKER; //蜂鸣器发声
- }
复制代码
所有资料51hei提供下载:
单片机演奏音乐.rar
(54.52 KB, 下载次数: 43)
|