电子琴实验报告

电子琴实验报告

一, 实验目的

1. 学习使用AT89S52单片机的功能,进行单片机编程,实现键盘演奏音乐的功能,进一步加深对于单片机功能实现过程的理解,强化单片机编程的能力。

2. 设计实现各种功能,包括对音乐的录音以及回访放能,要求能实现各种不同音调,在编程过程中必须考虑到各种细节,例如按键的干扰问题以及滞键。

二,实验要求

基本要求:

1:能够通过键盘演奏音符。

2:能够保存演奏的音乐,并实现回放。

3:有音调调整功能(如:C调,G调)。

4: 自由发挥其他功能.

5: 要求有单片机硬件系统框图,电路原理图,软件流程图。

三,实验基本原理

在单片机的设计中,电子琴是一个典型的例子,电子琴的实现需要用到单片机AT89S52、蜂鸣器等模块。而在本次的实验中,我们利用简单的模块,实现了一个简单的电子琴功能,使用单片机可以驱动蜂鸣器发出声音,还可以控制其发出不同的音调,在一首歌曲里面,不同的音阶对应着不同的频率,在蜂鸣器的发音原理里面,我们只需要给蜂鸣器输入不同的脉冲,蜂鸣器就会发出对应的声音,因此,我们只需要弄明白音阶对应的脉冲就可以了。

    在键盘控制中,每个按键对应不同的音阶,按键按下的时候,单片机程序里面都会执行一次程序判断是否有前一次的按键被按下,按键按下以后会控制单片机对蜂鸣器输出不同频率的方波,每种情况对应不同的音阶或者音调。一首歌曲就是有不同的音阶构成,从而就实现了电子琴的功能。

四,实验设计分析

针对要实现的功能,采用AT89S52单片机进行设计,AT89S52单片机是一款低功耗,高性能CMOS8位单片机,片内含4KB在线可编程(ISP)的可反复擦写1000次的Flash只读程序存储器,器件采用高密度、非易失性存储技术制造,兼容标准MCS- 51指令系统及80C51引脚结构。这样,既能做到经济合理又能实现预期的功能。

在设计程序的时候,分析道电子的功能有三个模块构成,分别是单片机本身,键盘按键输入和蜂鸣器的功能响应。首先应该把程序分开成三个主要部分,分别为按键输入程序、高低音的发生程序和主程序。需要注意的是设计程序的时候,需要把各个程序兼容起来,综合匹配的时候,还要注意各种单片机编程的小细节。

在进行编程之前,需要安装各种必须的软件,包括编程用的ukeil软件、模拟程序运行的Progisp软件,最重要的是电脑必须安装正确的单片机驱动程序。硬件部分需要我们学生自己动手焊制,在焊制的时候一定要保证原件的完好连接,从而保证在运行程序的过程中不会出现硬件问题的影响。编程之前,需要先学习理解C语言编程的方法,再根据设计的硬件电路进行分块的编程调试,最终完成程序设计。

五,实验要求实现

A.电路设计

1. 整体设计

此次设计主要是应用单片机来设计电子时钟,硬件部分主要分以下电路模块:显示电路用8个共阴数码管分别显示,星期(年份),小时、分钟(月份)和秒(日),通过动态扫描进行显示,从而避免了译码器的使用,同时节约了I/0端口,使电路更加简单。单片机采用AT89S51系列,这种单片机应用简单,适合电子钟设计。

电路的总体设计框架如下:

 

B. 程序总体设计

本实验用汇编程序完成.

程序总的流程图如下:

                          

结合电路图,程序设计的整体思路为:

接通电源,执行程序,在程序至此那个过程中各个按键代表不同的功能,下面是不同状态下各个按键的实现目标方式:

在程序执行开始时,先判断之前是否有按键按下,若之前没有按键按下:

     按1键--蜂鸣器发出Do的声音;

按2键--蜂鸣器发出Rei的声音;

按3键--蜂鸣器发出Mi的声音;

按4键--蜂鸣器发出Fa的声音;

按5键--蜂鸣器发出Suo的声音;

按6键--蜂鸣器发出La的声音;

按7键--蜂鸣器发出Xi的声音;

按8键--蜂鸣器发出程序里本来自带的的声音;

