Ⅰ 單片機 音樂程序編寫 歌曲《小星星》
只有音樂發聲匯編程序,沒有加入LED燈,供參考。數據代碼已改為小星星發聲
;**********************************************
ORG
0000H
SJMP
MAIN
ORG
0BH
AJMP
TIME0
;*************主程序************************
MAIN:
MOV
SP,#60
MOV
TMOD,#01H
;T0定時工作方式
MOV
IE,#82H
;CPU
中斷允許,T0中斷允許
START0:
MOV
30H,#00H
;TABLE
相對地址指針
NEXT:
MOV
A,30H
MOV
DPTR,#TABLE
;到TABLE處取
簡譜碼
節拍
碼
MOVC
A,@A+DPTR
MOV
R2,A
;取到的簡譜碼
節拍碼
暫存於R2中
JZ
ENDF
;取到
00
結束
ANL
A,#0FH
;否,取低四位
節拍
碼
MOV
R5,A
;將節拍碼存於R5中
MOV
A,R2
;簡譜碼
節拍
碼
給A
SWAP
A
;高4位
與
低4位
交換
ANL
A,#0FH
;取簡譜
碼
JNZ
SING
;取到的簡譜
碼不是0,則去發聲
CLR
TR0
;取到0
則不發聲
SJMP
DLY1
;節拍延時子程序(
隨節拍碼變化,延時時間不同)
;---------------發聲-----------------------
SING:
DEC
A
;取到的簡譜碼減1
;(簡譜碼計數值16位數據存儲首地址從TABLE1
《相對地址》0處開始放起,所以要減1)
MOV
22H,A
;存入(22H)中
RL
A
;乘2
因為取的數據占兩位元組(16位)
;所以指針增加量要乘2
MOV
DPTR,#TABLE1
;...........簡譜碼轉換為相應定時器16位計數值.............
MOVC
A,@A+DPTR
;到TABLE1取相應的高位元組計數值
MOV
TH0,A
;高位元組計數值存入TH0和(21H)中
MOV
21H,A
MOV
A,22H
;減1的簡譜碼給A
RL
A
;乘2
因為取的數據占兩位元組(16位)
;所以指針增加量要乘2
INC
A
;A
增加
取下一個位元組計數值
;...........簡譜碼轉換為相應定時器16位計數值.............
MOVC
A,@A+DPTR
;到TABLE1取相應的低位元組計數值
MOV
TL0,A
;低位元組計數值存入TL0和(20H)中
MOV
20H,A
SETB
TR0
;啟動T0定時器讓喇叭發出不同頻率聲音
;---------------節拍延時-------------------
DLY1:
ACALL
DELAY
;基本單位時間為1/4拍
187ms
INC
30H
;取下一個簡譜碼
節拍
碼
SJMP
NEXT
;---------------歌放完結束---------------
ENDF:
CLR
TR0
;關閉T0定時器
AJMP
START0
;反復循環
;****T0中斷子程序(用來驅動喇叭發出不同頻率聲音)**************
TIME0:
PUSH
ACC
PUSH
PSW
MOV
TL0,20H
;重裝計數值
MOV
TH0,21H
CPL
P3.7
;驅動發聲
POP
PSW
POP
ACC
RETI
;******************節拍延時187ms****************************
DELAY:
MOV
R7,#187
;187ms延時子程序
DLY2:
MOV
R4,#02
DLY3:
MOV
R3,#248
DJNZ
R3,$
DJNZ
R4,DLY3
DJNZ
R7,DLY2
DJNZ
R5,DELAY
RET
;*******音符T值表(用來讓定時器發出不同的頻率)**DW
表示一個
計數值
占兩個位元組存儲單元***************
TABLE1:
DW
64260,64400,64524,64580,64684
;低音SO
低音LA
低音SI
/中音DO
中音RE
DW
64777,64820,64898,64968,65030
;中音MI
中音FA
中音SO
中音LA
中音SI
DW
65058,65110,65157,65178,65217
;高音DO
高音RE
高音MI
高音FA
高音SO
;*********簡譜碼
節拍碼(高4位簡譜碼
,低4位節拍碼)*************
TABLE:
DB
44H,44H,84H,84H
;
1
1
5
5
DB
094H,094H,88h
;
6
6
5
-
DB
74H,74H,63H,63H;
4
4
3
3
DB
52H,52H,48h
;
2
2
1-
DB
84H,84H,74H,74H
;
5
5
4
4
DB
64H,64H,58h;
3
3
2-
DB
84H,84H,74H,74H
;
5
5
4
4
DB
64H,64H,58h
;
3
3
2-
DB
44H,44H,84H,84H
;
1
1
5
5
DB
094H,094H,88h;
6
6
5
-
DB
74H,74H,63H,63H;
4
4
3
3
DB
52H,52H,48h;
2
2
1-
END
加入了LED燈,水平有限,效果有點不太好
;**********************************************
ORG
0000H
SJMP
MAIN
ORG
0BH
AJMP
TIME0
;*************主程序************************
MAIN:
MOV
SP,#60
MOV
TMOD,#01H
;TO定時工作方式
MOV
IE,#82H
;CPU
中斷允許,TO中斷允許
START0:
MOV
30H,#00H
;TABLE
相對地址指針
NEXT:
MOV
A,30H
MOV
DPTR,#TABLE
;到TABLE處取
簡譜碼
節拍
碼
MOVC
A,@A+DPTR
MOV
R2,A
;取到的簡譜碼
節拍碼
暫存於R2中
JZ
ENDF
;取到
00
結束
ANL
A,#0FH
;否,取低四位
節拍
碼
MOV
R5,A
;將節拍碼存於R5中
MOV
A,R2
;簡譜碼
節拍
碼
給A
SWAP
A
;高4位
與
低4位
交換
ANL
A,#0FH
;取簡譜
碼
JNZ
SING
;取到的簡譜
碼不是0,則去發聲
CLR
TR0
;取到0
則不發聲
SJMP
DLY1
;節拍延時子程序(
隨節拍碼變化,延時時間不同)
;---------------發聲-----------------------
SING:
DEC
A
;取到的簡譜碼減1
;(簡譜碼計數值16位數據存儲首地址從TABLE1
《相對地址》0處開始放起,所以要減1)
MOV
22H,A
;存入(22H)中
RL
A
;乘2
因為取的數據占兩位元組(16位)
;所以指針增加量要乘2
MOV
DPTR,#TABLE1
;...........簡譜碼轉換為相應定時器16位計數值.............
MOVC
A,@A+DPTR
;到TABLE1取相應的高位元組計數值
MOV
TH0,A
;高位元組計數值存入TH0和(21H)中
MOV
21H,A
MOV
A,22H
;減1的簡譜碼給A
RL
A
;乘2
因為取的數據占兩位元組(16位)
;所以指針增加量要乘2
INC
A
;A
增加
取下一個位元組計數值
;...........簡譜碼轉換為相應定時器16位計數值.............
MOVC
A,@A+DPTR
;到TABLE1取相應的低位元組計數值
MOV
TL0,A
;低位元組計數值存入TL0和(20H)中
MOV
20H,A
SETB
TR0
;啟動T0定時器讓喇叭發出不同頻率聲音
;---------------節拍延時-------------------
DLY1:
ACALL
DELAY
;基本單位時間為1/4拍
187ms
INC
30H
;取下一個簡譜碼
節拍
碼
CPL
P1.0
LED燈
閃爍
CPL
P1.1
CPL
P1.2
CPL
P1.3
CPL
P1.4
CPL
P1.5
CPL
P1.6
CPL
P1.7
SJMP
NEXT
;---------------歌放完結束---------------
ENDF:
CLR
TR0
;關閉T0定時器
AJMP
START0
;反復循環
;****T0中斷子程序(用來驅動喇叭發出不同頻率聲音)**************
TIME0:
PUSH
ACC
PUSH
PSW
MOV
TL0,20H
;重裝計數值
MOV
TH0,21H
CPL
P3.7
;驅動發聲
POP
PSW
POP
ACC
RETI
;******************節拍延時187ms****************************
DELAY:
MOV
R7,#187
;187ms延時子程序
DLY2:
MOV
R4,#02
DLY3:
MOV
R3,#248
DJNZ
R3,$
DJNZ
R4,DLY3
DJNZ
R7,DLY2
DJNZ
R5,DELAY
RET
;*******音符T值表(用來讓定時器發出不同的頻率)**DW
表示一個
計數值
占兩個位元組存儲單元***************
TABLE1:
DW
64260,64400,64524,64580,64684
;低音SO
低音LA
低音SI
/中音DO
中音RE
DW
64777,64820,64898,64968,65030
;中音MI
中音FA
中音SO
中音LA
中音SI
DW
65058,65110,65157,65178,65217
;高音DO
高音RE
高音MI
高音FA
高音SO
;*********簡譜碼
節拍碼(高位簡譜碼
,低位節拍碼)*************
TABLE:
DB
44H,44H,84H,84H
;
1
1
5
5
DB
094H,094H,88h
;
6
6
5
--表示有節拍
DB
74H,74H,63H,63H
;
4
4
3
3
DB
52H,52H,48h
;
2
2
1-
DB
84H,84H,74H,74H
;
5
5
4
4
DB
64H,64H,58h
;
3
3
2-
DB
84H,84H,74H,74H
;
5
5
4
4
DB
64H,64H,58h
;
3
3
2-
DB
44H,44H,84H,84H
;
1
1
5
5
DB
094H,094H,88h
;
6
6
5
-
DB
74H,74H,63H,63H
;
4
4
3
3
DB
52H,52H,48h
;
2
2
1-
END
Ⅱ 單片機播放音樂的原理
單片機發音原理:利用定時器或PWM功能,輸出PWM,經一級有源濾波後放大驅動揚聲器。
單片機演奏音樂基本是單音頻率,它不包含相應幅度的諧波頻率,
也就是說不能象電子琴那樣能奏出多種音色的聲音,但一定要弄清楚兩個概念即可,也就是「音調」和「節拍」 。音調 表示一個音符唱多高的頻率。節拍 表示一個音符唱多長的時間
1.要生產音頻脈沖,只要算出某一音頻的周期(1/頻率),然後將此周期除以2,即為半周期的時間.利用定時器計時這個半周期時間,每當計時到後就將輸出脈沖的I/O反相,然後重復計時此半周期時間再對I/O反相,就可在I/O腳上得到此頻率的脈沖。
2. 利用8051的內部定時器使用其工作在計數器模式MODE1下,改變計數值THO及TLO以產生不同頻率的方法。
Ⅲ 這是一個利用89C52RC單片機蜂鳴器演奏生日快樂歌。請高手幫我解釋一下:整體思想,再在每一步添加註釋。
#include<reg51.h>
sbit speaker=P1^6;
unsigned char timer0h,timer0l,time;
//生日歌,這三個位元組一組,分別定義:旋律(1234567)、高低音(低音、中音、高音)、節奏(長度)
code unsigned char sszymmh[]={5,1,1, 5,1,1, 6,1,2, 5,1,2, 1,2,2, 7,1,4,
5,1,1, 5,1,1, 6,1,2, 5,1,2, 2,2,2, 1,2,4,
5,1,1, 5,1,1, 5,2,2, 3,2,2, 1,2,2, 7,1,2, 6,1,2,
4,2,1, 4,2,1, 3,2,2, 1,2,2, 2,2,2, 1,2,4};
// 音階頻率表 高八位,也就是發音對應頻率的高八位
code unsigned char FREQH[]={0xF2,0xF3,0xF5,0xF5,0xF6,0xF7,0xF8, 0xF9,0xF9,0xFA,0xFA,0xFB,0xFB,0xFC,0xFC, //1,2,3,4,5,6,7,8,i
0xFC,0xFD,0xFD,0xFD,0xFD,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF,} ;
// 音階頻率表 低八位,也就是發音對應頻率的低八位
code unsigned char FREQL[]={0x42,0xC1,0x17,0xB6,0xD0,0xD1,0xB6,0x21,0xE1,0x8C,0xD8,0x68,0xE9,0x5B,0x8F, //1,2,3,4,5,6,7,8,i
0xEE,0x44, 0x6B,0xB4,0xF4,0x2D,0x47,0x77,0xA2,0xB6,0xDA,0xFA,0x16, };
void delay(unsigned char t) //延時程序
{
unsigned char t1;
unsigned long t2;
for(t1=0;t1<t;t1++)
{
for(t2=0;t2<8000;t2++)
{ ; } }
TR0=0;
}
void t0int() interrupt 1 //定時器0中斷服務程序,控制聲音打頻率
{ TR0=0;
speaker=!speaker;
TH0=timer0h;
TL0=timer0l;
TR0=1;
}
void song() //啟動演奏當前頻率
{ TH0=timer0h; //當前頻率的高八位
TL0=timer0l; //當前頻率的低八位
TR0=1; //啟動定時器0
delay(time); //延時當前頻率的演奏時間
}
void main(void)
{
unsigned char k,i;
TMOD=1; //置CT0定時工作方式1 EA=1; ET0=1;//IE=0x82 //CPU開中斷,CT0開中斷
while(1)
{
i=0;
while(i<75)
{ //音樂數組長度 ,唱完從頭再來
k=sszymmh[i]+7*sszymmh[i+1]-1; //取當前節奏的頻率地址
timer0h=FREQH[k]; //取當前頻率高八位
timer0l=FREQL[k]; //取當前頻率低八位
time=sszymmh[i+2]; //取當前頻率的時長
i=i+3; //三個位元組一組
song(); //演奏當前頻率,共75/3,25個曲調。
}
}
}
//程序的設計思路就是將一首樂曲分成三個變數來控制,分別是曲調、所在音區、時長。而控制曲調的因素也就是頻率又分成高八位和第八位兩個表,每演奏一個曲調,就根據該曲調的三個變數來取值。
Ⅳ 讓單片機唱歌的c語言程序是怎麼弄的
其實原理很簡單,就是控制單片機的某個引腳,輸出一定頻率的方波信號,而輸出方波信號的方法,是最基礎的,最簡單的編程了,用定時器定時,根據信號頻率算出信號周期,然後計算出定時的時間。那單片機演奏歌曲的程序,也是同樣的原理,只是事先根據歌曲的簡譜查出每個音階的信號頻率,再根據各音階頻率計算出定時器的初值。演奏時,按簡譜的各音階順序輸出不同的頻率的信號就行了。
下表是音階與頻率對應關系表,給出常用音階對應的定時常數。
Ⅳ 51單片機唱歌怎麼實現啊
單片機可以演奏從低音、中音、高音和超高音,四個八度共28個音符。
演奏樂曲時,就根據音符的不同數值,從半周期數據表中找到定時時間初始值,送入定時器即可控制發音的音調。
比如把表中的0xF2和0x42送到定時器,定時器按照這個初始值來產生中斷,輸出的方波,人們聽起來,這就是低音1。
樂曲的數據,也要寫個數據表,程序中以 code unsigned char sszymmh[] 命名。
這個表中每三個數字,說明了一個音符,它們分別代表:
第一個數字是音符的數值1234567之一,代表多來咪發...;
第二個數字是0123之一,代表低音、中音、高音、超高音;
第三個數字是時間長度,以半拍為單位。
樂曲數據表的結尾是三個0。
Ⅵ 用51單片機實現音樂播放的原理是什麼
需要寫一段程序。
如果是簡單的音樂,編樂譜推蜂鳴器就可以;如果是mp3/wav之類的音樂,需要晶元自帶解碼模塊,或者使用外部解碼晶元,還需要dac將聲音推出來。
聲音的頻譜范圍約在幾十到幾千赫茲,若能利用程序來控制單處機某個口線的「高」電平或低電平,則在該口線上就能產生一定頻率的矩形波,接上喇叭就能發出一定頻率的聲音,若再利用延時程序控制「高」「低」電平的持續時間,就能改變輸出頻率,從而改變音調。要准確奏出一首曲子,必須准確地控制樂曲節奏,即一音符的持續時間。音符的節拍我們可以用定時器T0來控制,送入不同的初值,就可以產生不同的定時時間。便如某歌曲的節奏為每分鍾94拍,即一拍為0.64秒。
Ⅶ 單片機,用一個蜂鳴器可以演奏出音樂嗎
當然可以。
單片機演奏一個音符,是通過引腳,周期性的輸出一個特定頻率的方波。
這就需要單片機,在半個周期內輸出低電平、另外半個周期輸出高電平,周而復始。
眾所周知,周期為頻率的倒數,可以通過音符的頻率計算出周期;演奏時,要根據音符的不同,把對應的、半個周期的定時時間初始值,送入定時器,再由定時器按時輸出高低電平。
Ⅷ 單片機電子琴演奏
八鍵電子琴.hex:
:
:
:
:
:
:
:
:
:
:
:03000B000200B739
:0900B70085098C850A8AB2B73272
:030000000200AB50
:
:00000001FF
八鍵觸摸電子琴.hex:
:
:
:
:
:
:
:
:
:
:
:
:03000B000200C52B
:0900C50085098C850A8AB2B73264
:030000000200B942
:
:00000001FF
老鼠愛大米.hex:
:03000000020014E7
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:00000001FF
圖太大,告訴我郵箱,我發你。