亚洲春色中文字幕久久久-三上亚,一吻二脱三床四吻胸,国产真实伦对白视频全集,在线毛片观看,精品成品入口黄网,国产毛aⅴ片久久久,亚洲AV色香蕉一区二区三区老师,萧皇后A级艳片,色情日本视频更新,99久久亚洲精品日本无码
標題:
單片機21音電子琴程序 含仿真
[打印本頁]
作者:
愛寶之tear
時間:
2016-10-10 10:48
標題:
單片機21音電子琴程序 含仿真
21音電子琴程序仿真
0.png
(29.95 KB, 下載次數: 38)
下載附件
2016-10-10 20:18 上傳
0.png
(47.58 KB, 下載次數: 29)
下載附件
2016-10-10 20:18 上傳
所有資料打包下載:
21音電子琴程序【含仿真】.zip
(205.26 KB, 下載次數: 35)
2016-10-10 10:47 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
單片機源程序:
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define PSMG P0 //數碼管IO口
#define PKEY P1 //定義4x4按鍵接的IO口 行掃描
#define PLED P2 //LED接的IO口
sbit PLAY = P3^1;
sbit SPK = P3^0;
#define ALLSONG 3 //歌曲總數 按實際寫
#define CODEMAX 30 //最大音符數
uchar tone_h;
uchar tone_l;
uchar t1_flag = 0; //用于記錄定時器1進入中斷的次數
uchar PressTime = 0; //按鍵按下的時間(節拍)
uchar code chuzhi[3][16]={ //音調對應的計數初值
0xff,0xff, //用任意值占0位,因為音調從1開始
0xf8,0x8c,//低1
0xf9,0x5b,// 2
0xfa,0x15,// 3
0xfa,0x67,// 4
0xfb,0x04,// 5
0xfb,0x90,// 6
0xfc,0x0c,//低7
0xff,0xff,//占0位
0xfc,0x44,//中1
0xfc,0xac,// 2
0xfd,0x09,// 3
0xfd,0x34,// 4
0xfd,0x82,// 5
0xfd,0xc8,// 6
0xfe,0x06,//中7
0xff,0xff,//占0位
0xfe,0x22,//高1
0xfe,0x56,// 2
0xfe,0x85,// 3
0xfe,0x9a,// 4
0xfe,0xc1,// 5
0xfe,0xe4,// 6
0xff,0x03 //高7
};
//共陰數碼管段碼表
uchar code YDTAB[23]={
0x00, //各段全滅 【0】
0x77,0x7c,0x39,0x5e,0x79,0x71,0x3d, //a - g 【1~7】
0x3f, //0 【8】
0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, //1 - 7 【9~15】
0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87 //1. - 7. 【16~22】
};
//發光二極管閃爍表
uchar code LEDTAB[9]={0xff,0x7f,0x3f,0x1f,0x0f,0x07,0x03,0x01,0x00};
//****** 生日快樂 ******
uint code srkl[] = {
205,205,406,405,411,807,
205,205,406,405,412,811,
205,205,415,413,411,407,406,
314,114,413,411,413,812,
305,105,406,405,411,807,
305,105,406,405,412,811,
305,105,415,413,411,
407,406,314,114,413,411,412,811,410,
0xffff
};
//*******戀曲1990*******
uint code lq1990[] = {
613,213,412,411,613,213,412,411,613,213,412,411,1213, 110, //前奏
215,215,215,215,413,412, //烏溜溜的黑眼珠
613,211,211,212,413,1206, //和你的笑臉
212,213,212,213,415,213,212, //怎么也難忘記
612,211,211,206,405,1213,110, //你 容顏的轉變
215,215,215,215,213,212, //輕飄飄的舊時
613,211,211,212,213,1206, //光 就這么溜走
212,213,212,213,415,213,212, //轉頭回去看看
612,205,213,212,413,1211,110, //時 已匆匆數年
215,215,215,215,413,412, //蒼茫茫的天涯
613,211,211,212,413,1206, //路 是你的漂泊
212,213,212,213,415,213,212, //尋尋覓覓長相
612,211,211,206,405,1213,110, //守 是我的腳步
215,215,215,215,213,212, //黑漆漆的孤枕
613,211,211,212,213,1206, //邊 是你的溫柔
212,213,212,213,415,213,212, //醒來時的清晨
612,205,213,212,413,1211,110, //里 是我的哀愁
215,215,215,215,413,412, //轟隆隆的雷雨
613,211,211,212,413,1206, //聲 在我的窗前
212,213,212,213,415,213,212, //怎么也難忘記
612,211,211,206,405,1213,110, //你 離去的轉變
215,215,215,215,213,212, //孤單單的身影
613,211,211,212,213,1206, //后 寂寥的心情
212,213,212,213,415,213,212, //永遠無怨
612,205,213,212,413,1211,110, //的 是我的雙眼
615,213,415,416, //或許明日
621,216,421,416, //太陽西下
415,415,415,416,1213, //倦鳥已歸時
212,213,212,213,415,413, //你將已經踏上
612,211,411,413,1212,210, //舊時的歸途
613,213,412,413, //人生難得
615,213,415,416, //再次尋覓
421,421,421,422,1216, //相知的伴侶
221,221,221,221,416,415, //生命終究難舍
212,412,212,412,413,1215,1610, 1610, //藍藍的白云天
0xFFFF,
};
//==========================
//粗略延時函數
//==========================
void delayms(uint ms)//延時?個 ms
{
uchar a,b,c;
while(ms--)
{
for(c=1;c>0;c--)
for(b=142;b>0;b--)
for(a=2;a>0;a--);
}
}
//======================
//定時器1 測量按鍵持續的節拍數
//======================
void Timer1_Init(void)
{
EA = 1;
ET1 = 1;
TMOD &= 0x0F;
TMOD |= 0x10;
TH1 = (65536-25000)/256;
TL1 = (65536-25000)%256; //25ms中斷一次
}
void timer1() interrupt 3
{
TH1 = (65536-25000)/256;
TL1 = (65536-25000)%256; //25ms中斷一次
t1_flag++;
if(t1_flag == 5) //125ms
{
t1_flag = 0;
if(PressTime < 16) //最多16 即最長4秒
PressTime++;
//8個LED顯示節拍
if(PressTime <= 8)
PLED = LEDTAB[PressTime];
else PLED = LEDTAB[8];
}
}
//======================
//按鍵掃描函數 【行掃描】
//低4位接行,高4位接列
/*鍵值分布
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
*/
//======================
uchar keyScan(void)
{
uchar hang;
uchar key;
uchar temp;
for(hang = 0;hang < 4;hang++)
{
PKEY = ~(1<<hang);
temp = PKEY&0xF0; //取高4位的值
temp >>= 4; //將高四位右移到低四位
if(temp != 0x0F) //有按鍵按下
{
switch(temp)
{
case 14: key = 4*hang+0;break; //temp:1110
case 13: key = 4*hang+1;break; //temp:1101
case 11: key = 4*hang+2;break; //temp:1011
case 7: key = 4*hang+3;break; //temp:0111
}
break; //有鍵按下,獲取鍵值后,終止掃描
}
else //沒有按鍵按下 返回255
key = 255;
}
return key;
}
//======================
//節拍延時
//======================
void delay125ms(uint pai) //延時 ?*125ms 即?個節拍
{
uchar a,b,c;
while(pai--)
{
for(c=239;c>0;c--)
for(b=104;b>0;b--)
for(a=1;a>0;a--);
}
}
//======================
//定時器0 產生音調
//======================
void Timer0_Init(void)
{
EA = 1;
ET0 = 1;
TMOD &= 0xF0;
TMOD |= 0x01;
PT0 = 1;
TH0 = 255;
TL0 = 255;
}
//======================
//定時器0中斷 每進入一次,SPK取反
//======================
void timer0() interrupt 1
{
TH0 = tone_h;
TL0 = tone_l;
SPK = ~SPK;
}
//======================
//存儲彈奏的歌曲
//0xffff代表歌曲結束
//千位與百位表示節拍
//十位:低中高音[分別是0,1,2]
//個位:音調[0~7] [0代表不發聲]
//======================
uint music[CODEMAX] =
{
215,215,215,215,413,412, //烏溜溜的黑眼珠
613,211,211,212,413,1206, //和你的笑臉
212,213,212,213,415,213,212, //怎么也難忘記
612,211,211,206,405,1213,110, //你 容顏的轉變
0xffff,
};
//====================================
//播放函數
//播放完畢后返回1,否則返回0
//music:歌曲數組,note:發第幾個音
//====================================
uchar PlayMusic(uint *music,uint note)
{
uchar yin1; //低中高音 0,1,2
uchar yin2; //音調 0~7 0代表不發聲,但有節拍
uchar jiepai;
if(music[note] == 0xffff)
return 1;
else
{
if(music[note]%10 != 0) //音調不為0 【音調為0時表示不發聲,但有節拍】
{
yin1 = music[note]%100/10;
yin2 = music[note]%10;
tone_h = TH0 = chuzhi[yin1][yin2*2 ]; //音調高位 【二維數組 第1維表示低中高音,第二維表示音調】
tone_l = TL0 = chuzhi[yin1][yin2*2 + 1]; //音調低位
TR0 = 1; //開啟定時器0 開始發聲
//======數碼管顯示音調==================
if(yin1 == 0) //低音
{ PSMG = YDTAB[yin2]; }
else if(yin1 == 1) //中音
{ PSMG = YDTAB[8+yin2];}
else if(yin1 ==2) //高音
{ PSMG = YDTAB[15+yin2];}
//==================================
}
else{ PSMG = YDTAB[8]; }
jiepai = music[note]/100;
//===此處利用定時器1中斷中的節拍顯示功能
t1_flag = 0;
PressTime = 0;
TH1 = (65536-25000)/256;
TL1 = (65536-25000)%256; //25ms中斷一次
TR1 = 1; //開啟定時器1
delay125ms(jiepai); //節拍
TR0 = 0; //已經響夠節拍數,停止發聲。
TR1 = 0; //停止顯示節拍
PSMG = YDTAB[0]; //數碼管不顯示
PLED = LEDTAB[0]; //8位LED全滅
delayms(30); //每個節拍結束后,停一段時間
return 0;
}
}
//======================
//主函數
//======================
void main(void)
{
uchar key = 255;
uchar save = 0;
uint note = 0; //音符
uchar note2 = 0;
uchar play_flag = 0;
uchar yin1 = 0; //低中高音 0,1,2
uchar yin2 = 1; //音調 0~7 0代表不發聲,但有節拍
uchar PlayID = 0; //播放歌曲的序號
uchar PlayIDb = 0; //上次播放的歌曲序號
music[CODEMAX-1] = 0xffff; //防止歌曲數組無0xffff出現錯誤
PSMG = YDTAB[0];
Timer0_Init();
Timer1_Init();
while(1)
{
if(PLAY == 0) //按下PLAY鍵
{
PLAY = 0; //引腳置0 進入播放模式
//切換了播放歌曲,從第0個音符開始播放,
if(PlayID != PlayIDb)
{
PlayIDb = PlayID;
note = 0;
}
//===============================================================
//==== 重點 =====
if(play_flag %2 == 0) //play_flag為偶數時播放,奇數時暫停播放
{
if(PlayID == 0)
{
if(PlayMusic(music,note) == 0) //播放音符
note++; //為結束播放下一個音符
else
{
if(PlayID < ALLSONG-1) PlayID++; //播放下一首
else PlayID = 0;
}
}
else if(PlayID == 1)
{
if(PlayMusic(srkl,note) == 0) //播放音符
note++; //為結束播放下一個音符
else
{
if(PlayID < ALLSONG-1) PlayID++; //播放下一首
else PlayID = 0;
}
}
else if(PlayID == 2)
{
if(PlayMusic(lq1990,note) == 0) //播放音符
note++; //為結束播放下一個音符
else
{
if(PlayID < ALLSONG-1) PlayID++; //播放下一首
else PlayID = 0;
}
}
}
//===================================================================
key = keyScan(); //要稍微按久一點才有反應
if(key == 15) //按下15號按鍵,停止播放
{
PLAY = 1;
note = 0; //停止后再按播放,從頭開始播放。
play_flag = 0;
TR0 = 0;
tone_h = TH0 = chuzhi[2][2*2];
tone_l = TL0 = chuzhi[2][2*2+1];
TR0 = 1;
delayms(100); //按鍵后響一聲
TR0 = 0;
while(keyScan() != 255); //放開按鍵時(255時) 跳出循環
}
else if(key == 13) //按下13號鍵 暫停與暫停后播放
{
play_flag++;
TR0 = 0;
tone_h = TH0 = chuzhi[2][2*2];
tone_l = TL0 = chuzhi[2][2*2+1];
TR0 = 1;
delayms(100); //開始或者暫停都響一聲
TR0 = 0;
while(keyScan() != 255); //放開按鍵時(255時) 跳出循環
}
else if(key == 12) //播放上一首
{
if(PlayID > 0) PlayID--;
else PlayID = ALLSONG-1;
TR0 = 0;
tone_h = TH0 = chuzhi[2][2*2];
tone_l = TL0 = chuzhi[2][2*2+1];
TR0 = 1;
delayms(100); //按鍵后響一聲
TR0 = 0;
while(keyScan() != 255); //放開按鍵時(255時) 跳出循環
}
else if(key == 14) //播放下一首
{
if(PlayID < ALLSONG-1) PlayID++;
else PlayID = 0;
TR0 = 0;
tone_h = TH0 = chuzhi[2][2*2];
tone_l = TL0 = chuzhi[2][2*2+1];
TR0 = 1;
delayms(100); //按鍵后響一聲
TR0 = 0;
while(keyScan() != 255); //放開按鍵時(255時) 跳出循環
}
}
else if(PLAY == 1) //彈奏模式
{
PlayID = 0;
note = 0;
key = keyScan();
if(key == 0) //按下0鍵開始記錄
{
if(save == 0) //第一次按 表示開始彈奏
{
save = 1; //標記,存儲
note2 = 0;
tone_h = TH0 = chuzhi[0][1*2];
tone_l = TL0 = chuzhi[0][1*2+1];
TR0 = 1;
delayms(100); //開始錄制 響一短低音
TR0 = 0;
}
else //第二次按 表示彈奏結束 寫入結束符0xffff
{
save = 0;
music[note2] = 0xffff;
tone_h = TH0 = chuzhi[1][3*2];
tone_l = TL0 = chuzhi[1][3*2+1];
TR0 = 1;
delayms(100); //錄制完成 響一短高音
TR0 = 0;
}
while(keyScan() != 255); //放開按鍵時(255時) 跳出循環
}
else if(key != 255) //按下1~15鍵
{
t1_flag = 0;
PressTime = 0;
TH1 = (65536-25000)/256;
TL1 = (65536-25000)%256; //25ms中斷一次
TR1 = 1; //開啟定時器1,開始計算按鍵按下時間
//判斷被按下按鍵的鍵值
if(key >= 1 && key <= 3) //低音 5~7
{ yin1 = 0; yin2 = key+4; } //音調對應的定時器初值,在二維數組中的位置
else if(key >= 4 && key <= 11) //0音 與中音1~7
{ yin1 = 1; yin2 = key - 4; }
else if(key >= 12 && key <= 15) //高音1~4
{ yin1 = 2; yin2 = key - 11; }
tone_h = TH0 = chuzhi[yin1][yin2*2]; //音調高位 【二維數組 第1維表示低中高音,第二維表示音調】
tone_l = TL0 = chuzhi[yin1][yin2*2+1]; //音調低位
if(yin2 != 0) //非0音時,開啟定時器0,發聲
TR0 = 1;
//======數碼管顯示音調==================
if(yin2 == 0) //0音
PSMG = YDTAB[8];
else if(yin1 == 0) //低音
{ PSMG = YDTAB[yin2]; }
else if(yin1 == 1) //中音
{ PSMG = YDTAB[8+yin2];}
else if(yin1 ==2) //高音
{ PSMG = YDTAB[15+yin2];}
//==================================
while(1) //釋放按鍵時 跳出循環
{
key = keyScan();
if(key == 255) //放開按鍵
{
PSMG = YDTAB[0];
PLED = LEDTAB[0];
TR1 = 0;
TR0 = 0; //停止發聲
if(save == 1) //save變量為1時,將彈奏的信息保存
{
TR1 = 0; //關閉定時器1,停止
music[note2] = (uint)PressTime*100 + yin1*10 + yin2;
if(note2 < CODEMAX - 2) //長度有限制
note2++;
}
break;
}
}
}
}
}
}
//===================================
//單片機STC89C52RC
//晶振12MHz
//最后編輯2016/7/3
//僅供學習交流,不得用于商業用途,版權歸 李資鵬 所有
//===================================
復制代碼
歡迎光臨 (http://www.denmoz.com/bbs/)
Powered by Discuz! X3.1