51電子琴,附帶仿真
仿真.jpg (121.03 KB, 下載次數: 64)
下載附件
2021-3-12 15:58 上傳
單片機源程序如下:
- //////////////////////////////////////////////////////////////////////////////////
- // 功能描述 : OLED 4接口
- // ----------------------------------------------------------------
- // GND 電源地
- // VCC 接5V或3.3v電源
- // SCL P1^0
- // SDA P1^1
- // ----------------------------------------------------------------
- // K9 P1^2;//音樂播放按鍵
- // KD P1^3;//低音播放
- // KG P1^4;//高音播放
- // beep P1^5; //蜂鳴器定義
- //******************************************************************************/
- #include "REG52.h"
- #include "oled.h"
- #include "bmp.h"
- #include <music.h>
- #define uchar unsigned char //無符號字符型 宏定義 變量范圍0~255
- #define uint unsigned int //無符號整型 宏定義 變量范圍0~65535
- sbit K9=P1^2;//音樂播放按鍵2
- sbit KD=P1^3;//低音播放
- sbit KG=P1^4;//高音播放
- sbit beep=P1^5; //蜂鳴器定義
- sbit K10=P1^6;//錄入指示
- sbit K11=P1^7;//休止符
- sbit K12=P3^2;//播放錄入的
- sbit K13=P3^3;//
- unsigned char n=0,m=0,k=0; //定義取頻率常數m和節拍常數n 數組元素編號k
- unsigned char music_load[]={ 8,2,9,2,10,2,11,2,12,2,12,2,12,1,11,1,10,2,11,2,11,2,11,1,10,1,9,1,0xff,8,2,10,2,12,4,0};
- void delay(uchar i)//用于OLED顯示
- {
- uchar j,u,v;
- for(j=i;j>0;j--)
- for(u=125;u>0;u--)
- for(v=125;v>0;v--);
- }
-
- void delayms(unsigned char j) //毫秒延時子程序 用于播放音樂
- {
- while(--j); //采用while(--j) 不要采用while(j--); 各位可編譯一下看看匯編結果就知道了!
- }
-
- void TimerInit()
- {
- TMOD|=0X11;//選擇為定時器0/1模式,工作方式1,僅用TR0/1打開啟動。
- TH1=0x0b; //節拍用
- TL1=0xdc;
- IE=0x8A;//1000,1010打開EA/ET1/ET0
- }
- /******************按鍵程序*************************/
- void oled_menu()//4功能
- {
-
- OLED_ShowNum(0,0,1,1,16);//1234
- OLED_ShowNum(0,2,2,1,16);
- OLED_ShowNum(0,4,3,1,16);
- OLED_ShowNum(0,6,4,1,16);
-
- OLED_ShowCHinese(10,0,7);//單音播放
- OLED_ShowCHinese(28,0,8);
- OLED_ShowCHinese(46,0,9);
- OLED_ShowCHinese(64,0,10);
-
- OLED_ShowCHinese(10,2,9);//播放音樂
- OLED_ShowCHinese(28,2,10);
- OLED_ShowCHinese(46,2,11);
- OLED_ShowCHinese(64,2,12);
-
- OLED_ShowCHinese(10,4,13);//錄入音樂
- OLED_ShowCHinese(28,4,14);
- OLED_ShowCHinese(46,4,11);
- OLED_ShowCHinese(64,4,12);
-
- OLED_ShowCHinese(10,6,9);//播放錄入音樂
- OLED_ShowCHinese(28,6,10);
- OLED_ShowCHinese(46,6,13);
- OLED_ShowCHinese(64,6,14);
- OLED_ShowCHinese(82,6,11);
- OLED_ShowCHinese(100,6,12);
-
- }
- void oled_start()//歡迎使用林天羽
- {
- OLED_ShowCHinese(26,0,0);//歡迎使用
- OLED_ShowCHinese(46,0,1);//
- OLED_ShowCHinese(66,0,2);//
- OLED_ShowCHinese(86,0,3);//
-
- OLED_ShowCHinese(36,4,4);//林天羽
- OLED_ShowCHinese(56,4,5);//
- OLED_ShowCHinese(76,4,6);//
-
- OLED_ShowString(12,6,"2016330301081",16);
-
- delay(150);
- OLED_Clear();
- oled_menu();
- }
- void load_music() //錄入功能--對應28個音,1個休止符自動1/4拍,末尾自動添加停止符號
- {
- uint i,j,temp;
- uchar ky=0,kj=0,kp=0; //定義數組元素編號ky,kj,kp,休止符次數kp
- music_load[0]=0;//保存第一個元素為0,按鍵時復寫,并要求下一個元素為0
- while(K10==0)
- {
- start2:
- temp = P2;
- j=3;//C調
- if(KD==0)j=4;//低音
- else if(KG==0)j=2;//高音
- if(KG==0&&KD==0)j=1;//更高音
- if(K11==0)//休止符1/4
- {
- delayms(5);
- if((ky+kj)%2==0)//如果此時需要輸入音調,則直接用休止符代替
- {
- OLED_ShowCHinese(80,0,16);//休止符
- OLED_ShowCHinese(96,0,17);
- OLED_ShowCHinese(112,0,18);
- music_load[ky+kj+kp]=0xff;//保存休止符為0xff
- music_load[ky+kj+kp+1]=0;
- kp++;
- while(K11==0);P0=0;OLED_ShowCHinese(80,0,15);OLED_ShowCHinese(96,0,15);OLED_ShowCHinese(112,0,15);
- }
- else if((ky+kj)%2==1)//如果此時需要輸入節拍,則節拍默認1/4,外加1/4休止
- {
- OLED_ShowCHinese(80,0,16);//休止符
- OLED_ShowCHinese(96,0,17);
- OLED_ShowCHinese(112,0,18);
- music_load[ky+kj+kp]=1;
- music_load[ky+kj+kp+1]=0xff;//保存休止符為0xff
- music_load[ky+kj+kp+2]=0;
- kj++;
- kp++;
- while(K11==0); P0=0;OLED_ShowCHinese(80,0,15);OLED_ShowCHinese(96,0,15);OLED_ShowCHinese(112,0,15);
- }
- goto start2;
- }
- for(i=0;i<8;i++)
- {
- if(temp==for_P2[i])
- {
- if((ky+kj)%2==0)//音調
- {
- OLED_ShowNum(100,0,1+i,1,16);
- m=7*j-i-1;n=0xff; //取頻率常數m=28-mk,mk=music[第一個元素] 和 節拍常數n=4*nk,nk=music[第二個元素]
- music_load[ky+kj+kp]=28-m;//保存
- music_load[ky+kj+kp+1]=4;//自動補齊節拍為一拍
- music_load[ky+kj+kp+2]=0;//確保結束符號
- TR1=1; //開定時器1
- TH0=T_H0[m];
- TL0=T_L0[m];
- while(P2==for_P2[i]) TR0=1; //等待節拍完成, 通過P1口輸出音頻(可多聲道哦!)
- TR0=0;
- TR1=0;
- OLED_ShowCHinese(100,0,15);
- ky++;
- }
- else if((ky+kj)%2==1)//節拍
- {
- /***********************/
- P0=smg_du[1+i];//使數碼管顯示該音調的字符
- music_load[ky+kj+kp]=i+1;//保存
- music_load[ky+kj+kp+1]=0;
- kj++;
- while(P2==for_P2[i]);
- }
- }
- }
- }
-
- }
- void play_music_load() //按下按鍵播放單音--一個音階7個音
- {
- unsigned char i=0,p=0;
- while(1)
- {
- start:
- p=music_load[i];
- if(p==0) //音樂停止標志
- {
- i=0;
- delayms(100);
- goto ending;
- }
- else if(p==0xff) //若碰到休止符,停止1/4拍,用第八個按鍵輸入休止符
- {
- i=i+1;
- n=1;//暫停1/4拍
- P0=smg_du[0];
- OLED_ShowNum(100,0,0,1,16);
- TR1=1;
- while(n!=0);
- TR0=0;
- OLED_ShowCHinese(100,0,15);
- goto start;
- }
- else //取頻率常數m和節拍常數n
- {
- m=28-music_load[i++];
- n=8*music_load[i++];
- P0=smg_du[(28-m)%7];
- OLED_ShowNum(100,0,(28-m)%7,1,16);
- }
- TR1=1; //開定時器1
- TH0=T_H0[m];
- TL0=T_L0[m];
- while(n!=0) TR0=1;
- TR0=0;
- TR1=0;
- OLED_ShowCHinese(100,0,15);
- } ending: ;
- }
- int main(void)
- {
- TimerInit();
- OLED_Init(); //初始化OLED
- OLED_Clear();
- oled_start();
- //播放音樂部分
-
- while(1)
- {
- // if(K13==0)key();//1
- // if(K9==0)play_music();
- if(K10==0)load_music();//1
- if(K12==0)play_music_load();
- //OLED_ShowNum(100,0,1+i,1,16);OLED_ShowCHinese(100,0,15);
- }
- }
-
- void int0() interrupt 1 //采用中斷0 控制音調
- {
- TH0=T_H0[m];
- TL0=T_L0[m];
- beep=~beep;
- }
- void int1() interrupt 3 //采用中斷3 控制節拍 優先級低
- {
- TH1=0x0b;
- TL1=0xdc;
- n--;
- }
復制代碼
所有資料51hei提供下載:
51單片機電子琴.rar
(97.26 KB, 下載次數: 27)
2021-3-12 15:41 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|