基于51单片机的简易电子琴设计.docx
《基于51单片机的简易电子琴设计.docx》由会员分享,可在线阅读,更多相关《基于51单片机的简易电子琴设计.docx(34页珍藏版)》请在冰豆网上搜索。
基于51单片机的简易电子琴设计
基于51单片机的简易电子琴设计
————————————————————————————————作者:
————————————————————————————————日期:
基于51单片机的简易电子琴设计
一.问题提出
为什么选择简易电子琴设计?
1.对于音乐的兴趣
我们对音乐都有着浓厚的兴趣,喜欢听钢琴曲,如理查德·克莱德曼演奏的《思乡曲》《星空》《秋日的私语》等,音乐在我们的生活中扮演着很重要的角色。
有人曾说,喜欢音乐的人不会向恶。
以前不以为然,可是随着这些年来慢慢喜欢上阴郁,听了越来越多的钢琴曲之后,觉得这句话非常有道理。
音乐是用艺术家用音符记录世界,传达情感的一种艺术形式,音乐里有一种和谐之美,听音乐可以让人心情舒畅,与外界和谐统一。
音乐现在已经成为我生活中很重要的一部分,我们每周都会抽些时间去欣赏世界名曲,作为对精神的洗礼.
2.对于电子琴的好奇
好奇是人的天性,人类对于自然的认识,对于科学的探索,无不始于好奇。
我们对电子琴如何实现其功能,如音色选择、声音强弱控制、节拍器、自动放音功能等等也很好奇,想通过学习单片机这个机会,深入了解电子琴的功能实现原理。
3.对于51单片机强大功能的信赖
51单片机有基本特性:
(1)面向控制的8位CPU和指令系统
(2)4K字节的程序存储器(ROM或EPROM)
(3)128字节的数据存储器
(4)可编程的并行I/O口P0~P3,有32位双向输入/输出线
(5)一个全双工串行口
(6)两个16位定时器/计数器
(7)五个中断源,两个优先级的中断结构
(8)一个片内时钟振荡器和时钟电路
(9)可以寻址64K字节的程序存储器和64K字节的外部数据存储器
51单片机功能强大,性能日趋完善,在工业测控、智能仪器仪表、机电一体化产品、家电领域中应用广泛,因此基于51单片机设计简易的电子琴可行性非常大。
二.功能需求
1.能够实现基本的琴键功能
即每按下一个琴键,单片机能够检测到键盘的按键,并根据按键的位置,通过程序来控制,使蜂鸣器发出不同频率(音调)的声音,声音延迟一段时间,等到按键放开后,声音停止。
然后再继续扫描,看是否有键按下,如此循环下去,即可实现基本的琴键功能。
2.能够实现调节电子琴音色的功能
在键盘上设置功能键,通过按键来选择不同的音色。
当选通后,按下琴键,蜂鸣器就一直发出此种音色的声音。
直到下一次再次按下音色选择功能键,才会改变音色。
系统共设置五种音色:
长笛音,钢琴音,小号音,小提琴音,短笛音,默认状态为钢琴音。
3.能够实现通过按键自动播放歌曲的功能
在键盘上设置几个功能键,按下之后会根据功能键跳转到自动播放歌曲的程序,来播放相应的歌曲。
播放歌曲的默认音色为钢琴音,若希望调整音色,只需在自动播放歌曲之前,按下相应的音色选择功能键即可实现。
三.总体方案
1.电子琴原理
在介绍总体方案之前,先简单介绍一下电子琴的发生原理以及如何改变音色的基本原理:
声音的频谱范围约在几十到几千赫兹,若能利用程序来控制单片机某个口线不断输出“高”“低”电平,则在该口线上就能产生一定频率的方波,将该方波接上喇叭就能发出一定频率的声音,若再利用程序控制“高”“低”电平的持续时间,就能改变输出波形的频率从而改变音调。
乐曲中,每一音符对应着确定的频率,下表给出各音符频率。
如果单片机某个口线输出“高"“低”电平的频率和某个音符的频率一样,那么将此口线接上喇叭就可以发出此音符的声音。
本系统就是根据此原理设计,对于单片机来说要产生一定频率的方波大致是先将某口线输出高电平然后延时一段时间再输出低电平,如此循环的输出就会产生一定频率的方波,通过改变延时的时间就可以改变输出方波的频率。
单片机内部有两个位的定时计数器T1和T0,单片机的定时计数器实际上是个计数装置它既可以对单片机的内部晶振驱动时钟计数也可以对外部输入的脉冲计数,对内部晶振计数时称为定时器,对外部时钟计数时称为计数器.当对单片机的内部晶振驱动时钟计数时,每个机器周期定时计数器的计数值就加,当计数值达到计数最大值时计数完毕并通知单片机的尸比对外部输入的时钟信号计数时,外部时钟的每个时钟上升沿定时计数器的计数值就加,当计数值达到计数最大值时计数完毕并通知单片机的尸。
因此,如果知道单片机的机器周期或者外部输入时钟信号的周期单片机就可以根据定时器的计数值计算出定时的时间。
用此方法定时十分准确,想得到多大的延时时间就可以给定时器赋一定的计数初值,定时器从预先设置的计数初值开始不断增当增加到计数最大值时计数完毕,调整计数初值的大小就可以调整定时器定时的时间,从而达到准确的延时。
在本设计中我们使用的外部时钟信号的晶振频率为12MHz,而采用的计数方式为方式1,所以计数器的初始值可以由如下公式求得.本文为互联网收集,请勿用作商业用途本文为互联网收集,请勿用作商业用途
T=65536-1000000/2/f
f为对应音调的频率;
通过以上方法,可求出各音调对应的频率,如下表
2。
外观设计
2.硬件部分总体方案
51单片机P0口通过8155扩展,连接4*8的矩阵键盘,作为琴键键盘和相应的功能控制键;并P2口一起,与EPROM连接;P0口则接通不通音色的滤波电路,通过程序控制P0口,选通不通的琴声音色滤波电路,使电子琴发出不同音色的声音。
3.软件部分总体方案
(1)键盘扫描程序:
检测是否有键按下,有键按下则记录按下键的键值,并跳转至功能转移程序;无键按下,则返回键盘扫描程序继续检测
(2)功能转移程序:
对检测到得按键值进行判断,是琴键则跳转至琴键处理程序,是功能键则跳转至相应的功能程序,我们设计的功能程序有两种,即音色调节功能和自动播放乐曲功能
(3)琴键处理程序:
根据检测到得按键值,查询音律表,给计时器赋值,使发出相应频率的声音
(4)音色调节程序:
检测到键盘按下的是音色调节功能键后执行该程序,改变P0端口的值,选通相应的音色滤波电路,达到调节音色的目的
(5)自动播放歌曲程序:
检测到按键按下的是自动播放歌曲功能键后执行该程序,电子琴会自动播放事先已经存放好的歌曲,歌曲播放完毕之后自动返回至键盘扫描程序,继续等待是否有键按下
四.硬件详细设计
总电路图
8155扩展
外部EPROM扩展电路
键盘电路
长笛滤波电路
钢琴滤波电路
小号滤波电路
小提琴滤波电路
短笛滤波电路
四.软件框图
总程序简易流程图
键盘扫描程序流程图
弹奏程序流程图
音色调整子程序
自动播放歌曲程序流程图
六.软件清单
ORG0200H
MOVP1,#02H;初始化P1口,使得电子琴默认为钢琴声
KEYPRO:
;键盘扫描程序
ACALLKEXAM;检查是否有键按下
JZKEYPRO;若无键按下,则转KEYPRO,继续等待并检查
ACALLD10ms;若有键按下,则延时10ms,进行曲抖动处理
ACALLKEXAM;再次检查是否有键按下
JZKEYPRO;若无键按下,则转KEYPRO
KEY1:
MOVR2,#OFEH;输出使第X0行为低电平模型数值
MOVR3,#OFFH;列值寄存器预置初值
MOVR4,#OOH;行值寄存器清零
KEY2:
MOVDPTR,#0303H;送8155PC口地址
MOVA,R2;扫描第一行
MOVX@DPTR,A
MOVDPTR,#0301H;送8155PA口地址
MOVXA,@DPTR;读列数据值
CPLA
ANLA,#OFFH
JNZKEY3;有键按下,请求转值
MOVA,R4;无键按下,行值寄存器加8
ADDA,#08H
MOVR4,A
MOVA,R2;求下一行为低电平模型数值
RLA
MOVR2,A
JBACC。
4,KEY2;判断各行是否完全扫描完,若未完,则继续扫描下一行
AJMPKEYPRO;若全部扫描完毕,则等待下一次按键
KEY3:
CPLA;恢复列模型
KEY4:
INCR3
RRCA;求列值
JCKEY4
KEY5:
ACALLD10ms
ACALLKEXAM
JNZKEY5;若有键按下,则转KEY5,等待键释放
MOVA,R4;计算键值
ADDA,R3
MOVBUFF,A
AJMPKEYADR;转查找功能键入口地址子程序
D10ms:
;延时10ms的子程序
MOVR5,#14H
DL:
MOVR6,DL0
DL0:
DJNZR6,DL0
DJNZR5,DL
RET
BUFFEQU30H
KEXAM:
MOVDPTR,#0303H;送端口C地址
MOVA,#00H;输出使所有的行均为低电平模型数值
MOVX@DPTR,A
MOV@DPTR,#0301H
MOVXA,@DPTR
CPLA
ANLA,#0FFH
RET
ORG8000H;跳转功能程序
KEYADR:
MOVA,BUFF;取出键值
CJNEA,#17H,KYARD1
AJMPPLAY;等于17H,转琴键处理
KEYRD1:
JCPLAY;小于17H,转琴键处理
KEYTBL:
MOVDPTR,#JMPTBL;送功能键地址表指针
CLRC;清进位位
SUBBA,#10H
RLA
JMP@A+DPTR;转相应的功能键处理程序
BUFFEQU30H
JMPTBL:
AJMPSONG1;跳转至化蝶
AJMPSONG2;跳转至童年
AJMPSONG3;跳转至龙的传人
AJMPFLUTE;调节成长笛音色状态
AJMPPIANO;调节成钢琴音色状态
AJMPTRUMPET;调节成小号音色状态
AJMPVIOLIN;调节成小提琴音色状态
AJMPPICCOLO;调节成短笛音色状态
SONG1:
MOVDPTR,#BUTTERFLY;赋梁祝谱初值
ACALLSUB_SONG;调用播放歌曲子程序
AJMPKEYPRO;返回至键盘扫描程序
SONG2:
MOVDPTR,#YOUTH;赋童年谱值
ACALLSUB_SONG;调用播放歌曲子程序
AJMPKEYPRO;返回至键盘扫描程序
SONG3:
MOVDPTR,#MULTIPLY_OF_THE_DRAGON;赋龙的传人谱初值
ACALLSUB_SONG
AJMPKEYPRO
FLUTE:
MOVP1,#01H;使长笛滤波电路选通
AJMPKEYPRO;跳转回键盘扫描程序
PIANO:
MOVP1,#02H;使钢琴琴滤波电路选通
AJMPKEYPRO;跳转回键盘扫描程序
TRUMPET:
MOVP1,#04H;使小号滤波电路选通
AJMPKEYPRO;跳转回键盘扫描电路
VIOLIN:
MOVP1,#08H;使小提琴滤波电路选通
AJMPKEYPRO;跳转回键盘扫描电路
PICCOLO:
MOVP1,#10H;使短笛滤波电路选通通
AJMPKEYPRO;跳转回键盘扫描电路
PLAY:
;弹琴子程序
ORG0F00H;子程序入口地址
SJMPMAIN
ORG0F1BH;设置中断入口地址
LJMPTINT1
MAIN:
MOVTMOD,#10H;计时器控制字T1方式计时
SETBEA;开中断总开关
SETBET1;允许T1中断
SETBTR1;定时开始
MOVDPTR,#TABLE1;查询音律表
PUSHACC
MOVCA,@A+DPTR
MOVTH1,A;音律表查询值高八位赋值
POPACC
INCA
MOVCA,@A+DPTR
MOVTL1,A;音律表查询值低八位赋值
ACALLDLAY
AJMPKEYPRO;跳转回键盘扫描程序
TINT1:
JBP1.0,FLUTE_ON;判断是否跳到长笛音色档
JBP1.1,PIANO_ON;判断是否调到钢琴音色档
JBP1。
2,TRUMPET_ON;判断是否调到小号音色档
JBP1。
3,VIOLIN_ON;判断是否跳到小提琴音色档
JBP1.4,PICCOLO_ON;判断是否跳到短笛音色档
FLUTE_ON:
;若是长笛音色档,则控制P1.0口电压变化
CPLP1。
0
POPDPH
POPDPL
PUSHDPL
PUSHDPH
RETI
PIANO_ON:
;若是钢琴琴音色档,则控制P1。
1口电压变化
CPLP1。
1
POPDPH
POPDPL
PUSHDPL
PUSHDPH
RETI
TRUMPET_ON:
;若是小号音色档,则控制P1.2口电压变化
CPLP1.2
POPDPH
POPDPL
PUSHDPL
PUSHDPH
RETI
VIOLIN_ON:
;若是小提琴音色档,则控制P1.2口电压变化
CPLP1.3
POPDPH
POPDPL
PUSHDPL
PUSHDPH
RETI
PICCOLO_ON:
;若是短笛音色档,则控制P1.2口电压变化
CPLP1.4
POPDPH
POPDPL
PUSHDPL
PUSHDPH
RETI
DLAY:
MOVR2,#0F0H;延时程序
DL2:
MOVR3,#0F0H
DL1:
NOP
NOP
DJNZR3,DL1
DJNZR2,DL2
RET
TABLE1:
;音律表
DW0F88BH;-1
DW0F95BH;—2
DW0FA14H;—3
DW0FA67H;—4
DW0FB07H;—5
DW0FB8FH;-6
DW0FB9EH;—6#
DW0FC0BH;—7
DW0FC43H;1
DW0FCACH;2
DW0FD09H;3
DW0FD33H;4
DW0FD83H;5
DW0FDC7H;6
DW0FDE7H;6#
DW0FE05H;7
DW0FE22H;+1
DW0FE56H;+2
DW0FE84H;+3
DW0FE9AH;+4
DW0FEC1H;+5
DW0FEE3H;+6
DW0FEF3H;+6#
DW0FF02H;+7
ORG0F00H
SUB_SONG:
;自动播放歌曲的子程序
-1EQU0H;低音域简谱码
-2EQU1H
-3EQU2H
-4EQU3H
-5EQU4H
—6EQU5H
-6#EQU6H
-7EQU7H
1EQU8H;中音域简谱码
2EQU9H
3EQU0AH
4EQU0BH
5EQU0CH
6EQU0DH
6#EQU0EH
7EQU0FH
+1EQU10H;高音域简谱码
+2EQU11H
+3EQU12H
+4EQU13H
+5EQU14H
+6EQU15H
+6#EQU16H
+7EQU17H
FREQ_TEMP。
EQU31H
TIME_TEMP.EQU32H
TH0_TEMP.EQU33H
TL0_TEMP.EQU34H
ORG00H;播放乐曲子程序的主程序
JMPSTART
ORGOBH
JMPTIMER0
START:
MOVSP,#50H
MOVIE,#10000010B;中断,EA=ET0=1
MOVTMOD,#00000001B;设定计数器0为mode1
BEGIN:
MOVA,#00H
MOVCA,@A+DPTR;取得简谱码
MOVFREQ_TEMP,A
INCDPTR;指向下一个地址
MOVA,#00H
MOVCA,@A+DPTR;取得节拍码
MOVTIME_TEMP,A
JZSTOP;比较唱歌是否结束
PUSHDPH
PUSHDPL
MOVA,FREQ_TEMP
CJNEA,#FFH,SING_SONG;比较是否停止发音
CLRTR0;停止计时
JMPHOLD
SING_SONG:
CLRTR0;停止计时
MOVDPTR,#TABLE;频率值存放开始地址
MOVA,FREQ_TEMP;
RLA;FREQ_TEMP地址乘以2
MOVCA,@A+DPTR;取得频率值高位组
MOVTH0,A;TH0=频率值高位组
MOVTH0_TEMP,A
MOVA,FREQ_TEMP
RLA;FREQ_TEMP地址乘以2
INCA;再加1
MOVCA,@DPTR;取得频率值低位组
MOVTL0,A;TL0=频率值低位组
MOVTL0_TEMP,A
SETBTR0;开始计时
HOLD:
CALLDELAY_TIME;延迟节拍数
POPDPL
POPDPH
INCDPTR;指向下一个地址
JMPBEGIN
STOPCLRTR0;乐曲播放结束
SETBP1。
0;关掉蜂鸣器
JMP$
DELAY_TIME:
;节拍数
DELAY#254,#245;125ms
DJNZTIME_TEMP,DELAY_TIME
RET
TIMER0:
MOVTH0,TH0_TEMP;重新载入频率值高位组
MOVTL0,TL0_TEMP;重新载入频率值低位组
JBP1.0,FLUTE_ON;判断是否调长笛音色档
JBP1。
1,PIANO_ON;判断是否调到钢琴音色档
JBP1。
2,TRUMPET_ON;判断是否调到小号音色档
JBP1.3,VIOLIN_ON;判断是否跳到小提琴音色档
JBP1.4,PICCOLO_ON;判断是否跳到短笛音色档
FLUTE_ON:
;若是长笛音色档,则是长笛版乐曲
CPLP1.0
POPDPH
POPDPL
PUSHDPL
PUSHDPH
RETI
PIANO_ON:
;若是钢琴音色档,则是钢琴版乐曲
CPLP1。
1
POPDPH
POPDPL
PUSHDPL
PUSHDPH
RETI
TRUMPET_ON:
;若是小号音色档,则是小号版乐曲
CPLP1。
2
POPDPH
POPDPL
PUSHDPL
PUSHDPH
RETI
VIOLIN_ON:
;若是小提琴音色档,则是小提琴版乐曲
CPLP1.3
POPDPH
POPDPL
PUSHDPL
PUSHDPH
RETI
PICCOLO_ON:
;若是短笛音色档,则是短笛版乐曲
CPLP1。
4
POPDPH
POPDPL
PUSHDPL
PUSHDPH
RETI
TABLE:
DW0F88BH;—1
DW0F95BH;-2
DW0FA14H;—3
DW0FA67H;-4
DW0FB07H;-5
DW0FB8FH;-6
DW0FB9EH;-6#
DW0FC0BH;—7
DW0FC43H;1
DW0FCACH;2
DW0FD09H;3
DW0FD33H;4
DW0FD83H;5
DW0FDC7H;6
DW0FDE7H;6#
DW0FE05H;7
DW0FE22H;+1
DW0FE56H;+2
DW0FE84H;+3
DW0FE9AH;+4
DW0FEC1H;+5
DW0FEE3H;+6
DW0FEF3H;+6#
DW0FF02H;+7
BUTTERFLY:
;化蝶曲谱
DW—3,04H,-5,03H,—6,01H,1,03H,2,01H,—6,01H,1,01H,—5,02H
DW5,03H,+1,01H,6,01H,5,01H,3,01H,5,01H,2,08H
DW2,02H,2,01H,3,01H,-7,02H,—6,02H,—5,03H,—6,01H,1,02H,2,02H
DW-3,02H,1,02H,-6,01H,—5,01H,—6,01H,1,01H,-5,08H
DW3,03H,5,01H,-7,03H,2,01H,—6,01H,1,01H,5,05H
DW—3,02H,—5,01H,—3,01H,—5,01H,—6,01H,-7,01H,2,01H,—6,06H,-5,01H,-6,01H
DW1,03H,2,01H,5,02H,3,02H,2,02H,3,01H,2,01H,1,02H,—6,01H,—5,01H
DW—3,04H,1,04H,—6,01H,1,01H,—6,01H,—5,01H,—3,01H,—5,01H,-6,01H,1,01H
DW-5,08H,FFH,08H
DW00H;歌曲结束标志
YOUTH:
;童年曲谱
DWFFH,04H,3,02H,5,02H,5,04H,3,02H
6,02H,6,02H,7,04H,6,04H,6,02H,6,02H,5,02H
DW+1,04H,+1,02H,+1,02H,+1,02H,6,02H,+1,02H,6,02H,
5,10H
DWFFH,04H,3,02H,5,02H,5,04H,5,02H,3,02H,
6,02H,6,02H,7,04H,6,04H,6,02H,6,02H,5,02H
DW+1,04H,+1,02H,+1,02H,+1,02H,6,02H,+1,02H,6,02H,
+2,10H
DW+5,02H,+5,04H,+5,04H,+5,02H,+3,02H,+2,02H
+1,02H,+1,04H,6,04H,+1,02H,6,02H,+1,02H
DW+2,03H,+2,01H,+2,02H,+2,02H,+2,02H,+1,02H,+3,02H,+2,02H
+2,10H
DW+3,02H,+3,04H,+3,02H,+3,02H,+2,02H,+2,02H
+1,02H,+1,04H,+