![]() |
發布時間: 2015-10-31 21:49
正文摘要:功能如下:1.通過按鍵能夠發出相應的音符并播放產生樂音,實現演奏;2.演奏的同時可數字顯示當前的音調,利于培養樂感3.可以選定播放固定樂曲自動演奏,演奏時LED進行節拍指示;4.在自動演奏和奏樂的過程中按停止鍵 ... |
原理圖有清晰點的嗎? |
謝謝大佬 |
仿真圖不清楚啊 |
受教了 |
有清楚點的原理圖嗎? |
求清晰電路圖![]() |
謝謝分享 |
這個能不能發出鋼琴的音。 |
謝謝大佬 |
真的好強大! |
絕世好帖!![]() ![]() ![]() |
謝謝大神。!![]() ![]() |
電壓大?? |
大神可以發一下生成的hex文件給我嗎?QQ郵箱1638078283@qq.com |
很不錯,支持一下,給力![]() |
好貼支持一下 |
好資料 感謝樓主分享 |
好貼,支持一下 |
圍觀大佬 |
希望發一個清晰的原理圖 |
學長,桂電的啊,你幾級的,我想用你的來做課設,苦澀笑 |
大神不在線,好惆悵 |
求清晰原理圖 |
有點6666 |
很實用。可以試看看。 |
謝謝大神 |
謝謝。最近正在做類似的東西,給了很多啟發,謝謝、 |
有沒有清晰得原理圖 |
求助清晰原理圖 |
上面電路圖我看的不是清楚,有清楚點的嗎 |
我下載來看看。 |
rosam_zhang 發表于 2016-7-24 00:42 你有上面那個電子琴的電路圖了不 能看清原件參數的 |
大神 能給個清晰的電路原理圖嗎,我想照做一個,可是看不清楚原件參數 |
題主能提供清晰的原理圖嗎,你這個圖看不清元件參數 |
大神,如果要換歌代碼怎么換算,很多歌曲代碼換過來就不能用了 |
Good ,我學習一下按鍵音調的編程思想,很好。 |
1246173372 發表于 2015-12-5 14:48 #include<reg52.h> #include<intrins.h> #define uchar unsigned char #define uint unsigned int #define allsong 4 //歌曲總數 按實際寫 sbit P1_0 = P1^0; sbit P1_1 = P1^1; sbit P1_2 = P1^2; sbit P1_3 = P1^3; sbit P1_4 = P1^4; sbit P1_5 = P1^5; sbit P1_6 = P1^6; sbit P1_7 = P1^7; sbit beep = P3^0; sbit key_play = P3^1; uchar x = 0; /*矩陣鍵盤橫坐標 從1開始 0為未按下的標志 */ uchar y = 0; /*矩陣鍵盤縱坐標 從1開始 0為未按下的標志 */ uchar flash = 0;//控制led燈顯示的變量 */ uchar f_l; /*按鍵發出音調的初值(低位)*/ uchar f_h; //高位 uchar song_l;/*歌曲音調的初值(低位)*/ uchar song_h;//高位 uchar out = 0;/*聲音輸出變量 1表示有輸出 0表示無輸出 */ uchar yindiao;/*音調 定義為全局變量 為了在播放時數碼管能顯示當前音調*/ uchar yindiao_h;//音調的高四位 uchar yindiao_l;//音調的低四位 uchar jiepai;/*節拍(簡而言之就是一個音調響的時間長度)*/ uchar song_id = 1;//歌曲序號變量 uchar temp_id = 1;//歌曲臨時序號 uint which = 2;/*簡譜表里的第幾個音 從第2個開始 第0個用來存曲速,第1個占位*/ uchar same = 0; /*在暫停時選了同一首歌曲,用于跳出暫停循環*/ uchar key_x(); //獲取鍵盤橫坐標 函數 uchar key_y();//獲取鍵盤縱坐標 函數 void play(); //播放歌曲 函數 void delayms(uint ms);//延時xx ms 函數 void delay(uint pai);//節拍延時 函數 void key_check(); //檢查按鍵狀態 函數 void display(); //數碼管顯示對應音調 函數 void speak();/*按鍵后 給定時器0賦對應音調的初值 從而發出聲音*/ uchar choose();/*播放狀態下 選歌函數 釋放按鍵后才跳出函數,返回歌曲序號*/ uchar choose2();/*暫停狀態下 選歌函數 不用釋放按鍵即可跳出函數,返回歌曲序號 */ void play();//播放歌曲 函數 uchar code num[]={0x00,//數碼管段選碼 0x77,0x7c,0x39,0x5e,0x79,0x71,0x3d, //a - g 0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, //1 - 7 0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87 //1. - 7. }; uchar code led_table[]={0xff,0x7f,0x3f,0x1f,0x0f,0x07,0x03,0x01,0x00};/*發光二極管閃爍表*/ uchar code chuzhi[]={ //音調對應的計數初值 0xff,0xff,//占0位 0xf8,0x8c,//低1 (0x01)a -數碼管顯示方式 0xf9,0x5b,// 2 b 0xfa,0x15,// 3 c 0xfa,0x67,// 4 d 0xfb,0x04,// 5 e 0xfb,0x90,// 6 f 0xfc,0x0c,//低7(0x07)g 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*占位 0x08 - 0x0b (8 - 11)*/ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,/*占位 0x0c - 0x10(12 - 16)*/ 0xfc,0x44,//中1 (0x11) (17) 0xfc,0xac,// 2 0xfd,0x09,// 3 0xfd,0x34,// 4 0xfd,0x82,// 5 0xfd,0xc8,// 6 0xfe,0x06,//中7 (0x17) (23) 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*占位 0x18 - 0x1b (24 - 27)*/ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /*占位 0x1c - 0x20 (28 - 32)*/ 0xfe,0x22,//高1 (0x21)1. (33) 0xfe,0x56,//2 2. 0xfe,0x85,//3 3. 0xfe,0x9a,//4 4. 0xfe,0xc1,//5 5. 0xfe,0xe4,//6 6. 0xff,0x03 //高7 (0x27)7. (39) }; uchar code ymt[]={//玉滿堂 0x96,0x00, //曲速 0x96表示 150拍/分 0x00,0x0a,0x05,0x02,0x15,0x02,0x12,0x02, 0x13,0x04,0x13,0x02,0x15,0x02,0x12,0x04,0x12,0x02,0x13,0x02, 0x12,0x10, 0x13,0x04,0x13,0x02,0x12,0x02,0x13,0x04,0x15,0x02,0x16,0x02, 0x15,0x0c,0x13,0x02,0x15,0x02, 0x16,0x04,0x16,0x02,0x21,0x02,0x16,0x04,0x15,0x02,0x13,0x02, 0x15,0x0c,0x15,0x02,0x16,0x02, 0x21,0x04,0x21,0x02,0x22,0x02,0x23,0x04,0x22,0x02,0x21,0x02, 0x22,0x10, 0x23,0x08,0x15,0x02,0x16,0x02,0x21,0x02,0x22,0x02, 0x23,0x04,0x23,0x02,0x22,0x02,0x21,0x06,0x21,0x02, 0x16,0x04,0x16,0x02,0x21,0x02,0x16,0x04,0x13,0x04, 0x15,0x10, 0x16,0x04,0x16,0x02,0x21,0x02,0x16,0x04,0x21,0x02,0x22,0x02, 0x23,0x04,0x23,0x02,0x22,0x02,0x21,0x06,0x21,0x02, 0x16,0x02,0x21,0x02,0x16,0x02,0x21,0x02,0x22,0x02,0x23,0x02,0x25,0x02,0x23,0x02, 0x22,0x0c,0x21,0x02,0x22,0x02, 0x23,0x06,0x15,0x02,0x16,0x02,0x21,0x02,0x22,0x02, 0x23,0x04,0x23,0x02,0x22,0x02,0x21,0x06,0x21,0x02, 0x16,0x04,0x16,0x02,0x21,0x02,0x16,0x02,0x21,0x02,0x15,0x02,0x13,0x02, 0x15,0x0c,0x13,0x02,0x15,0x02, 0x16,0x04,0x16,0x02,0x21,0x02,0x16,0x04,0x16,0x02,0x21,0x02, 0x22,0x04,0x22,0x02,0x23,0x02,0x22,0x04,0x22,0x02,0x23,0x02, 0x25,0x02,0x26,0x02,0x23,0x02,0x25,0x02,0x22,0x02,0x23,0x02,0x21,0x02,0x16,0x02, 0x21,0x10, 0xff }; uchar code dl[]={ //蝶戀 0x8c,0x00, //曲速 0x8c表示 140拍/分 0x13,0x04,0x13,0x04,0x13,0x04,0x12,0x04,0x13,0x08, 0x12,0x04,0x13,0x04,0x12,0x04,0x12,0x04,0x06,0x08, 0x06,0x04,0x07,0x04,0x11,0x08,0x12,0x04,0x11,0x04,0x07,0x08,0x06,0x04,0x05,0x04,0x06,0x10, 0x13,0x04,0x13,0x04,0x13,0x04,0x12,0x04,0x13,0x0c, 0x16,0x04,0x15,0x04,0x16,0x04,0x15,0x04,0x15,0x04,0x12,0x04, 0x12,0x04,0x13,0x04,0x14,0x08,0x15,0x04,0x14,0x04,0x13,0x04,0x12,0x04,0x11,0x04,0x13,0x0f,0x13,0x0c, 0x13,0x04,0x16,0x08,0x17,0x04,0x16,0x04,0x15,0x0c,0x13,0x04,0x15,0x0f, 0x13,0x04,0x15,0x04,0x12,0x08,0x16,0x04,0x15,0x04,0x13,0x08,0x12,0x04,0x12,0x04,0x13,0x0c, 0x12,0x08,0x16,0x04,0x16,0x0c, 0x11,0x08,0x16,0x04,0x16,0x08, 0x16,0x04,0x17,0x04,0x21,0x08,0x17,0x04,0x16,0x04,0x17,0x08,0x16,0x04,0x17,0x04,0x13,0x08,0x13,0x0c, 0x13,0x04,0x16,0x08,0x17,0x08,0x16,0x04,0x15,0x0c,0x13,0x04,0x15,0x10, 0x14,0x04,0x15,0x04,0x16,0x08,0x17,0x04,0x16,0x04,0x17,0x08, 0x16,0x04,0x17,0x04,0x13,0x10,0x13,0x10, 0x12,0x08,0x16,0x04,0x16,0x02,0x16,0x10, 0x11,0x04,0x16,0x04,0x16,0x02,0x16,0x08, 0x16,0x04,0x17,0x04,0x21,0x08,0x17,0x04,0x16,0x04,0x17,0x08,0x15,0x08,0x16,0x10, 0x23,0x04,0x22,0x04,0x22,0x04,0x21,0x04,0x21,0x04,0x17,0x04,0x17,0x04,0x16,0x04, 0x21,0x04,0x17,0x04,0x17,0x04,0x16,0x04,0x16,0x04,0x15,0x04,0x15,0x04,0x14,0x04, 0x16,0x04,0x15,0x04,0x15,0x04,0x14,0x04,0x14,0x04,0x13,0x04,0x13,0x04,0x12,0x04, 0x13,0x10,0x13,0x10, 0xff }; uchar code srkl[]={//生日快樂 0x78,0x00, //曲速 120 0x15,0x02,0x15,0x02, 0x16,0x04,0x15,0x04,0x21,0x04, 0x17,0x04,0x00,0x04,0x15,0x02,0x15,0x02, 0x16,0x04,0x15,0x04,0x22,0x04, 0x21,0x08,0x15,0x02,0x15,0x02, 0x25,0x04,0x23,0x04,0x21,0x04, 0x17,0x04,0x16,0x08, 0x16,0x04,0x00,0x04,0x24,0x02,0x24,0x02, 0x23,0x04,0x21,0x04,0x22,0x04, 0x21,0x08, 0x21,0x08,0x00,0x08, 0x15,0x02,0x15,0x02,//第二遍 0x16,0x04,0x15,0x04,0x21,0x04, 0x17,0x04,0x00,0x04,0x15,0x02,0x15,0x02, 0x16,0x04,0x15,0x04,0x22,0x04, 0x21,0x08,0x15,0x02,0x15,0x02, 0x25,0x04,0x23,0x04,0x21,0x04, 0x17,0x04,0x16,0x08, 0x16,0x04,0x00,0x04,0x24,0x02,0x24,0x02, 0x23,0x04,0x21,0x04,0x22,0x04, 0x21,0x08, 0x21,0x08,0x00,0x04, 0xff }; uchar code test[]={//測試 0x78,0x00, //曲速 0x78表示 120拍/分 0x01,0x04,0x02,0x04,0x03,0x04,0x04,0x04,0x05,0x04,0x06,0x04,0x07,0x04,0x00,0x04, 0x11,0x08,0x12,0x07,0x13,0x06,0x14,0x05,0x15,0x04,0x16,0x03,0x17,0x02,0x00,0x01, 0x21,0x01,0x22,0x02,0x23,0x03,0x24,0x04,0x25,0x05,0x26,0x06,0x27,0x07,0x00,0x08, 0xff, }; void delayms(uint ms) /*ms 等于1時,延時1ms 等于2時,延時2ms,以此類推*/ { uchar a,b,c; //+3 while(ms--) { for(c=1;c>0;c--)// 1+2 = 3 for(b=142;b>0;b--) //1*( 1+142*2)) = 285 for(a=2;a>0;a--);// 142*(1+2*2) = 710 } } void delay(uint pai)/*pai 是節拍 pai若定義成uchar類型,當節拍>0x0c時,會造成數據溢出,產生失真。*/ { uchar a,b,c; while(pai--)//延遲pai 個 6.25ms { for(c=1;c>0;c--) //1+2=3 for(b=28;b>0;b--)// 1*(1+28*2) =57 for(a=110;a>0;a--);//28*(1+110*2) = 6188 } } uchar key_x() /*P1口高位接縱坐標(P1.7 - P1.4) 低位接橫坐標(P1.3 - P1.0)*/ { uchar i; P1 = 0x0f; /*有按鍵按下后 對應按鍵的橫坐標電位被拉低( 注意低電位引腳不能被高電位引腳抬高,只能是低電位拉低高電位)*/ if(P1_0 == 0) {delayms(5); //延時5ms 去抖動 if(P1_0 == 0) i = 1; } else if(P1_1 == 0) {delayms(5); if(P1_1 == 0) i = 2; } else if(P1_2 == 0) {delayms(5); if(P1_2 == 0) i = 3; } else if(P1_3 == 0) {delayms(5); if(P1_3 == 0) i = 4; } else i = 0; return (i);//0表示按鍵未按下 } uchar key_y() { uchar j; P1 = 0xf0; if(P1_4 == 0) {delayms(5); if(P1_4 == 0) j = 1; } else if(P1_5 == 0) {delayms(5); if(P1_5 == 0) j = 2; } else if(P1_6 == 0) {delayms(5); if(P1_6 == 0) j = 3; } else if(P1_7 == 0) {delayms(5); if(P1_7 == 0) j = 4; } else j = 0; return (j); } void key_check() /*檢查矩陣按鍵坐標、播放鍵的狀態及播放鍵狀態設置*/ { x = key_x(); y = key_y(); if(key_play == 0) key_play = 0; /*保持播放鍵引腳低電平,讓其作為歌曲正在播放的標志*/ else key_play = 1; /*保持播放鍵引腳高電平,讓其作為歌曲未播放的標志*/ } void display() /*數碼管顯示相應的音調*/ { if(key_play == 1) //按鍵彈奏時 {if(x != 0 && y != 0 ) { if(x == 1) P0 = num[3 + y] ; //低音4 - 7 else if(x == 2) P0 = num[7 + y]; //中音1 - 4 else if(x == 3) P0 = num[11 + y]; //中音5 - 7 和 高音 1 else if(x == 4) P0 = num[15 + y]; //高音2 - 5 } else P0 = 0x00; } else //播放音樂時 {if(yindiao_h == 0) /* yindiao變量的高四位表示 低(0) 中(1) 高(2) 音*/ P0 = num[yindiao_l];/*yindiao變量的低四位表示“調”, 數碼管顯示當前音調*/ else if(yindiao_h == 1) //中音 P0 = num[yindiao_l + 7]; else if(yindiao_h == 2) //高音 P0 = num[yindiao_l + 14]; } } void speak()/* 按鍵 ,為定時器0 T0 賦計數初值,讓 T0函數驅動蜂鳴器發出對應的音調 */ { if(x == 1) { f_h = chuzhi[2*y + 6]; //低音4 - 7 f_l = chuzhi[2*y + 6 + 1]; } else if(x == 2) { f_h = chuzhi[(16+y)*2]; //中音 1 -4 f_l = chuzhi[(16+y)*2 +1]; } else if(x == 3) { if(y <= 3) { f_h = chuzhi[(20+y)*2]; //中音 5 - 7 f_l = chuzhi[(20+y)*2 + 1]; } else { f_h = chuzhi[66]; //高音1 f_l = chuzhi[67]; } } else if(x == 4) { f_h = chuzhi[(33+y)*2]; //高音2 -5 f_l = chuzhi[(33+y)*2 + 1]; } } void timer0() interrupt 1 //定時器0 { if(key_play == 0) { TL0 = song_l; TH0 = song_h; beep = ~beep; } else if(x != 0 && y != 0 && key_play == 1)/*當有矩陣按鍵按下,并且不播放歌曲時 */ { TL0 = f_l;//賦初值 TH0 = f_h;// beep = ~beep; /*蜂鳴器引腳電平取反,定時器每溢出一次電平取反一次,不同的計數初值對應不同的溢出時間,對應不同的方波頻率 */ } } void timer1() interrupt 3 //定時器1 led燈起落 { TL1 = 0x00; TH1 = 0x54;/*定時器1 高8位初值。控制led燈的起落快慢(數值不嚴格)*/ if(key_play == 1) //不播放歌曲時 { if(x != 0 && y != 0 && flash < 8 )//最大加到8 ++flash; else if(x == 0 && y == 0 && flash >0 ) //最小減到0 --flash; P2 = led_table[flash]; } else if(key_play == 0 ) //播放歌曲時 { if(out == 1 && flash < 8 && flash < jiepai)/*out ==1 表示有歌曲發聲時,(flash<jiepai)使 led燈剛好指示節拍*/ ++flash; else if(out == 0 && flash > 0) --flash; P2 = led_table[flash]; } } uchar choose()//播放狀態下 選歌 { uchar i = 0; //第i首歌 初值0表示未選歌 uchar j; x = key_x(); y = key_y(); if(x == 1 && y == 1) i = 1;//選第一首 else if(x == 1 && y == 2) i = 2; //選第二首 else if(x == 1 && y == 3) i = 3; else if(x == 1 && y == 4) i = 4; else if(x == 2 && y == 1) i = 5; else if(x == 4 && y == 1)// 上一首 i = 13; else if(x == 4 && y == 2)//用作暫停播放 i = 14; else if(x == 4 && y == 3)//下一首 i = 15; else if(x == 4 && y == 4) i = 16;//用作停止播放 if(i == song_id) { which = 2; //選同一首歌時,重播這首歌 } else if(i > allsong && i < 13)/*如果按鍵號 在 最大歌曲序號 和 功能鍵 之間,返回原歌曲序號*/ i = song_id;// else if(i == 0) //i等于初值 說明未按鍵 i = song_id; //不按鍵選歌時,返回原歌曲的序號 while(1)//釋放按鍵時才進行下一步 { x = key_x(); y = key_y(); if(x == 1) j = y; else if(x == 2) j = 4 + y; else if(x == 3) j = 8 + y; else if(x == 4) j = 12 + y; if(x == 0 || (j > allsong && j < 13)) /*釋放按鍵 或者按鍵號 在 最大歌曲序號 和 功能鍵 之間時 跳出循環*/ break; } return(i); } uchar choose2()/*選歌不用放開按鍵 在暫停的狀態下使用 */ { uchar i = 0; x = key_x(); y = key_y(); if(x == 1 && y == 1)//選第一首 i = 1; else if(x == 1 && y == 2)//選第二首 i = 2; else if(x == 1 && y == 3) i = 3; else if(x == 1 && y == 4) i = 4; else if(x == 2 && y == 1) i = 5; else if(x == 4 && y == 1)// 上一首 i = 13; else if(x == 4 && y == 2)//用作暫停播放 i = 14; else if(x == 4 && y == 3)//下一首 i = 15; else if(x == 4 && y == 4) i = 16;//用作停止播放 if(i == song_id) { same = 1; which = 2; /*選了同一首歌時,重播這首歌(0,1用來存曲速了 故從2開始) */ } else if(i > allsong && i < 13)/*如果按鍵號 在 最大歌曲序號 和 功能鍵 之間,返回原歌曲序號*/ i = song_id; else if(i == 0) //i等于初值 說明未按鍵 i = song_id; /*不按鍵選歌時,返回原歌曲的序號*/ return(i); } void play()//播放歌曲 { uint qusu;//歌曲播放速度 (拍/分) uint pai2; /*pai2 = (2400/qusu)*jiepai; 送到delay()函數*/ while(1) { while(1) { choose_id: temp_id = choose(); //選歌 /****************************↓↓↓↓↓暫!*****************************************/ if(temp_id == 14) //如果按下暫停鍵 { delayms(500);//延時500ms while(1) { temp_id = choose2();/*choose2 按下就起作用 不必等到放開按鍵才起作用*/ if(temp_id == 14) /*再次按下“暫停鍵” 表示繼續播放*/ { break; } else if(temp_id == 16)/*按下停止鍵 ,功能表現為:暫停播放時也能停止播放,回到播放前狀態*/ { song_id = 16; break; } else if(temp_id == 13)//上一首 { which = 2; if(song_id == 1) song_id = allsong ;//播放最后一首 else --song_id; break; } else if(temp_id == 15) //下一首 { which = 2; if(song_id == allsong) song_id = 1; //播放第一首 else ++song_id; break; } else if(temp_id != song_id && temp_id <= allsong)/*選了另一首歌曲 屏蔽掉了未定義的按鍵*/ { which = 2; /*從歌曲的第一個音播放 (0,1用來存曲速了 故從2開始)*/ song_id = temp_id; break; } else if(same == 1) break; } same = 0; //跳出循環后 需重置為0 } /****************************↑↑↑↑↑暫!***************************************/ else if(temp_id == 13)//上一首 { which = 2; if(song_id == 1) song_id = allsong ;//播放最后一首 else --song_id; } else if(temp_id == 15) //下一首 { which = 2; if(song_id == allsong) song_id = 1; //播放第一首 else ++song_id; } else if(temp_id == 16) { song_id = 16; } else if(temp_id != song_id && temp_id <= allsong) //選了另一首歌曲 { which = 2; //從歌曲的第一個音播放 song_id = temp_id; } /**************************************************************************************/ nochoose://不用選歌 當正常放完一首歌時,跳到這里 if(song_id == 3) {key_play = 0; if(srkl[which] == 0xff) /* 遇到結束符 跳出循環(內循環) 停止播放 */ break; qusu = srkl[0]; yindiao = srkl[which]; //音調 jiepai = srkl[which+1]; //節拍 } else if(song_id == 1) {key_play = 0; if(ymt[which] == 0xff) /* 遇到結束符 跳出循環(內循環) 停止播放 */ break; qusu = ymt[0]; yindiao = ymt[which]; //音調 jiepai = ymt[which+1]; //節拍 } else if(song_id == 2) { key_play = 0; if(dl[which] == 0xff) /* 遇到結束符 跳出循環 停止播放 */ break; qusu = dl[0]; yindiao = dl[which]; // jiepai = dl[which+1]; // } else if(song_id == 4) { key_play = 0; if(test[which] == 0xff) /* 遇到結束符 跳出循環 停止播放*/ break; qusu = test[0]; yindiao = test[which]; jiepai = test[which+1]; } /******************************************************************************/ else if(song_id == 16 ) { which = 2; break; } else { key_play = 1; goto choose_id; /*如果既沒有選歌 又沒有停止 返回去做選擇*/ } /********************************************************************************************/ yindiao_l = yindiao % 16;// 低四位 調 yindiao_h = yindiao /16;/*高四位 。。是低音0 中音1 還是 高音2*/ if(yindiao != 0) /*音調不為0。(當音調為0時表示這個音不響 但依舊要占這個音的播放時間)*/ { song_h = chuzhi[yindiao*2]; song_l = chuzhi[yindiao*2+1]; TR0 = 1; /*給初值賦值后,開啟定時器0 蜂鳴器開始發聲 */ TR1 = 1;/*開啟定時器1 ,led開始閃動*/ display(); //數碼管顯示音調 out = 1; /*正在發聲的標志,定時器1得以控制led燈按一定的時間間隔 逐個點亮 */ } else { TR0 = 0; out = 0; TR1 = 0; P0 = 0x00; flash = 0; P2 = led_table[0]; } pai2 = (2400/qusu)*jiepai; delay(pai2); /*延時 = 節拍數 x 125ms (決定著1個音的發聲時間) */ TR0 = 0;//蜂鳴器停止發聲 P0 = 0x00; out = 0; delayms(39); /*唱完一個音停xx ms(決定每個音調之間的時間間隔 根據個人喜好節奏來定 */ TR1 = 0; //led停止閃動 flash = 0; P2 = led_table[0]; which = which + 2;//下一個音 } /*已經放完一首歌,或者停止播放,接下來判斷是停止播放還是播放下一首 */ TR0 = 0; P0 = 0x00; out = 0; flash = 0; P2 = led_table[0]; if(song_id == 16) /*坐標(4,4)的鍵盤作為停止播放鍵*/ { while(1) { x = key_x(); if(x == 0) break;/*松開按鍵 才結束 避免觸發其他程序 比如電子琴發聲、led顯示等*/ } key_play = 1; /*播放鍵引腳置高電平,播放結束的標志*/ song_id = 1; // 第一首歌開始 which = 2; // 每首歌的最開始的一個音 break; /*跳出第二個循環(即結束play函數)*/ } else if(song_id == allsong)/*當放到最后一首時,從第一首開始 (當前共3首) */ { song_id = 1; which = 2; delayms(1000); //一秒后從第一首開始播放 goto nochoose; } else { ++song_id; /*歌曲序號自動+1 自動播放下一首歌*/ which = 2; delayms(1000); goto nochoose;//不用選歌 播放下一首 } } } void main() { P0 = 0x00; P2 = 0xff; TMOD = 0x11; /*定時器0 定時器1 都采用方式1(16位定時器方式) */ IE = 0x8a; PT0 = 1; /*設置定時器0為高優先級,避免被定時器1干擾,造成聲音失真*/ while(1) { key_check(); if(key_play == 1 && x != 0 && y != 0) { TR1 = 1; display(); speak(); TR0 = 1; } else if(key_play == 0) { key_play = 0; play(); /*play函數有循環語句,當按下停止鍵(16鍵)時才能跳出 */ } else { if(flash == 0)/*當flash 減到0時 再關閉定時器1,即 讓led燈全部熄滅再關閉T1 */ TR1 = 0; TR0 = 0; P0 = 0x00; } } } |
大神,可以把這個電子琴的代碼給我一下嗎,我下了沒辦法看 |