51单片机模拟音乐详解
来源:互联网 发布:知喻经济发展讲座 编辑:程序博客网 时间:2024/05/11 14:35
想用蜂鸣器模拟出音乐,就需要先把乐谱转换为十六进制数,简单看来音乐就是高低不一,长短不一声的音间隔不同时间的排列组合,所以乐谱改编成十六进制就是三个要素:音符即DO,RE,MI,FA,SO,LA,SI这七个不同音符,音高即高中低三种音,节拍即音符之间的间隔时长.
所以基本思路是用根据这三要素定时器产生音频脉冲,不同音符对应频率如下表:
音符
低
中
高
DO (C)
262
523
1046
RE (D)
294
587
1175
MI (E)
330
659
1318
FA (F)
349
698
1397
SO (G)
392
784
1568
LA (A)
440
880
1760
SI (B)
494
988
1967
每个音符使用1个字节,字节的高4位代表音符的高低,低4位代表音符的节拍,下表为节拍码的对照。但如果1拍为0.4秒,1/4拍是0.1秒,只要设定延迟时间就可求得节拍的时间。假设1/4节拍为1DELAY,则1拍应为4DELAY,以此类推。所以只要求得1/4拍的DELAY时间,其余的节拍就是它的倍数,如下表为1/4和1/8节拍的时间设定。
曲调
1/4拍的延迟时间
1/8拍的延迟时间
4/4
125ms
62ms
3/4
187ms
94ms
2/4
250ms
125ms
下面直接用程序举例(世上只有妈妈好,两只老虎)介绍下基本的编程方法:
#include <reg52.h>
#define uchar unsigned char
sbit beep=P3^6; //定义蜂鸣器输出端口
sbit s1 = P3^5; //定义一个按键以免刚烧写程序就开始响,可以不用
uchar timer0h,timer0l,time;
// 数据表 (音符,音高,节拍)以
code uchar sszymmh[]={
// 世上只有妈妈好 6,2,3, 5,2,1, 3,2,2, 5,2,2, 1,3,2, 6,2,1, 5,2,1,
// 6,2,4, 3,2,2, 5,2,1, 6,2,1, 5,2,2, 3,2,2, 1,2,1,
// 6,1,1, 5,2,1, 3,2,1, 2,2,4, 2,2,3, 3,2,1, 5,2,2,
// 5,2,1, 6,2,1, 3,2,2, 2,2,2, 1,2,4, 5,2,3, 3,2,1,
// 2,2,1, 1,2,1, 6,1,1, 1,2,1, 5,1,6, 0,0,0
//以免刚开始看不清楚,可以用简谱对比看下
// 两只老虎
1,2,2,2,2,2,3,2,2,1,2,2,
1,2,2,2,2,2,3,2,2,1,2,2,
3,2,2,4,2,2,5,2,4,
3,2,2,4,2,2,5,2,4,
5,2,1,6,2,1,5,2,1,4,2,1,3,2,2,1,2,2,
5,2,1,6,2,1,5,2,1,4,2,1,3,2,2,1,2,2,
2,2,2,5,1,2,1,2,4,
2,2,2,5,1,2,1,2,4
};
/*音符频率计算: T = 65536 - 1/Fr/2/MC
T: 要算得的定时器初值
Fr: 各音阶对应的频率
MC: 一个机器周期所需的时间 ,11.0592MHz的晶振对应的机器周期为1.085μs
EX:低音Do对应的频率为262,则T = 65536 - 1/2/1.085/262*(10^6)=63777,对应十六进制数为0xF921,分别写进TH0,和TL0
*/
// 音阶频率表 高八位(计时器初值)
code uchar FREQH[]={0xF2,0xF3,0xF5,0xF5,0xF6,0xF7,0xF8,
0xF9,0xF9,0xFA,0xFA,0xFB,0xFB,0xFC,
0xFC,0xFC,0xFD,0xFD,0xFD,0xFD,0xFE,
0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF,} ;
// 音阶频率表 低八位(计时器初值)
code uchar FREQL[]={0x42,0xC1,0x17,0xB6,0xD0,0xD1,0xB6,
0x21,0xE1,0x8C,0xD8,0x68,0xE9,0x5B,
0x8F,0xEE,0x44, 0x6B,0xB4,0xF4,0x2D,
0x47,0x77,0xA2,0xB6,0xDA,0xFA,0x16,};
void delay(uchar t) // 延时函数 t = 1表示四分之一拍,如果要用到八分之一拍可以改为t2<2000,类推
{
uchar t1;
unsigned long t2;
for(t1=0;t1<t;t1++)
{
for(t2=0;t2<4000;t2++);
}
TR0=0;
}
void song() // 音乐处理函数
{
TH0=timer0h;
TL0=timer0l;
TR0=1;
delay(time);
}
void main(void)
{
uchar k,i;
TMOD=1; //置CT0定时工作方式1
EA=1; //中断全开
ET0=1; //IE=0x82 //CPU开中断,CT0开中断
while(1)
{
i=0;
while(i<100) //音乐数组长度 ,唱完从头再来
{
k=sszymmh[i]+7*sszymmh[i+1]-1;
timer0h=FREQH[k];
timer0l=FREQL[k];
time=sszymmh[i+2];
i=i+3;
if(s1 == 0)
{
song();
}
}
}
}
void t0int() interrupt 1 //定时器0中断函数
{
TR0=0;
beep=!beep;
TH0=timer0h;
TL0=timer0l;
TR0=1;
}
- 51单片机模拟音乐详解
- 详解51单片机播放音乐、电子琴、快进
- 51单片机之音乐代码
- 单片机 音乐
- 51单片机模拟PWM
- 51单片机模拟PWM
- 51单片机模拟交通灯
- 51单片机 使用蜂鸣器播放简单音乐
- 51单片机:独立键盘实现音乐简谱
- 51单片机—用蜂鸣器播放音乐
- 51单片机IO模拟I2C
- 51单片机模拟电梯汇编程序
- 51单片机pwm信号模拟
- 51单片机 软件模拟IIC
- 单片机模拟
- 51单片机寄存器详解
- 51单片机定时器详解
- 51单片机数码管详解
- 常见的浏览器兼容问题
- CCF CSP 公共钥匙盒 JAVA 201709-2 100分
- 动态规划--最大和子序列
- springMVC使用multipartFile上传文件出错:MultipartHttpServletRequest: is a MultipartResolver configured?
- 排序算法总结(js代码实现,思想通用)
- 51单片机模拟音乐详解
- HBuilder ng-的编程回车输入下方显示不重复
- macOSsierra安装U盘制作命令
- Hi3519V101开发环境搭建(二)
- spring管理实务回滚条件:抛出运行时异常的时候
- Postgresql Index —快速理解Index only scan
- blink跨线程解析html有点小问题
- SVM简单解析(21)---《深度学习》
- 32. Longest Valid Parentheses