『壹』 單片機蜂鳴器波放音樂怎樣區分樂譜有幾個半拍
/*【音符頻率對應表 】
音符 頻率/HZ 半周期/us(N)
--------------------------------
低1DO 262 1908 #1DO# 277 1805
低2RE 294 1700 #2RE# 311 1608
低3MI 330 1516 #3MI# 340 1470
低4FA 349 1433 #4FA# 370 1350
低5SO 392 1276 #5SO# 415 1205
低6LA 440 1136 #6LA# 466 1072
低7SI 494 1012 #7SI# 524 0954
中1DO 523 0956 #1DO# 554 0903
中2RE 578 0842 #2RE# 622 0804
中3MI 659 0759 #3MI# 682 0733
中4FA 698 0716 #4FA# 740 0676
中5SO 784 0638 #5SO# 831 0602
中6LA 880 0568 #6LA# 932 0536
中7SI 988 0506 #7SI# 1046 478
高1DO 1046 478 #1DO# 1109 451
高2RE 1175 426 #2RE# 1245 402
高3MI 1318 372 #3MI# 1356 368
高4FA 1397 358 #4FA# 1480 338
高5SO 1568 319 #5S0# 1661 292
高6LA 1760 284 #6LA# 1865 268
高7SI 1976 253 #7SI# 2066 242
---------------------------------
("#"表示半音,用於上升半個音) */
/*------------------------------------------------*/
#include<reg52.h> //包含頭文件,一般情況不需要改動,頭文件包含特殊功能寄存器的定義
#define uint unsigned int
#define uchar unsigned char
sbit SPK=P1^2; //定義喇叭埠
unsigned int i; //定義全局變數
uchar table[14]={ //中音音階對應定時器初值
0xfc,0x44, //1
0xfc,0xb6, //2
0xfd,0x09, //3
0xfd,0x34, //4
0xfd,0x82, //5
0xfd,0xc8, //6
0xfe,0x06 //7
};
/******************************************************************/
/* 延時函數聲明 */
/******************************************************************/
void delayms(unsigned int xms) //毫秒延時
{
uint i,j;
for(i=xms;i>0;i--)
for(j=125;j>0;j--);
}
void init() //定時器初始化函數
{
TMOD|=0x01; // 定時器工作方式,定時器0作定時用
TH0=table[0]; //定時器賦音階1對應初值,高位0xfc,低位0x44
TL0=table[1];
ET0=1; // 定時器0允許
EA=1; //開總中斷
}
/******************************************************************/
/* 主函數 */
/******************************************************************/
main()
{
init(); //定時器初始化
while(1)
{
for(i=0;i<7;i++) //循環播放7個音階
{
TR0=1; //打開定時器0,開始計時,產生喇叭驅動頻率
delayms(500); //每個音階大致持續播放時間
TR0=0; //停止計時
delayms(1000); //喇叭停止工作,約1s間歇的時間,可更改
}
}
}
void timer0() interrupt 1 //定時器中斷函數
{
TH0=table[i*2]; //音階1234567對應定時器初值高位數值,
//table[i*2]代表table[]數組裡面的第0 2 4 6 8 10 12 14個數值
TL0=table[i*2+1]; //table[i*2+1]代表table[]數組裡面的第1 3 5 7 9 11 13 15個數值
SPK=~SPK; //定時時間到,喇叭電平取反,實現頻率驅動
}
『貳』 單片機c語言音樂簡譜代碼
代碼的格式,是由編程者設計的,並沒有統一的規范。
下面的鏈接可供參考。
http://hi..com/%D7%F6%B6%F8%C2%DB%B5%C0/blog/item/88bfff323ec42ef21b4cff09.html
『叄』 高分請教單片機 樂譜的編制
單片機實現音樂的原料很簡單,把樂曲中的符號按次序排成一個表,然後按該表編輯要播放的音樂,再由查表程序依次取出,產生音符並控制節奏。
一般來說結束符為FF,體止符為00, 0x是16進制數字表示法前綴
其他字元的意思,你可以查看你彈片機程序是怎麼定義的就知道了。
『肆』 單片機音樂的簡譜怎麼寫的代碼數據
首先你要知道你定時器的工作方式,單片機的晶振,這樣你才能計算出具體的需要頻率,因為音樂代碼的話主要還是通過定時器改變蜂鳴器的頻率,使得發出音樂。
你這個18H,30H應該是通過那個定時器頻率計算方法計算出來的。
『伍』 為什麼單片機的樂譜要用十六進制
這個需要自己把樂譜轉換為十六進制數據:
相關知識:
1.要產生音頻脈沖,只要算出某一音頻的周期(1/頻率),然後將此周期除以2,即為半周期的時間。利用定時器計時這個半周期時間,每當計時到後就將輸出脈沖的I/O反相,然後重復計時此半周期時間再對I/O反相,就可在I/O腳上得到此頻率的脈沖。
2.利用8051的內部定時器使其工作在計數器模式MODE1下,改變計數值TH0及TL0以產生不同頻率的方法。
3.例如頻率為523Hz,其周期T=1/523=1912us,因此只要令計數器計時956us/1us=956,在每計數956次時將I/O反相,就可得到中音DO(523Hz)。
計數脈沖值與頻率的關系公式如下:
N=Fi÷2÷FrN:計數值;
Fi:內部計時一次為1us,故其頻率為12MHz;
Fr:要產生的頻率;
4.其計數值的求法如下:
T=65536-N=65536-Fi÷2÷Fr
例如:設K=65536,F=1000000=Fi=1MHz,求低音DO(261MHz)、中音DO(523MHz)、高音DO(1046MHz)的計數值。
T=65536-N=65536-Fi÷2÷Fr=65536-1000000÷2÷Fr=65536-500000/Fr
低音DO的T=65536-500000/262=63627
中音DO的T=65536-500000/523=64580
高音DO的T=65536-500000/1047=65059
5.C調各音符頻率與計數值T的對照表如下:
表1C調各音符頻率與計數值T的對照表
音符
低1DO頻率(Hz)簡譜碼(T值)音符頻率(Hz)簡譜碼(T值)
26263628#4FA#74064860
#1DO#27763731中5SO78464898
低2RE
#2RE#29463835#5SO#83164934
31163928中6LA88064968
低3M33064021#693264994
低4FA34964103中7SI98865030
#4FA#37064185高1DO104665058
低5SO39264260#1DO#110965085
#5SO#41564331高2RE117565110
低6LA44064400#2RE#124565134
#646664463高3M131865157
低7SI49464524高4FA139765178
中1DO52364580#4FA#148065198
#1DO#55464633高5SO156865217
中2RE58764684#5SO#166165235
#2RE#62264732高6LA176065252
中3M65964777#6186565268
中4FA69864820高196765283
表2節拍與節拍碼對照
節拍碼節拍數節拍碼節拍數
11/4拍11/8拍
22/4拍21/4拍
33/4拍33/8拍
41拍41/2拍
51又1/4拍55/8拍
61又1/2拍63/4拍
82拍81
A2又1/2拍A1又1/4拍
C3拍C1又1/2拍
F3又3/4拍
表3各調1/4節拍的時間設定各調1/4節拍的時間設定
曲調值DELAY曲調值DELAY
調4/4125毫秒調4/462毫秒
調3/4187毫秒調3/494毫秒
調2/4250毫秒調2/4125毫秒
1/4拍的延遲時間=187毫秒
DELAY:MOVR7,#02
D2:MOVR4,#187別的延遲值,只需修改這兒的值為相應值,即可。
D3:MOVR3,#248
DJNZR3,$
DJNZR4,D3
DJNZR7,D2
DJNZR5,DELAY節拍值放在R5,決定節拍
RET
建立音樂的步驟:
1.先把樂譜的音符找出,然後建立T值表的順序。
2.把T值表建立在TABLE1,構成發音符是計數值放在「TABLE」。
3.簡譜碼(音符)為高位,節拍為(節拍數)為低4位,音符節拍碼放在程序的「TABLE」處。
相關知識:
每一音符使用1個位元組,位元組的高4位代表音符的高低,低4位代表音符的節拍,表2為節拍與節拍碼的對照。如果1拍為0.4秒,1/4拍是0.1秒,只要設定延遲時間就可求得節拍的時間。假使1/4拍為1DELAY,則1拍應為4DELAY,以此類推。所以只要求得1/4拍的DEALY時間,其餘的節拍就是它的倍數,如表3為1/4和1/8節拍的時間設定。
簡譜發音簡譜碼T值
5低音SO164260
6低音LA264400
7低音TI364524
1中音DO464580
2中音RE564684
3中音MI364777
4中音FA764820
5中音SO864898
6中音LA964968
7中音TIA65030
1高音DOB65058
2高音REC65110
3高音MID65157
4高音FAE65178
5高音SOF65217
不發音0
節拍碼節拍數
11/4拍
22/4拍
33/4拍
41拍
51又1/4拍
61又1/2拍
82拍
A2又1/2拍
C3拍
F3又3/4拍
表4簡譜對應的簡譜碼、T值、節拍數
#include"reg51.h"
#defineuintunsignedint
#defineucharunsignedchar
uchar*TABLE;
codeuintTABLE1[15]={64260,64400,64524,64580,<br>64684,64777,64820,64898,<br>64968,65030,65058,65110,<br>65157,65178,65217};
codeucharSONG[]={
//1.遲來的愛
//0
0x08,0x08,
//1
0x02,0x12,0x42,0x62,0x52,0x42,0x21,11,
0x18,0x18,
0x02,0x22,0x42,0x82,0x92,0x82,0x61,0x51,0x42,
0x58,0x58,
//2
0x66,0x51,0x61,0x84,0x62,0x82,
0x52,0x62,0x42,0x52,0x28,
0x52,0x42,0x52,0x62,0x94,0x81,0x91,0x81,0x61,
0x1C,0x12,0x82,
//3
0x68,0x02,0x92,0x82,0x42,
0x5C,0x12,0x62,
0x58,0x02,0x42,0x51,0x41,0x22,
0x4C,0x62,0x52,
//4
0x66,0x82,0x92,0x82,0x61,0x51,0x41,0x51,
0x6C,0x52,0x62,
0x53,0x63,0x52,0x42,0x42,0x22,
0x1C,0x12,0x22,
//5
0x42,0x44,0x51,0x61,0x82,0x84,0x61,0x81,
0x96,0x82,0x66,0x51,0x61,
0x56,0x42,0x22,0x42,0x82,0x62,
0x5C,0x62,0x52,
//6
0x66,0x82,0x92,0x82,0x61,0x51,0x41,0x51,
0x6C,0x52,0x62,
0x56,0x62,0x52,0x42,0x42,0x22,
0x1C,0x12,0x22,
//7
0x42,0x44,0x51,0x61,0x82,0x84,0x61,0x81,
0x96,0x82,0x66,0x51,0x61,
0x56,0x62,0x92,0x82,0x62,0x52,
0x4C,0x62,0x61,0x81,
//8
0x9C,0x81,0x91,0x81,0x61,
0x6C,0x82,0x62,
0x56,0x42,0x24,0x42,0x52,
0x6C,0x62,0x61,0x81,
//9
0x9C,0xB2,0x92,
0x8C,0x82,0x92,
0xB2,0xB2,0xB2,0x92,0xD4,0xC1,0xD1,0xC1,0xB1,
0xCC,0xB2,0xB1,0xC1,
//A
0xDC,0xD2,0xC1,0xB1,
0x9C,0x92,0x91,0xC1,
0x92,0x84,0x92,0x82,0x62,0x51,0x61,0x51,0x41,
0x48,0x48,
//B
0x42,0x41,0x51,0x66,0x82,0x91,0xB1,
0x92,0x86,0x88,
0x42,0x41,0x51,0x66,0x42,0x41,0x51,
0x22,0x16,0x18,
0x86,0x62,0x58,
//C
0x83,0x91,0x62,0x82,0x58,
0x52,0x62,0x52,0x42,0x22,0x12,0x62,0x52,
0x4C,0x62,0x52,
//6
0x66,0x82,0x92,0x82,0x61,0x51,0x41,0x51,
0x6C,0x52,0x62,
0x56,0x62,0x52,0x42,0x42,0x22,
0x1C,0x12,0x22,
//7
0x42,0x44,0x51,0x61,0x82,0x84,0x61,0x81,
0x96,0x82,0x66,0x51,0x61,
0x56,0x62,0x92,0x82,0x62,0x52,
0x4C,0x62,0x61,0x81,
//8
0x9C,0x81,0x91,0x81,0x61,
0x6C,0x82,0x62,
0x56,0x42,0x24,0x42,0x52,
0x6C,0x62,0x61,0x81,
//9
0x9C,0xB2,0x92,
0x8C,0x82,0x92,
0xB2,0xB2,0xB2,0x92,0xD4,0xC1,0xD1,0xC1,0xB1,
0xCC,0xB2,0xB1,0xC1,
//A
0xDC,0xD2,0xC1,0xB1,
0x9C,0x92,0x91,0xC1,
0x92,0x84,0x92,0x82,0x62,0x51,0x61,0x51,0x41,
0x4C,0x62,0x61,0x81,
//8
0x9C,0x81,0x91,0x81,0x61,
0x6C,0x82,0x62,
0x56,0x42,0x24,0x42,0x52,
0x6C,0x62,0x61,0x81,
//9
0x9C,0xB2,0x92,
0x8C,0x82,0x92,
0xB2,0xB2,0xB2,0x92,0xD4,0xC1,0xD1,0xC1,0xB1,
0xCC,0xB2,0xB1,0xC1,
//A
0xDC,0xD2,0xC1,0xB1,
0x9C,0x92,0x91,0xC1,
0x92,0x84,0x92,0x82,0x62,0x51,0x61,0x51,0x41,
0x4C,0x62,0x61,0x81,
//D
0x66,0x51,0x61,0x86,0x61,0x81,
0x52,0x62,0x52,0x42,0x28,
0x82,0x91,0x01,0x62,0x11,0x52,0x11,0x01,0x62,0x54,
0x48,0x48,0x00};
ucharljsz;
ucharjpm;
ucharyfm;
uchart0=0;
uinti=0;
sbitSpeaker=P1^0;
uintk;
voidDelay1()
{
for(k=0;k<20000;k++);
}
voidLignt()
{uchart;<br>for(t=0;t<10;t++)<br>{<br>P2=0xff;<br>Delay1();<br>P2=0x00;<br>Delay1();<br>}
}
voidLignt1()
{
P2=0xaa;
Delay1();
P2=0x55;
Delay1();
}
voidDelay(uchart0)//延時
{
while(t0--)//決定節拍
Lignt1();
}
voidDelay2(ucharw0)//延時
{
while(w0--)//決定節拍
Lignt();
}
voidT0Int()interrupt1//TIMER0
{
TL0=ljsz;
TH0=hjsz;
Speaker=!Speaker;
}
voidExtInt0()interrupt0//INT0
{
if(t0>10)
t0=0;
i=0;
switch(t0++)
{
case0:TABLE=SONG;break;//選擇第1首
case1:TABLE=SONG1;break;//選擇第2首
case2:TABLE=SONG2;break;//選擇第3首
case3:TABLE=SONG3;break;//選擇第4首
case4:TABLE=SONG4;break;//選擇第5首
case5:TABLE=SONG5;break;//選擇第6首
case6:TABLE=SONG6;break;//選擇第7首
case7:TABLE=SONG7;break;//選擇第8首
case8:TABLE=SONG8;break;//選擇第9首
case9:TABLE=SONG9;break;//選擇第10首
}
}
voidsongsing()//發音程序
{
i=0;
while(TABLE[i])
{
jpm=TABLE[i]&0x0f;//節拍值
yfm=(TABLE[i]>>0x04)&0x0f;//簡譜值
if(yfm)//簡譜為1,取計數值
{
yfm=yfm-1;
hjsz=(uchar)(TABLE1[yfm]>>0x08);//取計數值高位元組
TH0=hjsz;
ljsz=(uchar)(TABLE1[yfm]);//取計數值低位元組
TL0=ljsz;
TR0=1;//啟動TIMER0
}
elseTR0=0;//簡譜為0,不發音
Delay(jpm);//節拍延時
i++;
}
}
voidmain(void)
{
TMOD=0X01;//設TIMER0在MODE1
TCON=0X01;//外部中斷INT0,下降沿觸發
IE=0x83;//開中斷(INT0,TIMER0)
IP=0x00;//設置中斷優先順序
TABLE=SONG0;
while(1)
{
Lignt();
songsing();//調用發音程序
TR0=0;//停止TIMER0
Delay2(1);
TABLE=SONG0;
songsing();
}
}
『陸』 這些單片機代碼根據曲譜怎麼寫出來的,求大神詳細教啊!
哈哈,LZ有求知慾很好嘛!其實原理是這樣的:
首先,音樂有哪幾個最基本的要素?
1,音高(頻率) 2,節拍(音符長度)3,強度。
其次,單片機演奏音樂的原理?
1,硬體方面:以I/o口輸出方波,驅動無源蜂鳴器震動,方波頻率與樂譜中音符的頻率對應(實現了音樂的第1要素)
2,軟體方面,有兩點
(1)如何產生某一頻率的方波?通過定時器產生周期性中斷,在中斷里將IO口的電平翻轉即可,中斷周期(即定時器應賦的初值)可以由需要的頻率計算得到。
(2)如何控制音符的長度(即音樂的第2要素)?從程序結構上來講,有幾種實現途徑,我能想到的:再使用一個定時器,它的中斷周期固定,以它作為長度的基準。比如,定為10ms中斷一次,中斷100次就是1秒,那麼演奏節拍為2/4拍一分鍾60拍的二分音符小字一組A(440Hz),就是200次中斷。定時器0控制I/O口輸出頻率440Hz的方波,並等定時器1中斷 200次之後,就切換到下一音符。這樣就實現了樂音輸出。
3.當然,這樣的音樂是控制不了強弱的,無法實現音樂的要素3。非常簡陋,只能將就。
程序最下面的數組就是單片機的「樂譜」,每一對元素,前面是音高(對應的宏給其對應的在音階里的位置進行了編號,後面是音符長度)。m_note數組存儲的就是演奏某一頻率的樂音對應的定時器中斷周期。