找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 8571|回復: 4
打印 上一主題 下一主題
收起左側

51單片機超級電子琴(C語言)

[復制鏈接]
跳轉到指定樓層
樓主
ID:51707 發(fā)表于 2013-7-11 02:37 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
/*說明:此程序是用矩陣按鍵和音樂實驗組合而成的,先是寫出矩陣鍵盤程序,得出鍵值。然后通過判斷鍵值而分配各種音符,從而得到電子琴效果!硬件連接!
硬鍵連接: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ā)聲
}
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂1 踩
回復

使用道具 舉報

沙發(fā)
ID:64089 發(fā)表于 2015-12-28 10:00 | 只看該作者
嗨,樓主這么好的帖子竟然沒人頂,我支持一下。
回復

使用道具 舉報

板凳
ID:79544 發(fā)表于 2015-12-28 13:20 | 只看該作者
不知道好用不好用先頂
回復

使用道具 舉報

地板
ID:121189 發(fā)表于 2016-5-16 15:56 | 只看該作者
為啥沒電路圖
回復

使用道具 舉報

5#
ID:69481 發(fā)表于 2016-12-13 10:31 | 只看該作者
不錯,好東西
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表