按9键--系统执行录音功能,开始录音;

按10键--蜂鸣器发出录音功能执行时所录下的声音;

按11键—系统进入调音的功能,改变输出声音的音调。

    在执行录音功能的时候,当你按下录音键以后,每按下键盘里的1——7键的其中一个,系统就会以数组的形式记录下这一按键代表的数字,在你按下回放录音的10键的以后,系统就会从数组里一次取出值,把录下的声音重新播放出来。

B.2.3主程序

//按键1-7分别代表"DO"~"XI",第八个键保存一首歌曲,第九个键控制录音开始和停止,第十个键播放录音,第十一个键调节音调

#include<reg52.h>

#define uchar unsigned char

#define uint unsigned int

uchar i,j,x=0,y=0,k,u=0,temp=0;

uchar m[100];

sbit sound=P0^1;

void keyscan();

void musicH(uchar);

void musicL(uchar);

uchar code c[]={3,3,4,5,5,4,3,2,1,1,2,3,3,2,

                2,0,3,3,4,5,5,4,3,2,1,1,2,3,

                2,1,1,0,2,2,3,1,2,3,4,3,1,2,

                3,4,3,1,1,2,5,0,3,3,4,5,5,4,

                3,2,1,1,2,3,2,1,1};

void delay(uint a)

{while(a--);}

void main(){

   while(1){

        sound=1;

        keyscan();

    }

  

}

void keyscan() 

{

unsigned char X,Y,Z;

P3=0x0f;

if(P3!=0x0f) //判断是否有键按下

    {

    delay(10); //延时,软件去干扰

    if(P3!=0x0f) //确认按键按下

        {

        X=P3; //保存行扫描时有键按下时状态

        P3=0xf0;

        Y=P3;  

        Z=X|Y;

switch ( Z )

            {

                case 0xee: if(u==0)musicL(1); else musicH(1);if(y==1){m[x]=1;x++;}

                        break;

                case 0xed: if(u==0)musicL(2); else musicH(2);if(y==1){m[x]=2;x++;}

                        break;

                case 0xeb: if(u==0)musicL(3); else musicH(3);if(y==1){m[x]=3;x++;}

                        break;

                case 0xe7: if(u==0)musicL(4); else musicH(4);if(y==1){m[x]=4;x++;}

                        break;

                case 0xde: if(u==0)musicL(5); else musicH(5);if(y==1){m[x]=5;x++;}

                        break;

                case 0xdd: if(u==0)musicL(6); else musicH(6);if(y==1){m[x]=6;x++;}

                        break;

                case 0xdb: if(u==0)musicL(7); else musicH(7);if(y==1){m[x]=7;x++;}

                        break;

                case 0xd7: for(j=0;j<66;j++){musicL(c[j]);sound=1;delay(6000);}//播放

                        break;

                case 0xbe: if(y==0){y=1;x=0;}else {y=0;}//准备录音

                        break;

                case 0xbd: for(j=0;j<(x+1);j++){musicL(m[j]);sound=1;delay(6000);}//播放录音

                        break;

                case 0xbb: if(temp==0){u=1;temp++;} else {u=0;temp=0;}//调音

                        break;

               

            }

         }

    }

}

void musicL(uchar b)//低音

{

    switch(b){

       

            case 1:for(i=0;i<66;i++){sound=1;delay(140);sound=0;delay(140);}

                    break;

            case 2:for(i=0;i<74;i++){sound=1;delay(123);sound=0;delay(123);}

                    break;

            case 3:for(i=0;i<82;i++){sound=1;delay(111);sound=0;delay(111);}

                    break;

            case 4:for(i=0;i<88;i++){sound=1;delay(103);sound=0;delay(103);}

                    break;

            case 5:for(i=0;i<99;i++){sound=1;delay(92); sound=0;delay(92);}

                    break;

            case 6:for(i=0;i<110;i++){sound=1;delay(83);sound=0;delay(83);}

                    break;                             

            case 7:for(i=0;i<122;i++){sound=1;delay(74);sound=0;delay(75);}

                    break;

        }

}

void musicH(uchar b)//高音

