Author: Manba Cople
专业:IOT
说明:记录和输出学习内容

文章目录

  • 前言
  • 定时器
  • 音乐播放
  • 音乐库
  • 总结和展望

前言

程序思路:该程序是利用51单片机的定时器中断,另外根据音符的频率计算每个音符定时时长从而输出不同音符对应的PWM波驱动蜂鸣器播放音乐。
使用工具:Keil4,protues8;程序具体代码和仿真原理图都已打包放到《基于51单片机的MIDI音乐(可切换)》资源,

完整资源链接:51单片机MIDI音乐播放器完整工程.

定时器

 采用13位非自动重装初值模式TMOD=0x00;初值duty由音乐播放函数调用是计算:
duty=460830/music[i];其中460830的由来是:460830=10^6/2/1.085
完整计算计数初值的思路:duty=(1/fren)*10^6/2/机器周期(本文用的11.0592MHz机器周期为:1.085us)

代码如下:

/******************定时器******************/
void Init_Timer0()    //定时器初始化函数
{TMOD=0x00;        //13位非自动TH0=(8192-duty)/32;TL0=(8192-duty)%32;TF0=0;ET0=1;IT0 = 1;         //设置中断EX0 = 1;EA=1;
}void Serve_Timer0() interrupt 1
{TH0=(8192-duty)/32;TL0=(8192-duty)%32;   //重装初值sound=!sound;         //计数值到时输出电平发生反转
}
/******************************************/

音乐播放

 在音乐播放中,不断读入乐谱数组,首先根据乐谱的音阶确定定时器输出的PWM波,其次音乐的每个音符之间有拍子,
即每个音符要输出一定的时间,一般乐谱会标出J=...,单位是每分钟多少拍,因此本文用:t=60*1000/J/2 实现,其中t为
每半拍的时间(可根据自己的乐谱改)。另外,本文    实现三首曲子的切换功能,借助state_INT变量记录开关状态实现。

代码如下:(仅写实现一首,其他代码相同)

