‘壹’ 毕业设计我想用单片机做一个电子琴,程序最好是c语言编写的,那个好心人可以帮我提供点资料,要钱的免进!
www.doyoung.net
上有好多,要的话我还有流程图
/*********************************************************************************************
程序名:DoToy系列作品MidTouch21电子琴程序
编写人:杜洋
编写时间:2009年6月3日
硬件支持:STC11L60XE外部12MHZ晶振电源3V
接口说明:详见《DoToy_MidTouch21电路原理图》
修改日志:
NO.1-20090603_17.54完成电子琴21键的测试(20090603_1备)
NO.2-20090604_01.29改为第二次新板的硬件电路(20090604_2备)
/*********************************************************************************************
说明:
用STC11Fxx单片机I/O接口的高阻态输入功能,扫描I/O接口电平。
手指将VCC线和I/O接口线半连接,产生高电平信号。
/*********************************************************************************************/
voidINIT(void);
#include<STC11Fxx.H>
/*********************************************************************************************/
sbitSPEAKER=P1^0;//扬声器,低使能
sbitLED=P3^0;//LED正极,强推
sbitLED2=P3^1;//LED负极
sbitKEY11=P2^0;
sbitKEY12=P2^1;
sbitKEY13=P2^2;
sbitKEY14=P2^3;
sbitKEY15=P2^4;
sbitKEY16=P2^5;
sbitKEY17=P2^6;
sbitKEY21=P2^7;
sbitKEY22=P4^4;
sbitKEY23=P4^5;
sbitKEY24=P4^6;
sbitKEY25=P0^7;
sbitKEY26=P0^6;
sbitKEY27=P0^5;
sbitKEY31=P0^4;
sbitKEY32=P0^3;
sbitKEY33=P0^2;
sbitKEY34=P0^1;
sbitKEY35=P0^0;
sbitKEY36=P3^3;
sbitKEY37=P3^2;
/*********************************************************************************************/
unsignedcharMUSIC;
unsignedcharSTH0,STL0;
unsignedintcodetab[]={//音阶表
63628,63835,64021,64103,64260,64400,64524,//低音1-7
64580,64684,64777,64820,64898,64968,65030,//中音1-7
65058,65110,65157,65178,65217,65252,65283//高音1-7
};
/*********************************************************************************************/
voiddelay1ms(unsignedinta){//1ms延时程序(12MHz10倍于51单片机速度时)
unsignedinti;
while(--a!=0){
for(i=0;i<600;i++);
}
}/***************************************************************************************/
voidINIT(void){//初始化程序
TMOD=0x11;
ET0=1;
ET1=1;
EA=1;
P0M1=0xff;//I/O接口工作方式
P0M0=0x00;//P0全为高阻输入
P1M1=0xfe;//P1.0为准双向,其他为高阻输入
P1M0=0x00;
P2M1=0xff;//P2全为高阻输入
P2M0=0x00;
P3M1=0xfc;//P3.0为强推,其他为标准双向
P3M0=0x01;
P4M1=0xff;//P4全为高阻输入
P4M0=0x00;
P4SW=0xff;
LED=1;
LED2=0;
SPEAKER=0;
}
/***************************************************************************************/
voidmain(void){
INIT();//初始化
while(1){
if(KEY37==1){delay1ms(20);if(KEY37==1){MUSIC=20;}}//高音B(37)
if(KEY36==1){delay1ms(20);if(KEY36==1){MUSIC=19;}}
if(KEY35==1){delay1ms(20);if(KEY35==1){MUSIC=18;}}
if(KEY34==1){delay1ms(20);if(KEY34==1){MUSIC=17;}}
if(KEY33==1){delay1ms(20);if(KEY33==1){MUSIC=16;}}
if(KEY32==1){delay1ms(20);if(KEY32==1){MUSIC=15;}}
if(KEY31==1){delay1ms(20);if(KEY31==1){MUSIC=14;}}
//3
if(KEY27==1){delay1ms(20);if(KEY27==1){MUSIC=13;}}
if(KEY26==1){delay1ms(20);if(KEY26==1){MUSIC=12;}}
if(KEY25==1){delay1ms(20);if(KEY25==1){MUSIC=11;}}
if(KEY24==1){delay1ms(20);if(KEY24==1){MUSIC=10;}}
if(KEY23==1){delay1ms(20);if(KEY23==1){MUSIC=9;}}
if(KEY22==1){delay1ms(20);if(KEY22==1){MUSIC=8;}}
if(KEY21==1){delay1ms(20);if(KEY21==1){MUSIC=7;}}
//2
if(KEY17==1){delay1ms(20);if(KEY17==1){MUSIC=6;}}
if(KEY16==1){delay1ms(20);if(KEY16==1){MUSIC=5;}}
if(KEY15==1){delay1ms(20);if(KEY15==1){MUSIC=4;}}
if(KEY14==1){delay1ms(20);if(KEY14==1){MUSIC=3;}}
if(KEY13==1){delay1ms(20);if(KEY13==1){MUSIC=2;}}
if(KEY12==1){delay1ms(20);if(KEY12==1){MUSIC=1;}}
if(KEY11==1){delay1ms(20);if(KEY11==1){MUSIC=0;}}
//1
if(MUSIC!=0xff){//如果有音阶数值(非0XFF时)
STH0=tab[MUSIC]/256;//将音阶的频率值装入定时器T0
STL0=tab[MUSIC]%256;
TR0=1;//启动定时器
MUSIC=0xff;//清除寄存器
}else{//否则
SPEAKER=1;//关扬声器
LED=1;
TR0=0;//关定时器
}
}
}
/***************************************************************************************/
voidt0(void)interrupt1using0{//定时器0产生音频
TH0=STH0;
TL0=STL0;
SPEAKER=~SPEAKER;//取反频率产生音调
LED=SPEAKER;//LED同频闪烁
}
/***************************************************************************************/
/*************************************************************
*杜洋工作室www.DoYoung.net
/*************************************************************/
‘贰’ 单片机简单的电子琴程序(C语言的),需要用4*4按键控制,简单点就行,不需要有音乐
#include<AT89X51.H>
unsignedchartemp;
unsignedcharkey;
unsignedchari,j;
unsignedcharSTH0;
unsignedcharSTL0;
unsignedintcodetab[]={64021,64103,64260,64400,
64524,64580,64684,64777,
64820,64898,64968,65030,
65058,65110,65157,65178};
voidmain(void)
{
TMOD=0x01;
ET0=1;
EA=1;
while(1)
{
P3=0xff;//将P3口取出
P3_4=0;//使P3_4为低电平,这样可以判断第一竖排有没有键按下
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)//判断是哪个键按下
{
case0x0e:
key=0;
break;
case0x0d:
key=1;
break;
case0x0b:
key=2;
break;
case0x07:
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)
{
case0x0e:
key=4;
break;
case0x0d:
key=5;
break;
case0x0b:
key=6;
break;
case0x07:
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)
{
case0x0e:
key=8;
break;
case0x0d:
key=9;
break;
case0x0b:
key=10;
break;
case0x07:
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)
{
case0x0e:
key=12;
break;
case0x0d:
key=13;
break;
case0x0b:
key=14;
break;
case0x07:
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;
}
}
}
}
voidt0(void)interrupt1using0
{
TH0=STH0;
TL0=STL0;
P1_0=~P1_0;
}
电路图和原理我都有,刚好我也在做这个。你自己看下程序吧,我也不愿意注释。
这个是能发出16个音符声音的,你写的AD89S52,应该是AT89S52吧
‘叁’ C语言电子琴程序
联机调试的程序,先一步一步的来。
‘肆’ C语言,电子琴程序
这是什么鬼东西,看不懂。得去问博士后级别的人物了
‘伍’ C语言工作原理
作为一种编程语言,本身是谈不上工作原理的,实际上C语言所有的语法,正是C语言编译器的工作原理或者工作机制的具体实现。要细致的讨论起来是不可能,但是作为C语言程序员,必须了解这个大致的流程。一个程序,从C语言源码,到系统可执行的文件,一般经历四个过程。
1、预处理阶断,这个阶断是文本处理阶断,有预处理器来完成,会将源码中的带"#"开头的预处理命令进行相应的处理,在Linux上C语言的预处理器程序是cp命令。
2、编译阶断,这个阶断是有C语言编译阶断,在Linux上C语言的编译器是cc命令,它将C语言源码转换成汇编指令。
3、汇编阶断,这个阶断是汇编编译阶断,在Linux上C语言的汇编器是as命令,这个阶断会将汇编指令编译成二进制机器码。
4、链接阶断,这个阶断是会将汇编阶断生成的机器码目标文件,装载成一个系统可执行的文件,在Linux平台以ELF格式进行组装,在Windows平台上以PE格式进行组装。在Linux平台上的链接器命令为ld,在windows平台上的链接器命令为linker。
‘陆’ 求简易电子琴程序(c51编写)
软件是keil2.0的#include"reg51.h"unsigned char i,j,tempsbit p3_3=p3^3void d0();void ra();void mi();void fa();void so();void la();void xi();void hd0();void music();main(){ie=0;tmod=0x10;tr1=1;while(1){do{p1=0xff;temp=p1;temp=~temp}:while(temp==0x00)switch(temp){case 0x01:d0();break;case 0x02:ra();breakcase 0x04:mi();break;case 0x08:fa();breakcase 0x10:so();breakcase 0x20:la();breakcase 0x40:xi();breakdefault:hd0();break}music()}}void d0(){i=0x21;j=0xf9}void ra(){i=0xe0;j=0xf9}void mi(){i=0x8bj=0xfa;}void fa(){i=0xd7j=0xfa;}void so(){i=0x67;j=0xfb}void la(){i=0xe8;j=0xfb}void xi(){i=0x5bj=0xfc}void hd0(){j=0x8e;j=0xfc}void music(){tl1=ith1=j;do{while(tf1!=1)tf1=0tl1=i;th1=jp3_3=~p3_3temp=~p1}while(temp!=0x00)p3_3=1}
‘柒’ 求关于单片机的电子琴C程序
1. 实验任务
(1. 由4X4 组成16 个按钮矩阵,设计成16 个音。
(2. 可随意弹奏想要表达的音乐。
2. 电路原理图
图4.22.1
3. 系统板硬件连线
(1. 把“单片机系统”区域中的P1.0 端口用导线连接到“音频放大模块”区
域中的SPK IN 端口上;
102
(2. 把“单片机系统“区域中的P3.0-P3.7 端口用8 芯排线连接到“4X4 行
列式键盘”区域中的C1-C4 R1-R4 端口上;
4. 相关程序内容
(1. 4X4 行列式键盘识别;
(2. 音乐产生的方法;
一首音乐是许多不同的音阶组成的,而每个音阶对应着不同的频率,这样我
们就可以利用不同的频率的组合,即可构成我们所想要的音乐了,当然对于单片
机来产生不同的频率非常方便,我们可以利用单片机的定时/计数器T0 来产生这
样方波频率信号,因此,我们只要把一首歌曲的音阶对应频率关系弄正确即可。
现在以单片机12MHZ 晶振为例,例出高中低音符与单片机计数T0 相关的计数值
如下表所示
下面我们要为这个音符建立一个表格,有助于单片机通过查表的方式来获得相应
的数据
低音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
音符频率(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
103
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 调)
对于不同的曲调我们也可以用单片机的另外一个定时/计数器来完成。
下面就用AT89S51 单片机产生一首“生日快乐”歌曲来说明单片机如何产生的。
在这个程序中用到了两个定时/计数器来完成的。其中T0 用来产生音符频率,T1
用来产生音拍。
5. 程序框图
图4.22.2
6. 汇编源程序
KEYBUF EQU 30H
STH0 EQU 31H
STL0 EQU 32H
TEMP EQU 33H
曲调值DELAY 曲调值DELAY
调4/4 125ms 调4/4 62ms
调3/4 187ms 调3/4 94ms
调2/4 250ms 调2/4 125ms
104
ORG 00H
LJMP START
ORG 0BH
LJMP INT_T0
START: MOV TMOD,#01H
SETB ET0
SETB EA
WAIT:
MOV P3,#0FFH
CLR P3.4
MOV A,P3
ANL A,#0FH
XRL A,#0FH
JZ NOKEY1
LCALL DELY10MS
MOV A,P3
ANL A,#0FH
XRL A,#0FH
JZ NOKEY1
MOV A,P3
ANL A,#0FH
CJNE A,#0EH,NK1
MOV KEYBUF,#0
LJMP DK1
NK1: CJNE A,#0DH,NK2
MOV KEYBUF,#1
LJMP DK1
NK2: CJNE A,#0BH,NK3
MOV KEYBUF,#2
LJMP DK1
NK3: CJNE A,#07H,NK4
MOV KEYBUF,#3
LJMP DK1
NK4: NOP
DK1:
MOV A,KEYBUF
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV P0,A
MOV A,KEYBUF
MOV B,#2
MUL AB
MOV TEMP,A
MOV DPTR,#TABLE1
105
MOVC A,@A+DPTR
MOV STH0,A
MOV TH0,A
INC TEMP
MOV A,TEMP
MOVC A,@A+DPTR
MOV STL0,A
MOV TL0,A
SETB TR0
DK1A: MOV A,P3
ANL A,#0FH
XRL A,#0FH
JNZ DK1A
CLR TR0
NOKEY1:
MOV P3,#0FFH
CLR P3.5
MOV A,P3
ANL A,#0FH
XRL A,#0FH
JZ NOKEY2
LCALL DELY10MS
MOV A,P3
ANL A,#0FH
XRL A,#0FH
JZ NOKEY2
MOV A,P3
ANL A,#0FH
CJNE A,#0EH,NK5
MOV KEYBUF,#4
LJMP DK2
NK5: CJNE A,#0DH,NK6
MOV KEYBUF,#5
LJMP DK2
NK6: CJNE A,#0BH,NK7
MOV KEYBUF,#6
LJMP DK2
NK7: CJNE A,#07H,NK8
MOV KEYBUF,#7
LJMP DK2
NK8: NOP
DK2:
MOV A,KEYBUF
106
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV P0,A
MOV A,KEYBUF
MOV B,#2
MUL AB
MOV TEMP,A
MOV DPTR,#TABLE1
MOVC A,@A+DPTR
MOV STH0,A
MOV TH0,A
INC TEMP
MOV A,TEMP
MOVC A,@A+DPTR
MOV STL0,A
MOV TL0,A
SETB TR0
DK2A: MOV A,P3
ANL A,#0FH
XRL A,#0FH
JNZ DK2A
CLR TR0
NOKEY2:
MOV P3,#0FFH
CLR P3.6
MOV A,P3
ANL A,#0FH
XRL A,#0FH
JZ NOKEY3
LCALL DELY10MS
MOV A,P3
ANL A,#0FH
XRL A,#0FH
JZ NOKEY3
MOV A,P3
ANL A,#0FH
CJNE A,#0EH,NK9
MOV KEYBUF,#8
LJMP DK3
NK9: CJNE A,#0DH,NK10
MOV KEYBUF,#9
LJMP DK3
107
NK10: CJNE A,#0BH,NK11
MOV KEYBUF,#10
LJMP DK3
NK11: CJNE A,#07H,NK12
MOV KEYBUF,#11
LJMP DK3
NK12: NOP
DK3:
MOV A,KEYBUF
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV P0,A
MOV A,KEYBUF
MOV B,#2
MUL AB
MOV TEMP,A
MOV DPTR,#TABLE1
MOVC A,@A+DPTR
MOV STH0,A
MOV TH0,A
INC TEMP
MOV A,TEMP
MOVC A,@A+DPTR
MOV STL0,A
MOV TL0,A
SETB TR0
DK3A: MOV A,P3
ANL A,#0FH
XRL A,#0FH
JNZ DK3A
CLR TR0
NOKEY3:
MOV P3,#0FFH
CLR P3.7
MOV A,P3
ANL A,#0FH
XRL A,#0FH
JZ NOKEY4
LCALL DELY10MS
MOV A,P3
ANL A,#0FH
XRL A,#0FH
JZ NOKEY4
108
MOV A,P3
ANL A,#0FH
CJNE A,#0EH,NK13
MOV KEYBUF,#12
LJMP DK4
NK13: CJNE A,#0DH,NK14
MOV KEYBUF,#13
LJMP DK4
NK14: CJNE A,#0BH,NK15
MOV KEYBUF,#14
LJMP DK4
NK15: CJNE A,#07H,NK16
MOV KEYBUF,#15
LJMP DK4
NK16: NOP
DK4:
MOV A,KEYBUF
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV P0,A
MOV A,KEYBUF
MOV B,#2
MUL AB
MOV TEMP,A
MOV DPTR,#TABLE1
MOVC A,@A+DPTR
MOV STH0,A
MOV TH0,A
INC TEMP
MOV A,TEMP
MOVC A,@A+DPTR
MOV STL0,A
MOV TL0,A
SETB TR0
DK4A: MOV A,P3
ANL A,#0FH
XRL A,#0FH
JNZ DK4A
CLR TR0
NOKEY4:
LJMP WAIT
DELY10MS:
MOV R6,#10
109
D1: MOV R7,#248
DJNZ R7,$
DJNZ R6,D1
RET
INT_T0:
MOV TH0,STH0
MOV TL0,STL0
CPL P1.0
RETI
TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H
DB 7FH,6FH,77H,7CH,39H,5EH,79H,71H
TABLE1: DW 64021,64103,64260,64400
DW 64524,64580,64684,64777
DW 64820,64898,64968,65030
DW 65058,65110,65157,65178
END
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;
110
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;
111
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;
112
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;
}
}
113
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;
}
}
114
}
}
void t0(void) interrupt 1 using 0
{
TH0=STH0;
TL0=STL0;
P1_0=~P1_0;
}
‘捌’ 电子琴的设计原理
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. 程序框图
图4.22.2
6. 汇编源程序
KEYBUF EQU 30H
STH0 EQU 31H
STL0 EQU 32H
TEMP EQU 33H
ORG 00H
LJMP START
ORG 0BH
LJMP INT_T0 ;T0中断入口
START: MOV TMOD,#01H ;T0工作方式1
SETB ET0
SETB EA
WAIT:
MOV P3,#0FFH ;输入口置1准备工作
CLR P3.4
MOV A,P3 ;读键盘
ANL A,#0FH ;保持低四位
XRL A,#0FH ;
JZ NOKEY1
LCALL DELY10MS
MOV A,P3
ANL A,#0FH
XRL A,#0FH
JZ NOKEY1
MOV A,P3
ANL A,#0FH
CJNE A,#0EH,NK1
MOV KEYBUF,#0
LJMP DK1
NK1: CJNE A,#0DH,NK2
MOV KEYBUF,#1
LJMP DK1
NK2: CJNE A,#0BH,NK3
MOV KEYBUF,#2
LJMP DK1
NK3: CJNE A,#07H,NK4
MOV KEYBUF,#3
LJMP DK1
NK4: NOP
DK1:
MOV A,KEYBUF
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV P0,A
MOV A,KEYBUF
MOV B,#2
MUL AB
MOV TEMP,A
MOV DPTR,#TABLE1
MOVC A,@A+DPTR
MOV STH0,A
MOV TH0,A
INC TEMP
MOV A,TEMP
MOVC A,@A+DPTR
MOV STL0,A
MOV TL0,A
SETB TR0
DK1A: MOV A,P3
ANL A,#0FH
XRL A,#0FH
JNZ DK1A
CLR TR0
NOKEY1:
MOV P3,#0FFH
CLR P3.5
MOV A,P3
ANL A,#0FH
XRL A,#0FH
JZ NOKEY2
LCALL DELY10MS
MOV A,P3
ANL A,#0FH
XRL A,#0FH
JZ NOKEY2
MOV A,P3
ANL A,#0FH
CJNE A,#0EH,NK5
MOV KEYBUF,#4
LJMP DK2
NK5: CJNE A,#0DH,NK6
MOV KEYBUF,#5
LJMP DK2
NK6: CJNE A,#0BH,NK7
MOV KEYBUF,#6
LJMP DK2
NK7: CJNE A,#07H,NK8
MOV KEYBUF,#7
LJMP DK2
NK8: NOP
DK2:
MOV A,KEYBUF
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV P0,A
MOV A,KEYBUF
MOV B,#2
MUL AB
MOV TEMP,A
MOV DPTR,#TABLE1
MOVC A,@A+DPTR
MOV STH0,A
MOV TH0,A
INC TEMP
MOV A,TEMP
MOVC A,@A+DPTR
MOV STL0,A
MOV TL0,A
SETB TR0
DK2A: MOV A,P3
ANL A,#0FH
XRL A,#0FH
JNZ DK2A
CLR TR0
NOKEY2:
MOV P3,#0FFH
CLR P3.6
MOV A,P3
ANL A,#0FH
XRL A,#0FH
JZ NOKEY3
LCALL DELY10MS
MOV A,P3
ANL A,#0FH
XRL A,#0FH
JZ NOKEY3
MOV A,P3
ANL A,#0FH
CJNE A,#0EH,NK9
MOV KEYBUF,#8
LJMP DK3
NK9: CJNE A,#0DH,NK10
MOV KEYBUF,#9
LJMP DK3
NK10: CJNE A,#0BH,NK11
MOV KEYBUF,#10
LJMP DK3
NK11: CJNE A,#07H,NK12
MOV KEYBUF,#11
LJMP DK3
NK12: NOP
DK3:
MOV A,KEYBUF
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV P0,A
MOV A,KEYBUF
MOV B,#2
MUL AB
MOV TEMP,A
MOV DPTR,#TABLE1
MOVC A,@A+DPTR
MOV STH0,A
MOV TH0,A
INC TEMP
MOV A,TEMP
MOVC A,@A+DPTR
MOV STL0,A
MOV TL0,A
SETB TR0
DK3A: MOV A,P3
ANL A,#0FH
XRL A,#0FH
JNZ DK3A
CLR TR0
NOKEY3:
MOV P3,#0FFH
CLR P3.7
MOV A,P3
ANL A,#0FH
XRL A,#0FH
JZ NOKEY4
LCALL DELY10MS
MOV A,P3
ANL A,#0FH
XRL A,#0FH
JZ NOKEY4
MOV A,P3
ANL A,#0FH
CJNE A,#0EH,NK13
MOV KEYBUF,#12
LJMP DK4
NK13: CJNE A,#0DH,NK14
MOV KEYBUF,#13
LJMP DK4
NK14: CJNE A,#0BH,NK15
MOV KEYBUF,#14
LJMP DK4
NK15: CJNE A,#07H,NK16
MOV KEYBUF,#15
LJMP DK4
NK16: NOP
DK4:
MOV A,KEYBUF
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV P0,A
MOV A,KEYBUF
MOV B,#2
MUL AB
MOV TEMP,A
MOV DPTR,#TABLE1
MOVC A,@A+DPTR
MOV STH0,A
MOV TH0,A
INC TEMP
MOV A,TEMP
MOVC A,@A+DPTR
MOV STL0,A
MOV TL0,A
SETB TR0
DK4A: MOV A,P3
ANL A,#0FH
XRL A,#0FH
JNZ DK4A
CLR TR0
NOKEY4:
LJMP WAIT
DELY10MS:
MOV R6,#10
D1: MOV R7,#248
DJNZ R7,$
DJNZ R6,D1
RET
INT_T0:
MOV TH0,STH0
MOV TL0,STL0
CPL P1.0
RETI
TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H
DB 7FH,6FH,77H,7CH,39H,5EH,79H,71H
TABLE1: DW 64021,64103,64260,64400
DW 64524,64580,64684,64777
DW 64820,64898,64968,65030
DW 65058,65110,65157,65178
END
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;
}
‘玖’ 在51单片机上用C语言实现电子琴功能,但同时数码管可以显示简谱,怎么编程序
1,数据管显示就没什么了,找几个简单的数码管驱动程序改改就可以了,一般都是先选中数码管,然后设置值,就可以显示了,不过需要注意刷新,10ms刷新一个应该就可以了,刷新频率比较低的话会闪闪的,这个你应该明白。
2,蜂鸣器发do音,这个硬件实现我就不知道了,也许有硬件可以 编码控制自动生成对应频率的值。我想如果通过软件实现的话,不妨考虑一下定时器。假设do音是1000Hz的频率(没有查,不清楚,假设的),那么你可以控制定时器的触发频率为1000hz,触发一次,对应的输出到蜂鸣器的口的电平跳变一下,如果定时器的频率为1000hz的话,那么应该有500hz的频率,一个周期需要一高一低嘛!中断读取按键信号,分析按键,然后设定定时器的频率,启动定时器,设置一个响的时间,然后到时间关闭定时器,这样你按下k1就会发出一声do的声音,然后停了。
3,按键读取程序,中断或者查询方式,自己选择吧,别忘了延迟5ms左右再次读取按键,这个是消抖的。
4,建议模块化编程,先搞定按键的,然后搞定数码管的,然后搞定定时器的,然后再考虑如何把它们组合起来。好了不说了,说得有点多了,再说会我都回到大学时代了,哈哈。总之自己一点一点的做,应该不难,51熟练,c语言熟练,板子焊接的结构比较清晰的话,很快就可以搞定的。
5,还是建议你自己写一份各个模块的驱动的代码,例如按键的,数码管的,led的,温度传感器的,光敏的,蜂鸣器的,遥控器的,定时器的,中断的,等等等等模块(可以借鉴别人写的,自己一定要会),然后需要的时候,过来,改改就行,快而且bug少。建议keil c语言编程,用汇编编码太耗时了。
‘拾’ 实验六 简易电子琴实验 一. 实验目的: 1. 了解8253/4的工作原理。 2. 用键盘实现弹奏规定音符的要求。
这个同学把实验指导书直接上传上来了,呵呵,指导书其中有错,“不能把其频率值直接送入42号端口
”,这里的42H是错的,应该是4AH,,,
写这个程序,要对“微机原理接口技术”知识有比较好的了解,并且初步掌握了可编程键盘显示接口芯片8279、可编程并行接口芯片8255的使用,还要对你的运行环境(实验设备)有较好的了解,那么用接口芯片8253来完成一个简易电子琴实验就很简单了,程序中关于8253芯片的初始化,频率因子的计算,8255来控制扬声器的发声程序都在实验指导中列出了,我建议同学还是试着自己编写程序,调试程序,这个过程是乐在其中的。