keil編程實例音樂
單片機源程序如下:
- /**********************
- 基于STC15F2K60S2系列單片機C語言編程實現
- 使用如下頭文件,不用另外再包含"REG51.H"
- ***********************/
- #include <STC15F2K60S2.h>
- #define uint unsigned int
- #define uchar unsigned char
- sbit beep=P3^4; //蜂鳴器
- sbit key1=P3^2; //按鍵1
- sbit key2=P3^3; //按鍵2
- sbit key3=P1^7; //按鍵3
- sbit Sel0=P2^0;
- sbit Sel1=P2^1;
- sbit Sel2=P2^2;//位選的三個引腳控制位
- uchar pinlv;
- uchar pinlv_flag;//改變數碼管滾動頻率
- uchar show_w1;
- uchar show_w2;
- uchar show_w3;
- uchar show_w4;
- uchar show_w5;
- uchar show_w6;
- uchar show_w7;
- uchar show_w8;//show_wi,分別對應從左到右的每個數碼管上的數字
- uchar duanxuan[]={0x73,0x38,0x79,0x77,0x6d,0x79,0x00,0x79,0x37,0x1e,0x3f,0x6e,0x40,0x40,0x0f,0x39,0x38,0x6e,0x00,0x00};//段選,顯示PLEASE ENJOY--XLY
- uchar weixuan[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07}; //位選,選擇是0-7中的一個數碼管
- uchar flag0,count;//數碼管掃描快慢分頻作用
- uchar timeh,timel,jindu=0,gequ=0; //定義定時器的重裝值
- bit flag; //播放標志位
- uchar code music1[] ={ //音樂代碼,歌曲為《同一首歌》,格式為: 音符, 節拍, 音符, 節拍,
- 0x15,0x20,0x21,0x10, //音符的十位代表是低八度,中八度還是高八度,1代表低八度,2代表中八度,3代表高八度
- 0x22,0x10,0x23,0x15, //個位代表簡譜的音符,例如0x15代表低八度的S0,0x21代表中八度的DO。
- 0x24,0x05,0x23,0x10, //節拍則是代表音長,例如:0x10代表一拍,0x20代表兩拍,0x05代表1/2拍
- 0x21,0x10,0x22,0x20,
- 0x21,0x10,0x16,0x10,
- 0x21,0x40,0x15,0x20,
- 0x21,0x10,0x22,0x10,
- 0x23,0x10,0x23,0x05,
- 0x24,0x05,0x25,0x10,
- 0x21,0x10,0x24,0x15,
- 0x23,0x05,0x25,0x10,
- 0x22,0x05,0x23,0x05,
- 0x23,0x05,0x22,0x05,
- 0x22,0x30,0x23,0x20,
- 0x25,0x10,0x31,0x10,
- 0x27,0x15,0x26,0x05,
- 0x26,0x20,0x25,0x10,
- 0x25,0x05,0x26,0x05,
- 0x27,0x10,0x26,0x05,
- 0x25,0x05,0x23,0x40,
- 0x24,0x15,0x24,0x05,
- 0x25,0x10,0x26,0x10,
- 0x25,0x10,0x24,0x05,
- 0x23,0x05,0x22,0x20,
- 0x17,0x10,0x17,0x05,
- 0x16,0x05,0x15,0x10,
- 0x16,0x10,0x21,0x40,
- 0x00,0x00
- };
- uchar code music2[] ={ //歌曲為小星星
- 0x21,0x10,0x21,0x10,
- 0x25,0x10,0x25,0x10,
- 0x26,0x10,0x26,0x10,
- 0x25,0x20,0x24,0x10,
- 0x24,0x10,0x23,0x10,
- 0x23,0x10,0x22,0x10,
- 0x22,0x10,0x21,0x20,
- 0x25,0x10,0x25,0x10,
- 0x24,0x10,0x24,0x10,
- 0x23,0x10,0x23,0x10,
- 0x22,0x20,
- 0x25,0x10,0x25,0x10,
- 0x24,0x10,0x24,0x10,
- 0x23,0x10,0x23,0x10,
- 0x22,0x20,
- 0x21,0x10,0x21,0x10,
- 0x25,0x10,0x25,0x10,
- 0x26,0x10,0x26,0x10,
- 0x25,0x20,0x24,0x10,
- 0x24,0x10,0x23,0x10,
- 0x23,0x10,0x22,0x10,
- 0x22,0x10,0x21,0x20,
- 0x00,0x00
- };
- uchar code music3[] ={ //歌曲為天空之城
- 0x16,0x05,0x17,0x05,
- 0x21,0x15,0x17,0x05,
- 0x21,0x10,0x23,0x10,
- 0x17,0x30,0x23,0x10,
- 0x16,0x15,0x15,0x05,
- 0x16,0x10,0x21,0x10,
- 0x15,0x30,0x13,0x10,
- 0x14,0x15,0x13,0x05,
- 0x14,0x05,0x21,0x05,
- 0x21,0x10,0x13,0x30,
- 0x21,0x10,0x17,0x10,
- 0x14,0x05,0x14,0x10,
- 0x17,0x10,0x17,0x20,
- 0xff,
- 0x16,0x05,0x17,0x05,
- 0x21,0x15,0x17,0x05,
- 0x21,0x10,0x23,0x10,
- 0x17,0x30,0x13,0x05,
- 0x13,0x05,0x16,0x15,
- 0x15,0x05,0x16,0x10,
- 0x21,0x10,0x15,0x30,
- 0x13,0x10,0x14,0x10,
- 0x21,0x05,0x17,0x05,
- 0x17,0x10,0x21,0x10,
- 0x22,0x10,0x23,0x05,
- 0x21,0x20,0xff,
- 0x21,0x05,0x17,0x05,
- 0x16,0x10,0x17,0x10,
- 0x15,0x10,0x16,0x20,
- 0xff,
- 0x21,0x05,0x22,0x05,
- 0x23,0x15,0x22,0x10,
- 0x23,0x10,0x24,0x10,
- 0x25,0x05,0x22,0x30,
- 0x15,0x10,0x22,0x03,
- 0x21,0x03,0x17,0x03,
- 0x21,0x03,0x21,0x10,
- 0x21,0x05,0x22,0x10,
- 0x23,0x05,0x23,0x40,
- 0x16,0x05,0x17,0x05,
- 0x21,0x10,0x17,0x05,
- 0x21,0x05,0x22,0x10,
- 0x21,0x15,0x15,0x05,
- 0x15,0x20,0x24,0x10,
- 0x23,0x10,0x22,0x10,
- 0x21,0x10,0x23,0x30,
- 0x16,0x05,0x17,0x05,
- 0x21,0x15,0x17,0x05,
- 0x21,0x10,0x23,0x10,
- 0x17,0x30,0x13,0x10,
- 0x16,0x15,0x15,0x05,
- 0x16,0x10,0x21,0x10,
- 0x15,0x30,0x13,0x10,
- 0x14,0x10,0x21,0x05,
- 0x17,0x05,0x17,0x10,
- 0x21,0x10,0x22,0x10,
- 0x23,0x05,0x21,0x05,
- 0x21,0x20,0x21,0x05,
- 0x17,0x05,0x16,0x10,
- 0x17,0x10,0x15,0x10,
- 0x16,0x40,0x00,0x00
- };
- uchar code quzi[] ={ //此數組數據為各個音符在定時器中的重裝值,第一列是高位,第二列是低位 //時間
- 0xf8,0x8c, //低八度,低1
- 0xf9,0x5b,
- 0xfa,0x15, //低3
- 0xfa,0x67,
- 0xfb,0x04, //低5
- 0xfb,0x90,
- 0xfc,0x0c, //低7
- 0xfc,0x44, //中央C調
- 0xfc,0xac, //中2
- 0xfd,0x09,
- 0xfd,0x34, //中4
- 0xfd,0x82,
- 0xfd,0xc8, //中6
- 0xfe,0x06,
- 0xfe,0x22, //高八度,高1
- 0xfe,0x56,
- 0xfe,0x6e, //高3
- 0xfe,0x9a,
- 0xfe,0xc1, //高5
- 0xfe,0xe4,
- 0xff,0x03 //高7
- };
- /**********************
- 函數名稱:void delay(unsigned int xms)
- 功能描述:延時
- 入口參數:xms:輸入需要延時的毫秒值
- 出口參數:無
- 備注:
- ***********************/
- void delay(unsigned int xms)
- {
- uint i,j;
- for(i=xms;i>0;i--)
- for(j=124;j>0;j--);
- }
- /**********************
- 函數名稱:uchar quyin(uchar tem)
- 功能描述:在quzi數組中,找到music數組定義的簡譜音符的重裝值,并返回其在quzi數組中的位置
- 入口參數:tem:music數組中定義的簡譜音符
- 出口參數:返回的是tem音符在quzi數組中的位置值
- 備注:
- ***********************/
- uchar quyin(uchar tem)
- {
- uchar qudiao,jp,weizhi; //定義曲調,音符和位置
- qudiao=tem/16; //高4位是曲調值
- jp=tem%16; //低4位是音符
- if(qudiao==1) //當曲調值為1時,即是低八度,低八度在quzi數組中基址為0
- qudiao=0;
- else if(qudiao==2) //當曲調值為2時,即是中八度,中八度在quzi數組中基址為14
- qudiao=14;
- else if(qudiao==3) //當曲調值為3時,即是高八度,高八度在quzi數組中,基址為28
- qudiao=28;
- weizhi=qudiao+(jp-1)*2; //通過基址加上音符作為偏移量,即可定位此音符在quzi數組中的位置
- return weizhi; //返回這一個位置值
- }
- /**********************
- 函數名稱:void playmusic()
- 功能描述:播放音樂
- 入口參數:無
- 出口參數:無
- 備注:
- ***********************/
- void playmusic()
- {
- uchar p,m,tem; //m為節拍
- while(1)
- {
- if(flag==1) //若播放的標志位為1則播放音樂
- {
- if(gequ==0) //歌曲選擇位為0,則播放第一首歌
- {
- p=music1[jindu];
- if(p==0x00) //如果碰到結束符,延時1秒,回到開始再來一遍
- {
- jindu=0;
- delay(1000);
- break;
- }
- else if(p==0xff) //若碰到休止符,延時100ms,繼續取下一音符
- {
- jindu=jindu+1;
- delay(100);
- TR0=0;
- break;
- }
- else //正常情況下取音符和節拍
- {
- tem=quyin(music1[jindu]); //取出當前音符在quzi數組中的位置值
- timeh=quzi[tem]; //把音符相應的計時器重裝載值賦予timeh和timel
- timel=quzi[tem+1];
- jindu++;
- TH0=timeh; //把timeh和timel賦予計時器
- TL0=timel;
- m=music1[jindu]; //取得節拍
- jindu++;
- }
- TR0=1; //開定時器0
- delay(m*180); //等待節拍完成, 通過P3^4口輸出音頻
- TR0=0; //關定時器0
- beep=0; //使beep端口置0,起保護蜂鳴器作用
- }
- else if(gequ==1) //歌曲選擇位為1,則播放小星星
- {
- p=music2[jindu];
- if(p==0x00) //如果碰到結束符,延時1秒,回到開始再來一遍
- {
- jindu=0;
- delay(1000);
- break;
- }
- else if(p==0xff) //若碰到休止符,延時100ms,繼續取下一音符
- {
- jindu=jindu+1;
- delay(100);
- TR0=0;
- break;
- }
- else //正常情況下取音符和節拍
- {
- tem=quyin(music2[jindu]); //取出當前音符在quzi數組中的位置值
- timeh=quzi[tem]; //把音符相應的計時器重裝載值賦予timeh和timel
- timel=quzi[tem+1];
- jindu++;
- TH0=timeh; //把timeh和timel賦予計時器
- TL0=timel;
- m=music2[jindu]; //取得節拍
- jindu++;
- }
- TR0=1; //開定時器1
- delay(m*300); //等待節拍完成, 通過P3^4口輸出音頻
- TR0=0; //關定時器1
- beep=0; //使beep端口置0,起保護蜂鳴器作用
- }
- else if(gequ==2) //歌曲選擇位為2,則播放天空之城
- {
- p=music3[jindu];
- if(p==0x00) //如果碰到結束符,延時1秒,回到開始再來一遍
- {
- jindu=0;
- delay(1000);
- break;
- }
- else if(p==0xff) //若碰到休止符,延時100ms,繼續取下一音符
- {
- jindu=jindu+1;
- delay(100);
- TR0=0;
- break;
- }
- else //正常情況下取音符和節拍
- {
- tem=quyin(music3[jindu]); //取出當前音符在quzi數組中的位置值
- timeh=quzi[tem]; //把音符相應的計時器重裝載值賦予timeh和timel
- timel=quzi[tem+1];
- jindu++;
- TH0=timeh; //把timeh和timel賦予計時器
- TL0=timel;
- m=music3[jindu]; //取得節拍
- jindu++;
- }
- TR0=1; //開定時器1
- delay(m*200); //等待節拍完成, 通過P3^4口輸出音頻
- TR0=0; //關定時器1
- beep=0; //使beep端口置0,起保護蜂鳴器作用
- }
- }
- else //播放標志位不為1時,暫停播放音樂
- while(flag!=1);
- }
- }
- /**********************
- 函數名稱:void init_sys()
- 功能描述:系統初始化,功能是配置IO口
- 入口參數:無
- 出口參數:無
- 備注:
- ***********************/
- void init_sys()
- {
- P0M0=0xff; //設置推挽模式
- P0M1=0x00;
- P2M0=0x08;
- P2M1=0x00;
- P3M0=0x10;
- P3M1=0x00;
- P4M0=0x00;
- P4M1=0x00;
- P5M0=0x00;
- P5M1=0x00;
- }
- /**********************
- 函數名稱:void init()
- 功能描述:定時器和外部中斷的初始化
- 入口參數:無
- 出口參數:無
- 備注:
- ***********************/
- void init()
- {
- TMOD=0x01; //設置定時器0,定時方式1,16位手動重裝模式(TH0和TL0全用)
- TH0=0xD8; //設置定時初值
- TL0=0xEF;
- IE=0x8f; // 1000 1111 EA=1(打開總的終中斷),ET1=1(定時器1中斷使能),EX0=1(外部中斷0使能),ET0=1(定時器0中斷使能),EX1=0(外部中斷1使能);
- IP=0x02; // 0000 0010 PT0=1; 定時器0優先級高
- TR0=0; //定時器0停止工作,初始化
- beep=0; //使beep端口置0,起保護蜂鳴器作用
-
- flag0=0;
- count=0;
-
- show_w1=0;
- show_w2=1;
- show_w3=2;
- show_w4=3;
- show_w5=4;
- show_w6=5;
- show_w7=6;
- show_w8=7;//賦初值,為接下來取模做準備
- }
- void main()
- {
- init_sys(); //系統初始化
- init();
- P0=0x00; //P0口初始化
- key1=1; //三個按鍵設為輸入狀態,檢測中斷
- key2=1;
- key3=1;
- flag=0; //播放標志位清零
-
- TMOD=0x90;//定時器1,方式1
- ET1=1;//開啟定時器1中斷
- pinlv_flag=0;
- pinlv=100;
- TH1=(65535-1000)/256;//定時器1的高八位設置
- TL1=(65535-1000)%256;//定時器1的低八位設置,這里總體就是設置定時器0的初始值是1ms
- TR1=1;//啟動定時器1
- EA=1;//打開總的中斷
-
- while(1)
- {
- playmusic(); //播放音樂函數
- }
- }
- /**********************
- 函數名稱:void tim1() interrupt 1
- 功能描述:定時器0中斷處理,重新裝值,并把beep值取反,產生方波
- 入口參數:無
- 出口參數:無
- 備注:
- ***********************/
- void tim1() interrupt 1 //計時器控制頻率
- {
- TH0=timeh; //賦初值
- TL0=timel;
- beep=~beep; //中斷使得beep翻轉產生方波
- }
- /**********************
- 函數名稱:void ex1() interrupt 0
- 功能描述:按下按鍵1的外部中斷,對標志位取反,功能是暫停和播放音樂
- 入口參數:無
- 出口參數:無
- 備注:
- ***********************/
- void ex1() interrupt 0
- {
- delay(5);
- if(key1==0) //判斷key1是否按下
- {
- delay(5); //按鍵消抖
- if(key1==0)
- {
- while(!key1);
- flag=~flag; //播放中斷位取反,播放或者暫停
- }
- }
- }
- /**********************
- 函數名稱:void ex2() interrupt 2
- 功能描述:按下按鍵2的外部中斷,作用為切換歌曲
- 入口參數:無
- 出口參數:無
- 備注:
- ***********************/
- void ex2() interrupt 2
- {
- delay(5);
- if(key2==0) //按鍵key2按下,切換歌曲
- {
- jindu=0; //歌曲的進度清零,從頭開始演唱
- gequ++; //下一曲
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
final_4.rar
(46.47 KB, 下載次數: 97)
2018-1-4 23:51 上傳
點擊文件名下載附件
keil實例 下載積分: 黑幣 -5
|