{

    switch(b)

        {

            case 1:for(i=0;i<131;i++){sound=1;delay(68);sound=0;delay(68);}

                    break;

            case 2:for(i=0;i<147;i++){sound=1;delay(61);sound=0;delay(61);}

                    break;

            case 3:for(i=0;i<165;i++){sound=1;delay(54);sound=0;delay(54);}

                    break;

            case 4:for(i=0;i<175;i++){sound=1;delay(51);sound=0;delay(51);}

                    break;

            case 5:for(i=0;i<196;i++){sound=1;delay(45);sound=0;delay(45);}

                    break;

            case 6:for(i=0;i<220;i++){sound=1;delay(40);sound=0;delay(40);}

                    break;                             

            case 7:for(i=0;i<245;i++){sound=1;delay(35);sound=0;delay(35);}

                    break;

        }

}C. 程序调试及仿真

本程序通过Keil单片机开发平台实现程序的编译,链接,生成HEX文件。程序再编译过程中可以发现错位,并及时改正,在设计时非常重要,使错误被扼杀在摇篮中。

通过Keil和硬件仿真平台Proteus的联合,可以将设计效果仿真出来,根据效果,有目的的改变设计,优化程序。

c.1 利用Keil软件实验过程截图:

五.实验总结及感想

在这个小学期中,我们进行了一系列的创新训练,其中就包括这个电子琴的设计。刚开始的时候,我们所有人都只是门外汉,面对着这一堆从来没有面对过的题目,都是不知所措,心理面一点底都没有。只知道我们只有将近一个月的时间去完成所有的设计,最困难的是我们以前根本就没有学习过单片机编程。

所谓动力的来源就是压力,面对着这巨大的压力,我们一组13个人开始了紧张的学习工作。在组长的带领下,我们首先开始了对单片机编程的学习,学习怎么使用ukeil软件编程。对于这个编程软件,我们都是一无所知,只能慢慢的摸索着前进。另外,我们也开始了解AT89S52单片机的各种功能,了解到单片机有诸如定时器/计时器、控制四个不同管脚的输出等功能。跟它配套的还有各个功能模块,例如4X4键盘、跑马灯、并行数码管和蜂鸣器等。每个模块的不同组合能够实现各种功能,例如十字交通灯、计算器、电子琴等等。经过了十多天的自主学习还有参加各种讲座,我们对这终于有了一定的认识了,开始走上了程序员的道路。

在编程的过程中,遇到了很多问题,接下来总结一下:

1,      在执行程序时,按下键盘里的时候,往往得不到想要的声音,每次按下去以后,鸣器都会响好多下,以至于根本就听不清按下的效果到底是一次还是多次,开始一直以为是蜂鸣器的硬件问题,就没有去管,可是换了多个蜂鸣器以后,情况并没有改善,开始怀疑是不是程序的问题。后来通过小组成员之间的讨论得知,是由于按键的滞键问题,每次按下去以后,按键在弹回来的过程中会出现多次接触的情况,这样就会导致之前说的问题。然后就开始想解决方法,经过多次的尝试以后,觉得只要在每次按键取值以后都加一个适当的延时程序,就可以避免滞键的影响。但是延时的时间必须严格控制好,太长会影响下一次的按键,太少却不能得到想要的效果。经过反复的实践,终于确定了一个相对最佳的时间,从而解决了滞键的问题。

2,      另一个执行中的问题就是在执行同一个程序时,每次得到的结果居然不一样。在执行录音功能的时候,每次按下9键的时候,有的情况下根本就录不到音,而有的时候却可以。这个问题让我们非常头疼,因为基本上可以否定是程序的本质错误或者是硬件问题,而编程时有没有出现错误。后来经过网上查询,查看别人的经验,终于把问题确定下来。应该是我们在编程的时候,忽略了开始时刻单片机对第一个按键的记忆,要是程序开始的时候没有清除上个键的影响,就不能准确执行下一次的程序,所以在改进时,我们加入了判定程序,在程序运行开始时,先判定键盘输入的状态,清除上一次残留的状态,并将键盘的状态初始化,加入一个判断就好了。

