找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5518|回复: 1
收起左侧

单片机电子琴课程设计论文

[复制链接]
ID:161768 发表于 2017-6-5 01:10 | 显示全部楼层 |阅读模式
《单片机原理及应用》课程设计
一、        电子琴电路功能介绍及组成框图
1、设计要求
由16个按键组成4×4键盘矩阵,设置成16个音,可随意弹奏想要表现的音乐。按下键的同时,显示键号;另外在没有键按下时能播放一首熟悉的音乐。

0.png

二、硬件电路设计
1、总电路
image008.jpg
2、各部分工作原理1 音频电路原理
音频电路原理为整个电子琴设计的核心原理,电路设计方法和编程方法都围绕着电子琴的音频产生、变化的原理来进行。
音频电路中包含一个发音装置。利用电子琴的音频脉冲和节拍的产生原理,通过P3.3口来控制发音装置,产生音符和音乐信号。
1.1)音频脉冲
音乐的产生主要是通过单片机的I/O口输出高低不同的脉冲信号来控制蜂鸣器发音,要想产生音频脉冲信号,需要算出某一音频的周期(1/频率),然后将此周期除以2,即为半周期的时间。利用单片机定时器计时这个半个周期时间,每当计时到后就将输出脉冲的I/O口反相,然后重复计时此半周期时间再对I/O口反相,这样就能在此I/O口上得到此频率的脉冲。通常,利用单片机的内部定时器0,工作在方式1下,改变计数初始值THO和TLO来实现。
例如,若单片机采用12MHz晶振,要产生频率为587Hz的音频脉冲时,其音频信号的脉冲周期 T=1/587=1703.5775μs,半周期的时间为852μs,因此只要令计数器计数=852μs/1μs=852,在每计数852时将I/O口反相,就可得到C调中音Re。
计数脉冲值与频率的关系如下:

频率Hz

周期us

简谱码(定时初值)

音符

频率Hz

周期

us

简谱码(定时初值)

低1Do

262

3816

63628

高1Do

1047

955

65058

低2Re

294

3401

63835

高2Re

1175

851

65110

低3Mi

330

3030

64021

高3Mi

1319

758

65157

低4Fa

349

2865

64103

高4Fa

1397

751

65160

低5So

392

2551

64260

高5So

1568

637

65217

低6La

440

2272

64400

高6La

1760

568

65252

低7Si

494

2024

64524

高7Si

1967

508

65282

中1Do

523

1912

64580

中2Re

587

1703

64684

中3Mi

659

1517

64777

中4Fa

698

1432

64820

中5So

784

1275

64898

中6La

880

1136

64968

中7Si

988

1012

65030

1.2 节拍
每个音符使用一个字节,字节的高四位代表音符的高低,低四位代表音符的节拍,表5-2为节拍与节拍码的对照表。如果1拍为0.4s,1/4拍是0.1s只要设定延迟时间就可求得节拍的时间。假设1/4拍为1个延迟单位时间,那么1拍对应的就是4个延迟单位时间,以此类推。所以只要求得1/4拍的延迟单位时间,其余的节拍就是它的倍数,表5-3为1/4拍和1/8拍的时间设定。
image009.gif 不管采用哪种方法,当歌曲结束时,在发音计数值表(TABLE)中均需加上音乐结束符00H。
2)音符显示
采用的共阴极7段数码管作为音符显示器。当AT89C51执行完按键扫描程序后,所得到的键号送至P0口,通过P0口进而控制数码管的音符字模的显示。另外,P0口作为通用I/O口时,需要外界上拉电阻。
3)矩阵式音符键盘
          采用矩阵式键盘,节省I/O口资源。矩阵式键盘的行线与列线的交叉处不相通,设置为按键,n条行线与m条列线,可构成n*m个按键的键盘。
