⑴ 基於51單片機的電子琴,用中斷實現
可以在賦值後設置一個標志, 如果標志沒有被清零, 就不再賦值, 如果中斷產生了, 清除標志
⑵ 跪求一個51單片機開發板的電子琴程序
電子琴程序
信號發生器設計報告
電子琴程序
2009-08-30 13:47:34| 分類: 默認分類
| 標簽: |舉報 |字型大小大中小 訂閱
電子琴程序發送部分:
/*
本程序是用AD9851的DDS模塊做的電子琴,
電子琴的音符完整,共21個按鍵,分別是低1--7,中1--7,高1--7。本程序為雙機通信的發送部分,可以顯示頻率
*/
#include <REG51.H> //
單片機內部專用寄存器定義
/**************************************/
sbit K1= P1^0; //
鍵K1輸入引腳定義
sbit K2= P1^1; // 鍵K2輸入引腳定義
sbit K3= P1^2; //
鍵K3輸入引腳定義
sbit K4= P1^3; // 鍵K4輸入引腳定義
sbit K5= P1^4; //
鍵K5輸入引腳定義
sbit K6= P1^5; // 鍵K6輸入引腳定義
sbit K7= P1^6; //
鍵K7輸入引腳定義
sbit K8= P1^7; //
鍵K15輸入引腳定義
/**************************************/
sbit K9= P2^0; //
鍵K8輸入引腳定義
sbit K10= P2^1; // 鍵K9輸入引腳定義
sbit K11= P2^2; //
鍵K10輸入引腳定義
sbit K12= P2^3; // 鍵K11輸入引腳定義
sbit K13= P2^4; //
鍵K12輸入引腳定義
sbit K14= P2^5; // 鍵K13輸入引腳定義
sbit K15= P2^6; //
鍵K14輸入引腳定義
sbit K16= P2^7; //
鍵K16輸入引腳定義
/**************************************/
sbit K17= P3^2; //
鍵K17輸入引腳定義
sbit K18= P3^3; // 鍵K18輸入引腳定義
sbit K19= P3^4; //
鍵K19輸入引腳定義
sbit K20= P3^5; // 鍵K20輸入引腳定義
sbit K21= P3^7; // 鍵K21輸入引腳定義
/******************延時程序********************/
void delay(unsigned int
k)
{
unsigned int i,j;
for(i=0;i<k;i++){
for(j=0;j<121;j++)
{;}}
}
/*****************串口初始化程序*****************/
void
init
(void)
{
TMOD=0x20;
TH1=0xfd;
TL1=0xfd;
SCON=0x50;
TR1=1;
}
/*****************串口發送程序*****************/
void chuan(shu)
{
SBUF=shu;
TI=0;
}
/******************主程序********************/
void main(void)
{
init();
while(1)
{
if(K1==0) chuan(1);
else if(K2==0)
chuan(2);
else if(K3==0) chuan(3);
else if(K4==0) chuan(4);
else
if(K5==0) chuan(5);
else if(K6==0) chuan(6);
else if(K7==0)
chuan(7);
else if(K8==0) chuan(8);
else if(K9==0) chuan(9);
else
if(K10==0) chuan(10);
else if(K11==0) chuan(11);
else if(K12==0)
chuan(12);
else if(K13==0) chuan(13);
else if(K13==0)
chuan(13);
else if(K14==0) chuan(14);
else if(K15==0)
chuan(15);
else if(K16==0) chuan(16);
else if(K17==0)
chuan(17);
else if(K18==0) chuan(18);
else if(K19==0)
chuan(19);
else if(K20==0) chuan(20);
else if(K21==0)
chuan(21);
else chuan(0);
}
}
電子琴接收部分:
/*
本程序是用AD9851的DDS模塊做的電子琴,
電子琴的音符完整,共21個音符,分別是低1--7,中1--7,高1--7。本程序為雙機通信的接受部分。有直接演奏方式,錄音演奏方式,錄音後放音方式
,可以顯示頻率 */
#include <STC12C5410AD.H>
#include<intrins.h>
#include <stdio.h> /* prototype
declarations for I/O functions */
#define uchar unsigned char
#define uint unsigned int
sbit
E_CLK =P2^6;//clock input 同步時鍾輸入端
sbit RW_SID
=P2^5;//data input/output 串列數據輸入、輸出端
sbit RS_DI
=P2^4; // 4號腳 jichunqi input
sbit DataIn_AD9851=P2^3;
//控制子串傳送位
sbit DDS_CLK=P2^2; //接外部晶振時鍾 這里為30M
sbit
DDS_FQUD=P2^1; //更新發送頻率
sbit RST_AD9851= P2^0; //復位
unsigned char Control_AD9851 = 0x01; // Phase0 ,power on mode and 6 REFCLK
Multiplier enable
/* T0_int 定時 時間常數 5ms=5000=1388H->EC78H f=12MH */
#define
time_5ms_H 0xC2 /* 定時時間為1/64s */
#define time_5ms_L 0xF7
char shu, bb;
unsigned char p=0;
unsigned char
point=0;
unsigned char recode_n=0;
unsigned char xdata
array[50]={0};
unsigned int xdata arrayt[50]={0};
float const
ton[]={0.00,261.63,293.67,329.63,349.23,391.99,440.00,494.00,
523.25,587.33,659.25,698.46,783.99,880.00,987.76,
1046.50,1174.66,1381.51,1396.92,1567.98,1760.00,1975.52};
unsigned int ttt,
nnn;
unsigned char mode=0;
sbit KEY_rec =P3^5;
sbit KEY_play=P3^7;
/*************************延時程序***************************/
void
delay(uint k)
{
uint i,j;
for(i=0;i<k;i++)
{for(j=0;j<121;j++)
{;}}
}
/*************************串列發送一位元組數據***************************/
void SendByte(unsigned char dat)
{
unsigned
char i;
RS_DI=1;
for(i=0;i<8;i++)
{
E_CLK=0;
if(dat&0x80)RW_SID=1;
else RW_SID=0;
E_CLK=1;
dat=dat<<1;
}
}
/*************************寫控制命令***************************/
void
SendCMD(unsigned char dat)
{
SendByte(0xF8);//11111,00,0
RW=0,RS=0 同步標志
SendByte(dat&0xF0);//高四位
SendByte((dat&0x0F)<<4);//低四位
}
/************************寫顯示數據或單位元組字元 ****************************/
void SendDat(unsigned char dat)
{
SendByte(0xFA);//11111,01,0 RW=0,RS=1
SendByte(dat&0xF0);//高四位
SendByte((dat&0x0F)<<4);//低四位
}
/************************顯示字元串****************************/
void
hzkdis(unsigned char code *s)
{ while(*s>0)
{
SendDat(*s);
s++;
delay(5);
}
}
/************************顯示數據子程序****************************/
void
Display(unsigned char x_add,unsigned long date,unsigned char dot)
{
unsigned char date0,date1,date2,date3,date4,date5;//;
date5=(date%1000000)/100000;
date4=(date%100000)/10000;
date3=(date%10000)/1000;
date2=(date%1000)/100;
date1=(date%100)/10;
date0=date%10;
SendCMD(x_add);
if(dot==0x02) //100---9999.99
{
SendDat(0x30+date5);
SendDat(0x30+date4);
SendDat(0x30+date3);
SendDat(0x30+date2);
SendDat(0x2e);
SendDat(0x30+date1);
SendDat(0x30+date0);
SendDat(0x48);
SendDat(0x7a);
}
}
/*************************設置AD9851頻率***************************/
void
SentFreq(unsigned long int freq)
{
unsigned char i=0;
unsigned int
temp;
DDS_FQUD=0;
for(i=0;i<32;i++) //串口數據
輸入頻率控制字
{
DDS_CLK =
0;
temp=((freq>>i)&1);
DataIn_AD9851 = temp;
DDS_CLK =
1;
}
for(i=0;i<8;i++) //phase-b4 ph-b3 ph-b2 ph-b1 ph-b0 Power-down
Logic0* 6*REFCLK Multiplier_En
{
DDS_CLK = 0;
temp=((Control_AD9851>>i)&1);
DataIn_AD9851 = temp;
DDS_CLK = 1;
}
DDS_CLK = 0;
DDS_FQUD = 1;
DDS_FQUD =
0;
}
/**************************換算頻率,並輸出***********************/
void
Set_Freq(float Freqency)
{unsigned long int freq_temp;
freq_temp=
(unsigned long int)(23.861*Freqency); // SYSCLK = 180 MHz
2^32/180000000=23.861
SentFreq(freq_temp);
}
/*************************T0作定時器,T1作波特率發生器,初始化*************************/
void
init (void)
{
TMOD= 0x01; /* 0001$0001 T1 & T0 are 16bit
timers */
TH0 = time_5ms_H; /* T0 timer 5ms */
TL0 =
time_5ms_L;
/* TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0 */
TCON= 0x10; /* 0 0 0 1 0 0 0 0 */
/* start T0 xint1 xint0 */
IE= 0x82; /* 1000 0010,
EA=ET0=1,
*/
TMOD=0x20;
TH1=0xfd;
TL1=0xfd;
TR1=1;
SCON=0x50;
ES=1;
EA=1;
}
/*************************設置AD9851初始化*************************/
void
AD9851Init(void) //DDS初始化函數,包括DDS復位和初始化為串列發送
{
DDS_CLK=0;
DDS_FQUD=0;
RST_AD9851=0;
RST_AD9851=1;//復位AD9851
RST_AD9851=1;
RST_AD9851=1;
RST_AD9851=0;
DDS_CLK=1;
DDS_CLK=0;
DDS_FQUD=1;
DDS_FQUD=0;
}
/**************************初始化LCM
**************************/
void initlcm(void)
{
delay(100);
SendCMD(0x30);//功能設置,一次送8位數據,基本指令集
SendCMD(0x0C);//0000,1100 整體顯示,游標off,游標位置off
SendCMD(0x14);
SendCMD(0x01);//0000,0001 清DDRAM 即清屏
SendCMD(0x02);//0000,0010 DDRAM地址歸位
SendCMD(0x80);//1000,0000
設定DDRAM 7位地址000,0000到地址計數器AC
//SendCMD(0xb8|page);翻頁
}
/**********************主程序******************************/
void
main(void)
{
uchar t;
init();
AD9851Init();
initlcm(); //12864初始化程序
shu=0;
bb=255;
while(1)
{
switch(mode)
{
case 0: //
演奏方式
SendCMD(0x80);//第一行(如果是地址是:80H,即LCD的第一行的第一個位置顯示)
hzkdis("
音樂播放頻率:");
if (shu!=bb)
{
Set_Freq(ton[shu]);
Display(0x93,(unsigned
long)100*ton[shu],0x02);
bb=shu;
}
if
(KEY_rec==0)
{
mode=1;
point=0;
recode_n=0;
shu=0;
bb=255;
nnn=0;
}
else if (KEY_play==0)
{
mode=2;
p=1;
}
break;
case
1: // 錄音方式
// SendCMD(0x01);//0000,0001 清DDRAM 即清屏
//
delay(10);
SendCMD(0x80);//第一行(如果是地址是:80H,即LCD的第一行的第一個位置顯示)
hzkdis("
音樂錄制頻率:");
if (shu!=bb)
{
arrayt[point]=nnn; // 記錄上一音階時間
Set_Freq(ton[shu]);
Display(0x93,(unsigned long)100*ton[shu],0x02);
nnn=0;
bb=shu;
recode_n++;
}
if ((recode_n>=50) || (KEY_play==0))
//停止錄音
{
Set_Freq(0.0);
p=0;
mode=0;
shu=0;
bb=20;
}
break;
case 2: //
放音方式
SendCMD(0x80);//第一行(如果是地址是:80H,即LCD的第一行的第一個位置顯示)
hzkdis("
音樂重播頻率:");
for(t=0;t< recode_n;t++)
{
Set_Freq(ton[array[p]]);
Display(0x93,(unsigned
long)*ton[array[p]],0x02);
ttt=arrayt[p];
while
(ttt);
delay(100);
p++;
}
if
(p>recode_n)
{
Set_Freq(0.0);
p=0;
mode=0;
shu=0;
bb=20;
}
break;
}
}
}
//*==================================*/
/* 串口中斷接收
*/
/*==================================*/
void s_receive() interrupt 4
//串列中斷
{
if(RI==1) //接收中斷標志位
{
RI=0; //中斷標志清零
shu=SBUF; //RXData賦值
}
else
TI=0;
}
⑶ 電子琴要同時發出兩個甚至更多的音符,用51單片機怎麼做
這玩意兩種實現方式吧。
一種簡單點。
你本來就是通過頻率驅動喇叭, 那你乾脆驅動3個喇叭算了,發幾個音就驅動幾個。如果是3個和音,那就同時驅動三個。雖然傻逼,但是這個很簡單,很容易做。
另外復雜點就是,你首先要能分析出來這三個音的和音的構成。由於是喇叭驅動的。所以音色可以不考慮,
那麼就是音調,頻率的事兒了。 這個在不同的頻域上,混合疊加。產生新的波形。如果你能算出這個波形,ok,你可以合成這個
⑷ 用51單片機 製作簡易電子琴 的兩個問題
內部大循環只要把掃描程序等需要不停執行的程序寫在
while(1)
{
。。。。。。(這里)
}
識別按鍵只要與按鍵相連的引腳檢測到低電平即可
給你一個按鍵範例:
假如按鍵接到單片機P2^0引腳
sbit K = P2^0;
if(K == 0)
{
delay(5); //延時去抖
if(K == 0) //確定鍵按下
{
while(!K); //判斷鬆手
。。。。。(功能函數)
}
}
⑸ 單片機簡易電子琴程序
22. 電子琴
1. 實驗任務
(1. 由4X4組成16個按鈕矩陣,設計成16個音。
(2. 可隨意彈奏想要表達的音樂。
2. 電路原理圖
圖4.22.1
3. 系統板硬體連線
(1. 把「單片機系統」區域中的P1.0埠用導線連接到「音頻放大模塊」區域中的SPK IN埠上;
(2. 把「單片機系統「區域中的P3.0-P3.7埠用8芯排線連接到「4X4行列式鍵盤」區域中的C1-C4 R1-R4埠上;
4. 相關程序內容
(1. 4X4行列式鍵盤識別;
(2. 音樂產生的方法;
一首音樂是許多不同的音階組成的,而每個音階對應著不同的頻率,這樣我們就可以利用不同的頻率的組合,即可構成我們所想要的音樂了,當然對於單片機來產生不同的頻率非常方便,我們可以利用單片機的定時/計數器T0來產生這樣方波頻率信號,因此,我們只要把一首歌曲的音階對應頻率關系弄正確即可。現在以單片機12MHZ晶振為例,例出高中低音符與單片機計數T0相關的計數值如下表所示
音符 頻率(HZ) 簡譜碼(T值) 音符 頻率(HZ) 簡譜碼(T值)
低1 DO 262 63628 # 4 FA# 740 64860
#1 DO# 277 63731 中 5 SO 784 64898
低2 RE 294 63835 # 5 SO# 831 64934
#2 RE# 311 63928 中 6 LA 880 64968
低 3 M 330 64021 # 6 932 64994
低 4 FA 349 64103 中 7 SI 988 65030
# 4 FA# 370 64185 高 1 DO 1046 65058
低 5 SO 392 64260 # 1 DO# 1109 65085
# 5 SO# 415 64331 高 2 RE 1175 65110
低 6 LA 440 64400 # 2 RE# 1245 65134
# 6 466 64463 高 3 M 1318 65157
低 7 SI 494 64524 高 4 FA 1397 65178
中 1 DO 523 64580 # 4 FA# 1480 65198
# 1 DO# 554 64633 高 5 SO 1568 65217
中 2 RE 587 64684 # 5 SO# 1661 65235
# 2 RE# 622 64732 高 6 LA 1760 65252
中 3 M 659 64777 # 6 1865 65268
中 4 FA 698 64820 高 7 SI 1967 65283
下面我們要為這個音符建立一個表格,有助於單片機通過查表的方式來獲得相應的數據
低音0-19之間,中音在20-39之間,高音在40-59之間
TABLE: DW 0,63628,63835,64021,64103,64260,64400,64524,0,0
DW 0,63731,63928,0,64185,64331,64463,0,0,0
DW 0,64580,64684,64777,64820,64898,64968,65030,0,0
DW 0,64633,64732,0,64860,64934,64994,0,0,0
DW 0,65058,65110,65157,65178,65217,65252,65283,0,0
DW 0,65085,65134,0,65198,65235,65268,0,0,0
DW 0
2、音樂的音拍,一個節拍為單位(C調)
曲調值 DELAY 曲調值 DELAY
調4/4 125ms 調4/4 62ms
調3/4 187ms 調3/4 94ms
調2/4 250ms 調2/4 125ms
對於不同的曲調我們也可以用單片機的另外一個定時/計數器來完成。
下面就用AT89S51單片機產生一首「生日快樂」歌曲來說明單片機如何產生的。
在這個程序中用到了兩個定時/計數器來完成的。其中T0用來產生音符頻率,T1用來產生音拍。
5. 程序框圖
貼不了.
7. C語言源程序
#include <AT89X51.H>
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
unsigned char temp;
unsigned char key;
unsigned char i,j;
unsigned char STH0;
unsigned char STL0;
unsigned int code tab[]={64021,64103,64260,64400,
64524,64580,64684,64777,
64820,64898,64968,65030,
65058,65110,65157,65178};
void main(void)
{
TMOD=0x01;
ET0=1;
EA=1;
while(1)
{
P3=0xff;
P3_4=0;
temp=P3;
temp=temp & 0x0f;
if (temp!=0x0f)
{
for(i=50;i>0;i--)
for(j=200;j>0;j--);
temp=P3;
temp=temp & 0x0f;
if (temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
switch(temp)
{
case 0x0e:
key=0;
break;
case 0x0d:
key=1;
break;
case 0x0b:
key=2;
break;
case 0x07:
key=3;
break;
}
temp=P3;
P1_0=~P1_0;
P0=table[key];
STH0=tab[key]/256;
STL0=tab[key]%256;
TR0=1;
temp=temp & 0x0f;
while(temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
}
TR0=0;
}
}
P3=0xff;
P3_5=0;
temp=P3;
temp=temp & 0x0f;
if (temp!=0x0f)
{
for(i=50;i>0;i--)
for(j=200;j>0;j--);
temp=P3;
temp=temp & 0x0f;
if (temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
switch(temp)
{
case 0x0e:
key=4;
break;
case 0x0d:
key=5;
break;
case 0x0b:
key=6;
break;
case 0x07:
key=7;
break;
}
temp=P3;
P1_0=~P1_0;
P0=table[key];
STH0=tab[key]/256;
STL0=tab[key]%256;
TR0=1;
temp=temp & 0x0f;
while(temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
}
TR0=0;
}
}
P3=0xff;
P3_6=0;
temp=P3;
temp=temp & 0x0f;
if (temp!=0x0f)
{
for(i=50;i>0;i--)
for(j=200;j>0;j--);
temp=P3;
temp=temp & 0x0f;
if (temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
switch(temp)
{
case 0x0e:
key=8;
break;
case 0x0d:
key=9;
break;
case 0x0b:
key=10;
break;
case 0x07:
key=11;
break;
}
temp=P3;
P1_0=~P1_0;
P0=table[key];
STH0=tab[key]/256;
STL0=tab[key]%256;
TR0=1;
temp=temp & 0x0f;
while(temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
}
TR0=0;
}
}
P3=0xff;
P3_7=0;
temp=P3;
temp=temp & 0x0f;
if (temp!=0x0f)
{
for(i=50;i>0;i--)
for(j=200;j>0;j--);
temp=P3;
temp=temp & 0x0f;
if (temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
switch(temp)
{
case 0x0e:
key=12;
break;
case 0x0d:
key=13;
break;
case 0x0b:
key=14;
break;
case 0x07:
key=15;
break;
}
temp=P3;
P1_0=~P1_0;
P0=table[key];
STH0=tab[key]/256;
STL0=tab[key]%256;
TR0=1;
temp=temp & 0x0f;
while(temp!=0x0f)
{
temp=P3;
temp=temp & 0x0f;
}
TR0=0;
}
}
}
}
void t0(void) interrupt 1 using 0
{
TH0=STH0;
TL0=STL0;
P1_0=~P1_0;
}
根據自己的情況稍微改改就好了
⑹ 單片機電子琴代碼
;電子琴
;P2口外接4*4鍵盤
ORG 0000H ;主程序起始
LJMP MAIN ;跳到MAIN主程序
ORG 000BH ;T0中斷起始
LJMP TT0 ;跳到T0中斷
MAIN:MOV TMOD,#01H ;設T0工作在方式1
MOV IE,#82H ;中斷使能
SETB TR0 ;啟動T0
W1:LCALL KEY ;調用KEY,是否有鍵盤按下
CLR EA ;中斷屏蔽
JB F0,W1 ;沒有按則F0=1,否則F0=1
MOV A,22H ;按下則取碼指針存址
RL A ;乘2
MOV DPTR,#TABLE ;
MOVC A,@A+DPTR ;至TABLE取碼,取T
MOV TH0,A ;取到的高位位元組存入TH
MOV 21H,A ;取到的高位位元組存入21H
MOV A,22H ;再載入取到的音符碼
RL A ;乘2
INC A ;加1
MOVC A,@A+DPTR ;至TABLE1取低位數值
MOV TL0,A ;取到的低位位元組存入TL0
MOV 20H,A ;取到的低位位元組存入20H
W2:LCALL KEY ;調用KEY,是否有鍵按下
SETB EA ;中斷使能
JB F0,W1 ;有按下否?
JMP W2 ;有則跳到W2
KEY:SETB F0 ;設F0=1
MOV R3,#0F7H;掃描初值P23=0
MOV R1,#00H ;取碼指針初值
W3:MOV A,R3 ;載入掃描指針
MOV P2,A ;輸出至P2,掃描P23-P20
MOV A,P2 ;讀入P2
CLR C ;
CPL C ;令C=1
MOV R5,#04H ;檢測(P27-P24)
W4:RLC A ;右移一位(P27-P24)
JNC KEYIN ;檢測行C=0,表按下
INC R1 ;沒被按下則取碼指針加1
DJNZ R5,W4 ;4列檢測完畢了?
MOV A,R3 ;載入掃描指針
CLR C ;
CPL C ;令C=1
RRC A ;掃下一行,即下行為0
MOV R3,A ;存回R3掃描指針寄存器
JC W3 ;C=0表掃完
RET ;
KEYIN:MOV 22H,R1 ;取碼指針存入22H地址
CLR F0 ;令F0=0
RET
TT0:PUSH ACC ;將A值存入堆棧
PUSH PSW ;將PSW值存入堆棧
MOV TL0,20H ;重新設計計數器
MOV TH0,21H ;
CPL P1.0 ;將P1.0反相
POP PSW ;至堆棧取回PSW值
POP ACC ;至堆棧取回A值
RETI ;返回主程序
TABLE:DW 64021,64103,64260,64400 ;.3
DW 64524,64580,64684,64777 ;.7
DW 64820,64898,64968,65030 ;4
DW 65058,65110,65157,65178 ;1.
⑺ 51單片機設計電子琴課程設計
http://code.21ic.com/code/31218
實現電子琴的功能,基於C51,通過7個按鍵,來發出7種音調,也可以做成水果鍵盤
21ic中國電子網站上有很多電子琴的源碼,你可以去搜索一下。。
⑻ 在51單片機上用C語言實現電子琴功能,但同時數碼管可以顯示簡譜,怎麼編程序
1,數據管顯示就沒什麼了,找幾個簡單的數碼管驅動程序改改就可以了,一般都是先選中數碼管,然後設置值,就可以顯示了,不過需要注意刷新,10ms刷新一個應該就可以了,刷新頻率比較低的話會閃閃的,這個你應該明白。
2,蜂鳴器發do音,這個硬體實現我就不知道了,也許有硬體可以 編碼控制自動生成對應頻率的值。我想如果通過軟體實現的話,不妨考慮一下定時器。假設do音是1000Hz的頻率(沒有查,不清楚,假設的),那麼你可以控制定時器的觸發頻率為1000hz,觸發一次,對應的輸出到蜂鳴器的口的電平跳變一下,如果定時器的頻率為1000hz的話,那麼應該有500hz的頻率,一個周期需要一高一低嘛!中斷讀取按鍵信號,分析按鍵,然後設定定時器的頻率,啟動定時器,設置一個響的時間,然後到時間關閉定時器,這樣你按下k1就會發出一聲do的聲音,然後停了。
3,按鍵讀取程序,中斷或者查詢方式,自己選擇吧,別忘了延遲5ms左右再次讀取按鍵,這個是消抖的。
4,建議模塊化編程,先搞定按鍵的,然後搞定數碼管的,然後搞定定時器的,然後再考慮如何把它們組合起來。好了不說了,說得有點多了,再說會我都回到大學時代了,哈哈。總之自己一點一點的做,應該不難,51熟練,c語言熟練,板子焊接的結構比較清晰的話,很快就可以搞定的。
5,還是建議你自己寫一份各個模塊的驅動的代碼,例如按鍵的,數碼管的,led的,溫度感測器的,光敏的,蜂鳴器的,遙控器的,定時器的,中斷的,等等等等模塊(可以借鑒別人寫的,自己一定要會),然後需要的時候,過來,改改就行,快而且bug少。建議keil c語言編程,用匯編編碼太耗時了。
⑼ 51單片機程序 電子琴音階
中央C的頻率為261.62557 Hz,音程相差八度則頻率相差一倍,例如C5的頻率是C4的兩倍。而電子琴鍵盤上相鄰的鍵(包括黑鍵)的頻率比為1:2^(1/12)。
⑽ 24鍵51單片機電子琴
您的P0,P2,P3 哪個是低音中音高音 在圖上看不太清楚,我是按照P0,P2,P3的順序來的
另外,第一個頻率您確定不是220Hz?
模擬播放到電腦音效卡聽了一下,音準大體是對的。
LED的接法雖然能用,但不是太規范呀。
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit out1 = P1^0;
sbit LED1 = P1^5;
#define LED_OFF 0
#define LED_ON 1
unsigned int t0_init_value;
unsigned char kv();
void set_out(unsigned char k);
void main(){
uchar kv0=0,kv1;
LED1 =LED_OFF;
TMOD=0x01;
TR0=0;
EA=1;
ET0=1;
while(1){
kv1=kv();
if(!kv1) {TR0=0;LED1 =LED_OFF;}
else if(kv0!=kv1){set_out(kv1);}
kv0=kv1;
}
}
unsigned char kv(){
unsigned char n=0,tmp1;
n=0;
if(tmp1=~P0){
while(tmp1){
n++;
if(tmp1&0x01){return n;}
tmp1>>=1;
}
return 0;
}
n=8;
if(tmp1=~P2){
while(tmp1){
n++;
if(tmp1&0x01){return n;}
tmp1>>=1;
}
return 0;
}
n=16;
if(tmp1=~P3){
while(tmp1){
n++;
if(tmp1&0x01){return n;}
tmp1>>=1;
}
return 0;
}
return 0;
}
const unsigned int freq_data[]={
0,
63390, // 233 why not 220?
63511,
63628,
63835,
64021,
64103,
64260,
64400,
64524,
64580,
64633,
64732,
64820,
64898,
64968,
65030,
65058,
65110,
65157,
65178,
65217,
65252,
65283,
65295,
} ;
void set_out(unsigned char k){
t0_init_value = freq_data[k];
TH0 =t0_init_value>>8;TL0=t0_init_value;
TR0=1;
}
void Timer0_isr() interrupt 1
{
TH0 =t0_init_value>>8;
TL0=t0_init_value;
out1=~out1;
LED1=out1;
}