通过这次的实验设计,我们学会了如何使用单片机去实现电子琴的功能,虽然只是一个简略版的电子琴功能,可是已经花费了我全组人的很多心血,每一行代码都是我们辛苦的成果。通过这次的团体协作,相信我们除了在学习方面得到了很大的提高以外,还学会了如何进行团体的工作,组长学会如何去领导一群人工作,组员学会了如何去分工合作,这对于我们未来的人生事业有着很大的影响。相信我们会在以后的工作中能够做的更好。

 

第二篇:电子琴实验报告

                          电子琴实验报告

一, 实验目的

1.进一步巩固和加深理论课基本知识的理解,提高综合运用所学知识的能力。 2.能根据需要选择参考书,查阅资料,通过独立思考,深入钻研有关问题。3.学会自己独立分析问题、解决问题。

4.学习按键扫描及蜂鸣器应用和单片机设计方法。

5. 设计任务及要求 利用实验平台上矩阵键盘和蜂鸣器及单片机设计实现要求的电子琴。

二,实验要求

A.基本要求:

1:能够通过键盘演奏音符。

2:能够保存演奏的音乐,并实现回放。

3:有音调调整功能(如:C调,G调)。

三,实验基本原理

1.键盘接口必须具有去抖动、按键识别基本功能。
    (1)去抖动:每个按键在按下或松开时,都会产生短时间的抖动。抖动的持续时间与键的质量相关,一般为5—20mm。所谓抖动是指在识别被按键是必须避开抖动状态,只有处在稳定接通或稳定断开状态才能保证识别正确无误。去抖问

题可通过软件延时或硬件电路解决。
       

     (2)被按键识别:如何识别被按键是接口解决的主要问题,一般可通过软硬结合的方法完成。常用的方法有行扫描法和线反转法两种。行扫描法的基本思想是,由程序对键盘逐行扫描,通过检测到的列输出状态来确定闭合键,为此,需要设置入口、输出口一个,该方法在微机系统中被广泛使用。线反转法的基本思想是通过行列颠倒两次扫描来识别闭合键,为此需要提供两个可编程的双向输入/输出端口。
   2利用键盘扫描原理分别设4×4矩阵键盘组成1—7数字键演奏音符,蜂鸣器发声,高电平发声,低电平不发声,并通过延迟程序控制输入的频率,不同的频率发出不同的音符,

四,实验设计分析

针对要实现的功能,采用AT89S52单片机进行设计,AT89S52 单片机是一款低功耗,高性能CMOS8位单片机,片内含4KB在线可编程(ISP)的可反复擦写1000次的Flash只读程序存储器,器件采用高密度、非易失性存储技术制造,兼容标准MCS- 52指令系统及80C52引脚结构。这样,既能做到经济合理又能实现预期的功能。

在程序方面,采用分块设计的方法,这样既减小了编程难度、使程序易于理解,又能便于添加各项功能。程序可分为键盘演奏程序、音乐播放程序、音调调整程序,保存音乐程序,延时程序等。运用这种方法,关键在于各模块的兼容和配合,若各模块不匹配会出现意想不到的错误。

首先,在编程之前必须了解硬件结构尤其是各引脚的用法,以及内部寄存器、存储单元的用法,否则,编程无从下手,电路也无法设计。这是前期准备工作。第二部分是硬件部分:依据想要的功能分块设计设计,比如输入需要开关电路,输出需要显示驱动电路和数码管电路等。第三部分是软件部分:先学习理解汇编语言的编程方法再根据设计的硬件电路进行分块的编程调试,最终完成程序设计。第四部分是软件画图部分:设计好电路后进行画图,包括电路图和仿真图的绘制。第五部分是软件仿真部分:软硬件设计好后将软件载入芯片中进行仿真,仿真无法完成时检查软件程序和硬件电路并进行修改直到仿真成功。第六部分是硬件实现部分:连接电路并导入程序检查电路,若与设计的完全一样一般能实现想要的功能。最后进行功能扩展,在已经正确的设计基础上,添加额外的功能!

五,实验要求实现

A.电路设计

1. 整体设计

2. 分块设计

模块电路主要分为:键盘输入部分、播放部分、复位电路。

2.1键盘输入模块

键盘接入单片机P3接口,

2.2播放模块

播放模块是蜂鸣器构成。蜂鸣器是一种一体化结构的电子讯响器,采用直流

图2-3   发声模块电路图

电压供电,广泛应用于计算机、打印机、复印机、报警器、电子玩具、汽车电子