/*************音乐播放函数*****************/
void MusicPlayer()
{   unsigned char i=0,j=1,p,t;while(music[i]!=0xff&state_INT==0){t=60*1000/150/2;duty=460830/music[i];      TR0=1;                      //启动定时器T0for(p=0;p<music[j];p++)      //控制节拍数Delay_ms(t);             //延时半个节拍单位TR0=0;                       //关闭定时器T0i+=2;                        //播放下一个音符j+=2;}
}
/******************************************/

音乐库

 音乐库数组,本文格式是:{音阶,拍子,音阶,拍子,...},即在给出音阶的同时就给出对应的拍子, 音阶和拍子的转换思路
如下(本人不是很懂音乐,纯属个人见解):音阶分为高音、中音、低音,在乐谱中根据音阶的标记可知道,数字头上有标记为高音,数字上下没有标记的为中音,数字下部有标记的为低音拍子的大致计算总结:单个数字数字下加下划线表示该音阶拍子是1/2节拍;数字加双下划线就是1/4节拍;数字后加点,该点是1/2节拍,加上前面数字也就是3/2节拍;同理,数字加下划线并且后面加点就是一个节拍,数字后面加横线就是二倍节拍

依据上述总结计算《我和我的祖国》(J=150)乐谱+代码如下:

/**********************我和我的祖国*J=l50**************************************/
unsigned int code music[]=
{ z5,2, z6,2, z5,2, z4,2, z3,2, z2,2,/**/ z1,6, l5,6, /**/z1,2, z3,2, h1,2, z7,2, z6,4, z3,1,/**/z5,6, z5,6, /**/z6,2, z7,2, z6,2, z5,2, z4,2, z3,2, /**/z2,6, l6,6,/**/l7,2, l6,2, l5,2, z5,2, z1,4, z2,1,/**/z3,6, z3,6, /**/z5,2, z6,2, z5,2, z4,2, z3,2, z2,2, /**/z1,6, l5,6,/**/z1,2, z3,2, h1,2, z7,2, h2,4, h1,1, /**/z6,6, z6,6,/**/h1,2, z7,2, z6,2, z5,6,/**/ z6,2, z5,2, z4,2, z3,6,/**/l7,4, l6,2, l5,4, z2,2,/**/z1,6, z1,6,/**/h1,2, h2,2, h3,2, h2,2, h1,2, z6,2, /**/z7,2, z6,4, z3,1, z5,6, z5,6, /**/h1,2, h2,2, h3,2, h2,2, h1,2, z6,2,/**/z7,2, z5,4, z3,1, z6,6, z6,6, /**/z5,2, z4,2, z3,2, z2,6, /**/l7,2, l6,1, l6,1, l5,2, z3,6, /**/z4,6, z2,4, z1,2, /**/z1,6, z1,6, /**/h1,2, h2,2, h3,2, h2,2, h1,2, z6,2, /**/z7,2, z6,4, z3,1, z5,6, /**/h1,2, h2,2, h3,2, h2,2, h1,2, z6,2, /**/z7,2, z5,4, z3,1, z6,6, /**/z5,2, z4,2, z3,2, z2,6, /**/l7,2, l6,2, l5,2, z3,6,/**/ z5,6, h2,4, h1,2, /**/h1,6,z1,12, /**/0xff/*停止标志位*/
};
/******************************************************************************/

另外音阶的定义如下:

/*****************音阶对应频率**********************/
#define l1 262    //将“l_dao”宏定义为低音“1”的频率262Hz
#define l2 286    //将“l_re”宏定义为低音“2”的频率286Hz
#define l3 311    //将“l_mi”宏定义为低音“3”的频率311Hz
#define l4 349    //将“l_fa”宏定义为低音“4”的频率349Hz
#define l5 392    //将“l_sao”宏定义为低音“5”的频率392Hz
#define l6 440    //将“l_a”宏定义为低音“6”的频率440Hz
#define l7 494    //将“l_xi”宏定义为低音“7”的频率494Hz
//以下是C调中音的音频宏定义
#define z1 523     //将“dao”宏定义为中音“1”的频率523Hz
#define z2 587     //将“re”宏定义为中音“2”的频率587Hz
#define z3 659     //将“mi”宏定义为中音“3”的频率659Hz
#define z4 698     //将“fa”宏定义为中音“4”的频率698Hz
#define z5 784     //将“sao”宏定义为中音“5”的频率784Hz
#define z6 880     //将“la”宏定义为中音“6”的频率880Hz
#define z7 987     //将“xi”宏定义为中音“7”的频率523H
//以下是C调高音的音频宏定义
#define h1 1046    //将“h_dao”宏定义为高音“1”的频率10
#define h2 1174    //将“h_re”宏定义为高音“2”的频率11
#define h3 1318    //将“h_mi”宏定义为高音“3”的频率13
#define h4 1396    //将“h_fa”宏定义为高音“4”的频率1396
#define h5 1567    //将“h_sao”宏定义为高音“5”的频率1567
#define h6 1760    //将“h_la”宏定义为高音“6”的频率1760Hz
#define h7 1975    //将“h_xi”宏定义为高音“7”的频率19
/**********************************************************/

总结和展望

 本文较完整的实现了51单片机定时器中断写MIDI音乐切实现了音乐的切换。改进的地方:超低音、超高音的实现,乐谱休止符等详细乐理内容的加入,使音乐
更加完美的呈现;对于代码,在音乐播放函数有较高的代码重用度可想办法优化,定义音阶对应频率可优化为数组。

【51MCU】51单片机定时器中断写MIDI音乐(按键可切换音乐)相关推荐

  1. c语言单片机定时器的应用程序,51单片机定时器中断程序(C语言)

    51c程序 51单片机定时器中断程序(C语言) 用C语言实现的,先要定义好定时器的初值 不管你使用多大的晶振,使用51单片机,一般都是12分频出来,也就可以得出一个机器周期 机器周期=12/n(n指晶 ...

  2. 51单片机定时器中断怎么用-------51单片机基础篇

    首先,什么时定时器,简单来说可以比喻为一个闹钟,当你把他打开以后,他就会每秒动一下,+1,+1,+1,+1,如果你设置了某一个时间点闹钟会向以后,那么当闹钟的时间点+1,+1,+1,+到了你设置的时间 ...

  3. 51单片机——定时器中断

    新版51单片机内部有3个16位可编程的定时器/计数器,即定时器T0,T1,T2.他们既有定时功能又有计数功能,我们可以通过配置与它们相关的特殊功能寄存器可以选择启用定时功能或计数功能:其中需要注意的是 ...

  4. 51单片机定时器中断TMOD

    最近在学定时器中断TMOD,写程序时,要对定时器进行配置 对TMOD进行赋值时,拌了好久.... 如何根据所用的     定时器0/1,  工作方式0/1/2/3     对TMOD赋值呢? 我们知道 ...

  5. 单片机定时报警C语言程序,51单片机 定时器 中断程序 (C语言)

    EA     是 中断总开关, 不管是定时器,串口还是外部中断,都需要打开 EA 才能触发中断; ET0   是 定时器0 的专用中断开关, 也就是说: 打开了EA.而不打开ET0,定时器0是无法触发 ...

  6. 51单片机-定时器中断

    目录 1.定时器/计数器 1.1.工作原理 1.2.相关寄存器 1.3.工作模式(模式1) 2.中断系统 2.1.中断的概念 2.2.中断结构 2.3.中断源 2.4.相关寄存器 3.如何配置定时器中 ...

  7. 51单片机定时器中断按键消抖(无延时)

    单片机入门学习记录(二) 在机械按键的触点闭合和断开时,都会产生抖动,为了保证系统能正确识别按键的开关,就必须对按键的抖动进行处理.按键的抖动对于人类来说是感觉不到的,但对单片机来说,则是完全可以感应 ...

  8. 51单片机——定时器中断实现跑马灯仿真

    keil 程序 #include <REGX51.H> void Timer0_init() {TMOD&=0XF0;//定时器配置TMOD|=0X01;TF0=0;TR0=1;T ...

  9. 51单片机定时器/计数器(定时器中断)

    51单片机定时器/计数器(中断系统:定时器中断) 实现功能 通过定时器终端控制LED灯 D1 间隔一秒闪烁 单片机型号:STC89C52 定时器介绍 1.51单片机定时器原理 定时器实质上就是一个加1 ...

最新文章

  1. c#如何将多个json合并_合并两个c#对象(json)列表作为父级子级
  2. Web服务器指纹识别工具httprint
  3. PowerShell攻防进阶篇:nishang工具用法详解
  4. Node基础: 回调函数 2
  5. 如何用html绘制阴影图形,HTML5 给图形绘制阴影
  6. Hibernate Validator用法
  7. Java并发编程(五):Java线程安全性中的对象发布和逸出
  8. mybatis异常invalid comparison: java.util.Date and java.lang.String
  9. WSDM Cup 2020大赛金牌参赛方案全解析
  10. sql server 恢复数据库时提示有其他用户连接,怎么办?
  11. 获取任务管理器中进程的Memory(Private Working Set)
  12. PLSQL导出表结构SQL
  13. android 下载apk后如何安装程序,Android下载并安装APK
  14. 怎么样申请9位的QQ?
  15. 数值分析基础工具使用Matlab绘制双曲线
  16. 广东计算机一级试题答案,广东计算机一级考试试题和答案
  17. 银河麒麟、中标麒麟学习实操资料汇总(含V4、V7、V10)
  18. C语言:编写程序把你的年龄转换成天数,不考虑闰年。
  19. 【Docker】Docker可视化管理工具Portainer
  20. SIMO EMS 技术支持

热门文章

  1. c全日制聋校实验教材语言训练教参小学1册,聋哑学校课程设置建议(2)
  2. 【渝粤题库】陕西师范大学164116 网络资源优化与推广 作业 (高起专)
  3. PAT --- 1071.小赌怡情 (15 分)
  4. Apache Http Server 解决不同域名共用服务器80端口问题
  5. 【技术】浅析磁传感器HALL、AMR、GMR、TMR技术
  6. OpenStack-Storage(6)
  7. 【免费分享】让思路更清晰,思维导图教程及工具
  8. MySQL约束条件及外键的关系
  9. XML学习笔记 第二记
  10. 浅析:如何选择关键词