?? yinxiang.c
字號:
//-----------------------------------------------------------------------------
// 版權歸新華龍電子公司所有
//-----------------------------------------------------------------------------
//
//文件名: YinXiang.c
//
//編寫人: LC
//
//編寫時間:2005/03/10
//
//目標器件: C8051F02x
//
//編譯工具: Silicon Laboratories IDE
//
//程序說明: 此程序將某段音樂用特定的頻率播放出來
//P54--MUSIC
//------------------------------------------------------------------------------------
// 頭文件包含
//------------------------------------------------------------------------------------
#include <C8051F020.h>
#include <ctype.h>
//------------------------------------------------------------------------------------
// Global CONSTANTS
//------------------------------------------------------------------------------------
#pragma ot(0)
#define uint unsigned int
#define uchar unsigned char
#define OSFREQ 6000000l /*所使用的晶振頻率*/
/**************音符頻率表****************/
uint code notefreq[]={ 523, 587, 659, 698, 784, 880, 988,
1047,1175,1319,1396,1568,1760,1976,
2093,2349,2637,2793,3136,3520,3961};
//uint code timreg[]={ 65058, 65110, 65157, 65178, 65217, 65252, 65283,
// 65297,65323,65347,65357,65377,65394,65410,
// 65417,65430,65441,65447,65456,65465,65473};
/*************音名***************/
uchar code notename[]={ 'c','d','e','f','g','a','b',
'1','2','3','4','5','6','7',
'C','D','E','F','G','A','B',0};
/*************半音頻率表*****************/
uint code halfnotefreq[]={ 554, 622, 740, 831, 933,
1109,1245,1480,1161,1865,
2218,2489,2960,3322,3729};
//uint code halftimreg[]={ 65085, 65134, 65198, 65235, 65268,
// 65311,65335,65367,65321,65402,
// 65423,65436,65452,65461,65469};
/*************音名***************/
uchar code halfnotename[]={ 'c','d','f','g','a',
'1','2','4','5','6',
'C','D','F','G','A',0};
//sbit BEEP_PWR=P1^0;
uchar FreqSandH,FreqSandL; /*產生方波的定時器的初值*/
uchar timer1cnt; /*定時器延時計數 */
uchar timer1cntflg; /*定時器定時完成標志 */
/***************************************************************************************
函數名稱: void timer0int() interrupt 1
功能描述: 定時器0中斷用來產生方波
輸入: 無
輸出: 無
全局變量: TH0,TL0,P5
調用模塊: 無
***************************************************************************************/
void timer0int () interrupt 1
{
TH0=FreqSandH;
TL0=FreqSandL;
P5 = P5 ^ 0x10; // change state of P5.4
}
/***************************************************************************************
函數名稱: void delay(uchar time)
功能描述: 延時
輸入: uchar time: 延時時間長度
輸出: 無
全局變量: 無
調用模塊: 無
***************************************************************************************/
void delay(uchar time)
{
uchar i;
uint j;
for(i=0;i<time;i++)
for(j=0;j<0x900;j++);
}
/***************************************************************************************
函數名稱: void sound(uint freq)
功能描述:
輸入: uint freq: 頻率值
輸出: 無
全局變量: OSFFEQ,FreqSandH,FreqSandL,TR0,ET0
調用模塊: 無
***************************************************************************************/
void Sound(uint freq)
{
uint timreg;
timreg=65536l-(OSFREQ/(24l*freq));
FreqSandH=timreg/256;
FreqSandL=timreg&0x00ff;
TR0=1;
ET0=1;
}
/***************************************************************************************
函數名稱: void Soundoff(void)
功能描述: 停止發聲
輸入: 無
輸出: 無
全局變量: TR0,ET0,P5
調用模塊: 無
***************************************************************************************/
void SoundOff(void)
{
TR0=0;
ET0=0;
//P5 = P5 & 0xef;
P5 = P5 | 0x10;
}
/***************************************************************************************
函數名稱: void GetFreq(uchar ch, uchar flag)
功能描述: 依據音名取對應的頻率
輸入: uchar ch: 音名
uchar flg: 全音/半音選擇
輸出: 返回頻率值
全局變量: halfnotename[],notename[],halfnotefreq[],notefreq[]
調用模塊: 無
***************************************************************************************/
uint GetFreq(uchar ch,uchar flg)
{
uchar * pn,i=0;
uint * pf;
if(flg) {pn=halfnotename; pf=halfnotefreq;}
else {pn=notename; pf=notefreq;}
while(1)
{
if(pn[i]==0) return 0;
if(ch==pn[i]) return pf[i];
i++;
}
}
/***************************************************************************************
函數名稱: void PORT_Init(void)
功能描述: 初始化I/O
輸入: 無
輸出: 無
全局變量: XBR2,P74OUT
調用模塊: 無
***************************************************************************************/
void PORT_Init (void)
{
XBR2 = 0x40; /*使能交叉開關和弱上拉*/
P74OUT |= 0xff; /*使能P6,P7推挽輸出*/
}
void Play(char * str)
{
uchar i=0,ch,halfflg=0;
uchar lasttime;
uint freq;
/*無效看門狗*/
WDTCN = 0xde;
WDTCN = 0xad;
PORT_Init ();
OSCICN=0x14; /*使用內部晶振*/
while(1)
{
for(;;i++)
{
ch=str[i]; /*允許曲譜用空格符 '|'符,換行回車等分隔以便閱讀*/
if((ch==' ')||(ch=='|')||(ch=='\r')||(ch=='\n')) {i++;continue;}
if(!ch) {SoundOff(); return;} /*樂曲結束則播放完畢*/
if(ch=='#') {halfflg=1; continue;} /*半音標志*/
if(isdigit(ch)||isalpha(ch))
{
freq=GetFreq(ch,halfflg); /*從音名獲取頻率*/
lasttime=16;
break;
}
else {halfflg=0; continue;}
}
i++;
ch=str[i]; /*從下一個符號獲取額外音長符號*/
while(1)
{
if(!ch) break;
if(isdigit(ch)||isalpha(ch)) break; /*非音長符號則下次處理*/
if(ch=='-') lasttime+=8; /*額外延時一拍*/
if(ch=='.') lasttime+=4; /*額外延時半拍*/
if(ch=='_') lasttime/=2; /*下劃線相當于簡譜中音名下面的下劃線,延時減半*/
if(ch=='=') lasttime/=4; /*雙下劃線相當于簡譜中音名下面的雙下劃線,延時減為1/4*/
i++;
ch=str[i];
}
if(freq!=0) Sound(freq); /*發聲*/
else SoundOff();
delay(lasttime); /*延時*/
SoundOff();
delay(1); /*兩個引之間的間歇*/
}
}
/*
編譜說明,低音(簡譜中數字下面有一個點的)1234567對應的為小寫cdefgab
中音(簡譜中數字上下都沒有點的)1234567對應的也為1234567
高音(簡譜中數字上面有一個點的)1234567對應的為大寫CDEFGAB
對于降音符b或聲音符#一律用#+合適的音名例如#5
一個音符本身為一拍,加下劃線后為半拍加等號為1/4拍 如:65_ 4= 則音6為一拍,音5為半拍,音4為1/4拍
下劃線或等號連續書寫則音長連續變短
音符后加-或.表示延長。‘-’延長一拍‘.’延長半拍多加則延長連續增加
*/
void main(void)
{
//uint i;
TMOD=0x11; ET0=1; EA=1;
delay(10);
//Play("1_1_5_5_6_6_5 4_4_3_3_2_2_1 5_5_4_4_3_3_2 5_5_4_4_3_3_21_1_5_5_6_6_5 4_4_3_3_2_2_1"); /*滿天都是小星星*/
//Play("1_2_3_1_ 1_2_3_1_ 3_4_5 3_4_5 5=6=5=4=3_1_ 5=6=5=4=3_1_ 2_g_12_g_1"); /*兩只老虎*/
//Play("a-a1-a2--a-b1b13-2a--a-- a-33-12--a-b1b13-21--1-- 5-55432--a-b1-12123--3-- 1-1_1_1235--4-32-b3-2a--a-- a-66565--4-34-56543--3--1-1_1_1235--4-32-b3-2a--a--"); /*山楂樹*/
//Play("5._3=2_1_5-12_3_g-5.3_23_5_1a_3_2-356.5_352._3=2_1_a32_21_a1g05.3_6562_3_50"); /*學習雷鋒好榜樣*/
//Play("C-53.2_1530C-53.2_1650 5_C6_5_C05_C6_5_6_0_3_C.6_53C.6_C0C53_6_5_3_2.1_30_5_C56_C_6_5_33_1_6-60C._C=5_5_2._3=5_5_6.5_6DC6_5_C6_5_33_5_C-"); /*團結就是力量*/
//Play("3- 2_3_4_3 3- 2_3_4_3 3- 4- 3_4_5_4 4- 3-2- 3- 2_3_4_3 3- 2_3_4_3 3-4- 3_4_5_4 4- 3-2");/*許巍-星空前奏*/
//Play("543 3_2_1_2_30 g53 3_2_1_2_30 a65 4_3_2_3_4 1 b a g");/*許巍-時光*/
Play("g_g_ag 1b- g_g_ag 21- g_g_53 1ba 004_4_ 312 1--1 "); /*生日快樂*/
SoundOff();
while(1);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -