/*說明:此程序是用矩陣按鍵和音樂實驗組合而成的,先是寫出矩陣鍵盤程序,得出鍵值。然后通過判斷鍵值而分配各種音符,從而得到電子琴效果!硬件連接!
硬鍵連接:P1口接矩陣鍵盤,P3.5接蜂鳴器引腳*/
#include <reg52.h>//頭文件
#define uint unsigned int//宏定義
#define uchar unsigned char//宏定義
void delay(uchar);//延時子函數(shù)聲明
void bbtt (uchar);//聲音處理子函數(shù)聲明
void pan();//按鍵子函數(shù)聲明
uint code table[]={
0xfd,0x12,0xfd,0x80, 0xfd,0xc6, 0xfe,0x07,0xfe,0x25,0xfe,0x57,
0xfe,0x84,0xfe,0x98,0xfe,0xc0,0xfe,0xe3,0xff,0x01, 0xff,0x10, 0xff,0x29,0xff,0x42
};/*音符代碼 低音3,低音5,低音6,低音7,中音1,中音2,中音3,中音4,中音5,中音6,
中音7,高音1,高音2,高音3,基中一個音用兩個數(shù)表示。*/
sbit bbt=P3^5;//定義蜂鳴器引腳為P3.5腳。
uchar num,lui,a,temp,num1,num2,numm,aa,bb;//定義行變量
void main()//主程序開始
{
TMOD=01;//設置定時器工作在方式0下
IE=0X82;//開總中斷與中斷允許
num=17;//定義初值,開機使它不亮
while(1)
{
pan();//按鍵識別子函數(shù)
TR0=0;//將定時器關掉
/
bbt=1;//將蜂鳴器關掉
//
/*將各按鍵得出鍵值碼,也就是讓每個鍵得到相應的音符*/
if(num!=17)//判斷num是否不等于17,不等就執(zhí)行以下語句,否則跳過
{
switch(num)//執(zhí)行開關語句
{
case 0://0x00與num值是否相等?
{
TR0=1;//打開定時器
bbtt (0);//調用聲音處理子函數(shù),并賦值0
num=17;// 將num值裝回,使按鍵按下時只響一聲
}
break;//返回開關語句
/////////////////////////////////////////////////////////////////
case 1://0x01與num值是否相等?
{
TR0=1;//打開定時器
bbtt (2);//調用聲音處理子函數(shù),并賦值2
num=17;// 將num值裝回,使按鍵按下時只響一聲
}
break;//返回
//////////////////////////////////////////////////////////////////
case 2://0x08與num值是否相等?
{
TR0=1;//打開定時器
bbtt (4); //調用聲音處理子函數(shù),并賦值4
num=17;// 將num值裝回,使按鍵按下時只響一聲
}
break;//返回
//////////////////////////////////////////////////////////////////
case 3://0x00與num值是否相等?
{
TR0=1;//打開定時器
bbtt (6);//調用聲音處理子函數(shù),并賦值6
num=17;// 將num值裝回,使按鍵按下時只響一聲
}
break;//返回繼續(xù)判斷是否有鍵按下
/////////////////////////////////////////////////////////////////
case 4://0x04與num值是否相等?
{
TR0=1;//打開定時器
bbtt (8);//調用聲音處理子函數(shù),并賦值8
num=17;// 將num值裝回,使按鍵按下時只響一聲
}
break;//返回
//////////////////////////////////////////////////////////////////
case 5://0x08與num值是否相等?
{
TR0=1;//打開定時器
bbtt (10);//調用聲音處理子函數(shù),并賦值10
num=17;// 將num值裝回,使按鍵按下時只響一聲
}
break;//返回
case 6://0x00與num值是否相等?
{
TR0=1;//打開定時器
bbtt (12);//調用聲音處理子函數(shù),并賦值12
num=17;// 將num值裝回,使按鍵按下時只響一聲
}
break;//返回繼續(xù)判斷是否有鍵按下
/////////////////////////////////////////////////////////////////
case 7://0x04與num值是否相等?
{
TR0=1;//打開定時器
bbtt (14);//調用聲音處理子函數(shù),并賦值14
num=17;// 將num值裝回,使按鍵按下時只響一聲
}
break;//返回
case 8://0x08與num值是否相等?
{
TR0=1;//打開定時器
bbtt (16);//調用聲音處理子函數(shù),并賦值16
num=17;// 將num值裝回,使按鍵按下時只響一聲
}
break;//返回
//////////////////////////////////////////////////////////////////
case 9://0x00與num值是否相等?
{
TR0=1;//打開定時器
bbtt (18);//調用聲音處理子函數(shù),并賦值18
num=17;// 將num值裝回,使按鍵按下時只響一聲
}
break;//返回繼續(xù)判斷是否有鍵按下
/////////////////////////////////////////////////////////////////
case 10://0x04與num值是否相等?
{
TR0=1;//打開定時器
bbtt (20);//調用聲音處理子函數(shù),并賦值20
num=17;// 將num值裝回,使按鍵按下時只響一聲
}
break;//返回
//////////////////////////////////////////////////////////////////
case 11://0x08與num值是否相等?
{
TR0=1;//打開定時器
bbtt (22);//調用聲音處理子函數(shù),并賦值22
num=17;// 將num值裝回,使按鍵按下時只響一聲
}
break;//返回
case 12://0x00與num值是否相等?
{
TR0=1;//打開定時器
bbtt (24);//調用聲音處理子函數(shù),并賦值24
num=17;// 將num值裝回,使按鍵按下時只響一聲
}
break;//返回繼續(xù)判斷是否有鍵按下
/////////////////////////////////////////////////////////////////
case 13://0x04與num值是否相等?
{
TR0=1;//打開定時器
bbtt (26); //調用聲音處理子函數(shù),并賦值26
num=17; // 將num值裝回,使按鍵按下時只響一聲
}
break;//返回
}
}
}
}
/*矩陣鍵盤掃描程序*/
void pan()
{
///////////////////////////////////掃第一行
P1=0xfe;//先掃第一行
temp=P1;//將它值給temp
temp=temp&0xf0;//與門比較
if(temp!=0xf0)//如果它不等于0xf0,就執(zhí)行括號語句
{
delay(100);//延時
temp=P1;//再賦值
temp=temp&0xf0;//再與門比較
if(temp!=0xf0)//再判斷是否為不等于0xf0?如果確實不等則說明有鍵按下
{
temp=P1;//將值重新給temp,以便下次再判斷!否則找不到合適值
switch(temp)//判斷出了第一行有鍵按下了,還要判斷具體哪個鍵
{
case 0xee:num=0;//0xee和temp比較,如果相等就將它編碼定義為0
break;//確定了就跳出switch語句
case 0xde:num=1;//0xde和temp比較,如果相等就將它編碼定義為1
break;//確定了就跳出switch語句
case 0xbe:num=2;//0xbe和temp比較,如果相等就將它編碼定義為2
break;//確定了就跳出switch語句
case 0x7e:num=3;//0x7e和temp比較,如果相等就將它編碼定義為3
break;//確定了就跳出switch語句
}
if(temp!=0xf0)//按鍵識放判斷,如果不等于0xf0就一直執(zhí)行括號語句
{
temp=P1;//重新賦值
temp=temp&0xf0;//重新與門
}
}
}
///////////////////////////////////掃第二行
P1=0xfd;
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(100);
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xed:num=4;
break;
case 0xdd:num=5;
break;
case 0xbd:num=6;
break;
case 0x7d:num=7;
break;
}
if(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
}
}
/////////////////////////////////////掃第三行
P1=0xfb;
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(100);
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xeb:num=8;
break;
case 0xdb:num=9;
break;
case 0xbb:num=10;
break;
case 0x7b:num=11;
break;
}
if(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
}
}
////////////////////////////////////////掃第四行
P1=0xf7;
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(100);
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xe7:num=12;
break;
case 0xd7:num=13;
break;
case 0xb7:num=14;
break;
case 0x77:num=15;
break;
}
if(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
}
}
}
}
void delay(uchar z)//延時函數(shù)
{
uchar x,y;
for(x=100;x>0;x--)
for(y=z;y>0;y--);
}
/*掃描得到音樂代碼,賦值給定時器*/
void bbtt (uchar aa)
{
numm=table[aa];//得到音樂碼高位
aa++;//將計數(shù)器加1,以便取下一個代碼
num1=table[aa];//得到音樂碼低位
TH0=numm;//將高位賦值
TL0=num1;//將低位賦值
}
/*中斷服務子程序*/
void zhong() interrupt 1
{
TH0=numm;//將高位賦值
TL0=num1;//將低位賦值
bbt=~bbt;//將蜂鳴器取反發(fā)聲
}
|