设备、电话机、定时器等电子产品中作发声器件。蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型。蜂鸣器在电路中用字母“H”或“HA”(旧标准用“FM”、“LB”、“JD”等)表示。而且由于所需驱动功率较小,且价格低廉,所以,被广泛应用。

2.3 复位电路

AT89S52复位模块

 AT89S52晶振模块

各模块拼接组合,电路总体设计图如下:

B.程序设计

B.1 程序总体设计

本实验用C程序完成.

流程图如下:

结合电路图,程序设计的整体思路为:

电子琴按键方式:

1.  按1键——发声音符为‘1’。

2.  按2键——发声音符为‘2’。

3.  按3键——发声音符为‘3’。

4. 按4键——发声音符为‘4’。

5.  按5键——发声音符为‘5’。

6.  按6键——发声音符为‘6’。

7.  按7键——发声音符为‘7’。

8.   按8键——播放保存的音乐。

9.   按9键——开始录音。

10. 按10键——播放录音。

11. 按11键——调整音调。

B.2 程序主要模块

主程序:

#include<reg52.h>

#define uchar unsigned char

#define uint unsigned int

uchar i,j,x=0,y=0,temp=0,u=0;                                  

uchar code c[]={3,3,4,5,5,4,3,2,1,1,2,3,3,2,2,0,3,3,4,5,5,4,3,2,1,1,2,3,2,1,1,0,2,2,3,1,2,3,4,3,1,2,3,4,3,1,1,2,5,0,3,3,4,5,5,4,3,2,1,1,2,3,2,1,1};

uchar m[100];              

void delay(uint a)

{while(a--);}

void music(uchar b)

{

switch(b){

   

        case(1):for(i=0;i<66;i++){P2=0xff;delay(140);P2=0x00;delay(140);}break;

        case(2):for(i=0;i<74;i++){P2=0xff;delay(123);P2=0x00;delay(123);}break;

        case(3):for(i=0;i<82;i++){P2=0xff;delay(111);P2=0x00;delay(111);}break;

        case(4):for(i=0;i<88;i++){P2=0xff;delay(103);P2=0x00;delay(103);}break;

        case(5):for(i=0;i<99;i++){P2=0xff;delay(92);P2=0x00;delay(92);}break;

        case(6):for(i=0;i<110;i++){P2=0xff;delay(83);P2=0x00;delay(83);}break;                 

        case(7):for(i=0;i<122;i++){P2=0xff;delay(74);P2=0x00;delay(75);}break;

    }

}

void musicH(uchar b)

{

switch(b)

    {

        case(1):for(i=0;i<131;i++){P2=0xff;delay(68);P2=0x00;delay(68);}break;

        case(2):for(i=0;i<147;i++){P2=0xff;delay(61);P2=0x00;delay(61);}break;

        case(3):for(i=0;i<165;i++){P2=0xff;delay(54);P2=0x00;delay(54);}break;

        case(4):for(i=0;i<175;i++){P2=0xff;delay(51);P2=0x00;delay(51);}break;

        case(5):for(i=0;i<196;i++){P2=0xff;delay(45);P2=0x00;delay(45);}break;

        case(6):for(i=0;i<220;i++){P2=0xff;delay(40);P2=0x00;delay(40);}break;                         

        case(7):for(i=0;i<245;i++){P2=0xff;delay(35);P2=0x00;delay(35);}break;

    }

}

void scan()

