演示视频见b站https://www.bilibili.com/video/BV1m44y1A7xr/
/************************************************************************
[文件名] C51音乐程序(春节序曲)
[功能] 通过单片机演奏音乐
[实现原理] (1)音乐主要由音符和时值(节拍)组成,这两个部分可以换算成数字参数。
(2)每一个音符对应一个震动频率,通过向无源蜂鸣器输入对应的震荡频率,蜂鸣器就
会发声对应的音符(比如C大调的 do 震动频率为261.6Hz,那么向蜂鸣器输入一个261.6Hz的信号即可)
(3)时值的控制就更简单了,用一个定时器控制每一个音符所震动的持续时间即可
(4)由此可见,音符和时值的控制实际上都可以转化成单片机的计时器控制,那么采用什么方法获得计时器?
答案是用延时函数获得音符的震动频率,用定时器获得时值。
由于时值所需的计时跨度比震动长得多,因此可以考虑采用延时函数得到音符的震动频率,用定时器得到音符的时值。
如果反过来使用,音符频率快速震动导致定时器频繁中断,会非常影响主程序中的延时函数,那么时值就不准了。
(5)因此,编谱实际上就是一个数组,里面包含了延时函数参数、定时器参数,分别对应音符、时值。
本例采用一位数组进行编谱,规则是音符,时值,音符,时值 ....循环往复。另外,为了使谱子书写方便,以及增加
可读性,本例还使用宏定义将每个音符对应的延时函数参数定义成 do re mi fa so等符号,将时值(节拍)对应的
定时器参数定义成全音符、二分音符、四分音符 .....。
/**********************************************************************/
#include <REG52.H>
#include <INTRINS.H>
//本例采用89C52, 晶振为12MHZ
sbit Beep = P1^5; //蜂鸣器管脚
unsigned int n=0; //n为节拍常数变量,取值范围0~65535
/***************D大调音阶宏定义 ,0代表低音,1代表高音**********************************/
/***********每个音符对应几个i(当延时时间=8i+6 us时),具体每个音符频率是多少可以百度*********/
/* Do Do# Re Re# Mi Fa Fa# So So# La La# Si
低音频率(8us) 850 802 757 714 674 636 601 567 535 505 476 450
中音频率(8us) 424 401 378 357 337 318 300 283 267 252 238 224
高音频率(8us) 212 200 189 178 168 159 150 141 133 126 119 112 */
#define Do0 850 //do为专用指令,因此改为大写D
#define Do 424
#define Do1 212
#define Do11 106
#define re0 575
#define re 378
#define re1 189
#define re11 94
#define mi0 674
#define mi 337
#define mi1 168
#define fa0 636
#define fa 318
#define fa1 159
#define so0 567
#define so 283
#define so1 141
#define la0 505
#define la 252
#define la1 126
#define si0 450
#define si 224
#define si1 112
#define B8XZ 0xff //八休止符,本例中只用到八分休止
#define STP 0x00 //结束符
/*********G大调音阶宏定义,GDo为G调的Do,********************************/
/*
Do Do# Re Re# Mi Fa Fa# So So# La La# Si
低音频率(8us) 637 601 567 536 505 477 450 425 401 378 357 337
中音频率(8us) 318 300 283 267 252 238 225 212 200 189 178 168
高音频率(8us) 159 150 141 133 126 119 112 106 100 94 89 84 */
#define GDo0 637
#define GDo 318
#define GDo1 159
#define GDo11 79
#define Gre0 567
#define Gre 283
#define Gre1 141
#define Gre11 70
#define Gmi0 505
#define Gmi 252
#define Gmi1 126
#define Gfa0 477
#define Gfa 238
#define Gfa1 119
#define Gso0 425
#define Gso 212
#define Gso1 106
#define Gla0 378
#define Gla 189
#define Gla1 94
#define Gsi0 337
#define Gsi 168