4)弹奏按键
音符按键采用外部中断1的方式来实现。当按键按下时,调用中断函数切断音乐播放模式,进入音符按键弹奏模式。
三、软件设计
1、程序组成
(1.1)歌曲播放程序
首先,建立音乐代码库:找出乐曲最低音和最高音范围,然后确定音符表T的顺序,把T值建立在数组 T[ ] 中,构成发音符的计数值放在数组tab[ ]中,以音符节拍码00H为音乐结束标记。通过调用音乐代码库来实现演奏歌曲。
image010.jpg [音乐代码库]
image011.jpg [音乐播放程序]
(1.2)键盘音符获取程序
键盘是人与单片机通信的重要接口。合适的键盘扫描程序能使单片机准确的运行。另外,按键按下时,由于弹簧抖动的原因,会对按键有无按下的判断产生干扰,故需要采用适当的消抖方法。本案例采用软件延时的方法去抖动。
image012.jpg image013.jpg [延时去抖动]
image014.jpg [按键扫描]
(1.3)音符显示程序
采用的共阴极7段数码管作为音符显示器,当执行完按键扫描程序后,所得到的键号送至P0口,通过P0口进而控制数码管的音符字模的显示。
image015.jpg [音符获取]
(1.4)弹奏模式程序
通过弹奏按键的按下来产生外部中断,利用中断来实现由歌曲播放模式转到弹奏模式。
image016.jpg [外部中断0函数]
image017.jpg [音符弹奏]
2、流程图
image018.gif
四、设计总结(包括调试软、硬件过程和体会、收获)
附录:
1. 仿真状态图
image019.jpg
2. 程序清单

  1. #include <reg51.h>
  2. #include <absacc.h>
  3. #include <stdio.h>
  4. #include <math.h>
  5. #define uchar unsigned char
  6. #define uint unsigned int
  7. uchar S=0,T=0;        
  8. uchar SH;      
  9. uchar SL;
  10. uchar k, key;
  11. bit flag=1;   
  12. sbit SPK=P3^0;
  13. uchar code DSY_CODE[]= {0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71};
  14. uchar code music[]= {8,9,10,8,8,9,10,8,10,11,12,10,11,12,-1};
  15. uchar code Len[]= {1,1,1,1,1,1,1,1,1,1,2,1,1,2,-1};
  16. uint code tab[]= { 64580,64684,64777,64820,64898,64968,65030,
  17.                      65058,65110,65157,65178,65217,65252,65283};  
  18. //延时
  19. void delay1(uint ms)
  20. { uchar t;
  21.         while(ms--)
  22.         for (t=0;t<120;t++); }

  23. /* 键消抖延时*/
  24.         void delay(void)
  25.         {  uchar i;
  26.                 for (i=300;i>0;i--); }

  27. /* 键扫描函数 */
  28. uchar getkey()
  29.         {
  30.         uchar scode,tcode;
  31.                 if ((P2&0xf0)==0xf0)
  32.                 return(0);
  33.                         scode = 0xfe;
  34.                                  while((scode&0x10)!=0)  
  35.                                 {                     P2 = scode;
  36.                                         if ((P2&0xf0)!=0xf0)  
  37.                                                 {         
  38.                                                  tcode = (P2&0xf0)|0x0f;                                                                                                                   return((~scode)+(~tcode)); }
  39.                                         else scode = (scode<<=1)|0x01;         }
  40.           }
  41. void EX0_INT() interrupt 0
  42. {   flag=0;   }
  43. void time0_int(void) interrupt 1 using 0
  44. {  
  45.         TH0 = SH;
  46.         TL0 = SL;
  47.         SPK=!SPK;
  48.         P0=DSY_CODE[k] ;   }
  49. void main(void) {
  50.         P0=0x3f;
  51.         IE=0x87;
  52.         TMOD=0x01;
  53.         IT0=1;
  54.         IT1=1;
  55.                 while(1)
  56.                 {
  57.                          P2 = 0xf0;                                
  58.                                 if ((P2&0xf0)!=0xf0)  
  59.                                            delay();                       
  60.                                 if ((P2&0xf0)!=0xf0)   
  61.                                  {     key = getkey();  
  62.                                         switch(key)              
  63.                                         {
  64.                                                 case 0x11:k = 0;break;  // 按键1
  65.                                                 case 0x21:k = 1;break;  //         按键2                                       
  66.                                                 case 0x41:k = 2;break;  // 按键3                                                
  67.                                                 case 0x81:k = 3;break;  // 按键4                                                
  68.                                                 case 0x12:k = 4; break;     // 按键5                                                
  69.                                                 case 0x22:k = 5;break;      // 按键6                                                
  70.                                                 case 0x42:k = 6;break;      // 按键7                                                
  71.                                                 case 0x82:k = 7;break;      // 按键8                                                
  72.                                                 case 0x14:k = 8;break;      // 按键9                                                
  73.                                                 case 0x24:k = 9;break;      // 按键10                                       
  74.                                                 case 0x44:k = 10;break;      // 按键11                                       
  75.                                                 case 0x84:k = 11;break;      // 按键12                                       
  76.                                                 case 0x18:k = 12;break;      // 按键13                                       
  77.                                                 case 0x28:k = 13;break;      // 按键14                                       
  78.                                                 case 0x48:k = 14;break;      // 按键15                                       
  79.                                                 case 0x88:k = 15;break;      // 按键16                                       
  80.                                                 default:break;
  81.                                                 }
  82.                                                  if(flag==0) {                                                                                                                SH = tab[k]/256;
  83.                                                      SL = tab[k]%256;
  84.                                                          TR0 = 1;           
  85.                                                          while ((P2&0xf0)!=0xf0);  
  86.                                                          SPK=1;
  87.                                                          TR0 = 0;                                                                                      }
  88.                                                 else
  89.                                                   { while(flag==1)
  90.                                                         {               
  91.                                                                         if (music[T]==-1)T=0;
  92.                                                                         SH=(tab[music[T]])/256;


  93. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

完整课设论文下载(word格式 可编辑)http://www.51hei.com/bbs/dpj-86870-1.html




回复

使用道具 举报

ID:205887 发表于 2017-6-5 07:37 | 显示全部楼层
学习一下,顶一个,
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表