{      

        P3=0x0f;   

     if(P3==0x0e)

        {

                    P3=0xf0;

                    switch(P3)

                        {

                            case(0x70):if(u==0)music(1); else musicH(1);if(y==1){m[x]=1;x++;}break;

                            case(0xb0):if(u==0)music(2); else musicH(2);if(y==1){m[x]=2;x++;}break;

                            case(0xd0):if(u==0)music(3); else musicH(3);if(y==1){m[x]=3;x++;}break;

                            case(0xe0):if(u==0)music(4); else musicH(4);if(y==1){m[x]=4;x++;}break;

                        }

        }

           

        else if(P3==0x0d)

                            {

                                P3=0xf0;

                                switch(P3)

                                            {

                                                case(0x70):if(u==0)music(5); else musicH(5);if(y==1){m[x]=5;x++;}break;

                                                case(0xb0):if(u==0)music(6); else musicH(6);if(y==1){m[x]=6;x++;}break;

                                                case(0xd0):if(u==0)music(7); else musicH(7);if(y==1){m[x]=7;x++;}break;

                                            case(0xe0):for(j=0;j<66;j++){music(c[j]);P2=0xff;delay(6000);}  break;//保存一首歌

                                            }

                            }

        else if(P3==0x0b)

                            {

                                        P3=0xf0;

                                        switch(P3)

                                            {

                                                case(0x70):if(y==0){y=1;x=0;music(1);}else {y=0;music(1);}break;//录音开始和停止

                                            case(0xb0):for(j=0;j<(x+1);j++){music(m[j]);P2=0xff;delay(6000);}break;//播放录音

                                                case(0xd0):if(temp==0){u=1;temp++;} else {u=0;temp=0;}break;//调节音调

                                            }

                            }

}

   

                   

void main()

{

while(1){

P2=0xff;

scan();

}

}

C. 程序调试及仿真

本程序通过Keil单片机开发平台实现程序的编译,链接,生成HEX文件。程序再编译过程中可以发现错位,并及时改正,在设计时非常重要,使错误被扼杀在摇篮中。

通过Keil和硬件仿真平台Proteus的联合,可以将设计效果仿真出来,根据效果,有目的的改变设计,优化程序。

c.1 利用Keil软件实验过程截图:

1,建一个工程,并设定与Proteus仿真相关的参数

2,编译程序,并生成HEX文件

c.2利用Proteus仿真实验过程截图:

五.实验总结及感想

本次实验制作简易电子琴,虽然花费了我们很多精力,但收获颇丰,一方面,将自己的理论知识与实践相结合起来,进一步巩固了专业基础知识和相关专业课程知识;另一方面,也培养了自己独立自主、综合分析的思维与创新能力,更让我知道了团队的力量是巨大的。

 实验中将程序烧入芯片,调试成功后,可任意弹奏自己想要的旋律。本研究通过制作电子琴,将几个模块很好的融合起来,对使用单片机设计简易电子琴进行了分析,并介绍了基于单片机电子琴统硬件组成。利用单片机产生不同频率来获得我们要求的音阶,最终可随意弹奏想要表达的音乐。说明一首音乐是许多不同的音阶组成的,而每个音阶对应着不同的频率,这样我们就可以利用不同的频率的组合,即可构成我们所想要的音乐了,因此,我们只要把一首歌曲的音阶对应频率关系弄正确即可,然后我们利用功放电路来将音乐声音放大,同时通过显示模块来确知自己所弹的音符。

思考:可弹奏的音符数较少,只能在一定范围内满足用户需要。可通过改进键盘识别模块和发生模块来增加其复杂度。音色不可调,只有一种波形的频率输出。可以在外围电路设计滤波电路,接在不同的输出口,通过软件实现不同端口的输出,从而接入不同的滤波电路,输出不同的波形,从而获得不一样的音色。不能以和弦形式演奏,只能单个键按下输出单个的音阶。

设计的过程不是一帆风顺,遇到过各种各样的问题。特别是设计软件时,一些很细小的问题都可能导致功能性的错误,修改了多次才通过仿真。在设计过程中我发现自己对以前所学过的知识理解得不够深刻,掌握得不够牢固,所以也利用图书馆、网络资源查阅了大量文献资料,也请教了老师和同学。同时在具体的制作过程中我们发现一些书本上的知识与实际的应用存在着一定的差距,书本上的知识很多都是理想化后的结论,忽略了很多实际的因素,或者涉及的不全面,可在实际的应用时这些是不能被忽略的,我们不得不考虑这方面的问题,这也让我更深刻地体会到在今后的学习工作中也要注重理论联系实际。

六、参考书目

[1] 李群芳,肖看,《单片机原理、接口及应用》,北京,清华大学出版社,20##年

[2] 戴佳,戴卫恒 ,《51单片机C语言应用程序设计实例精讲》 , 电子工业出版社,20##年

[3] 刘海成,《单片机及应用系统设计原理与实践》,北京,北京航空航天大学出版社,20##年

相关推荐