嵌入式必备能力之蜂鸣器唱歌
本片文章主要参考“江科大自化协”B站内容
主程序 main
//区别<>和"",<>为系统库,而""为程序员自定义库,需要令创.h文件
//本代码歌曲《天空之城》
#include <REGX52.H>
#include "delayms.h"
#include "timer0.h"
//蜂鸣器端口
sbit buzzer = P1^7;
//播放速度,值为四分音符时长
#define SPEED 500
//音符(若切换音乐,这里不用改)
/*P:休止符
L:低音
M:中音
H:高音
_:升半音符号
*/
#define P 0
#define L1 1
#define L1_ 2
#define L2 3
#define L2_ 4
#define L3 5
#define L4 6
#define L4_ 7
#define L5 8
#define L5_ 9
#define L6 10
#define L6_ 11
#define L7 12
#define M1 13
#define M1_ 14
#define M2 15
#define M2_ 16
#define M3 17
#define M4 18
#define M4_ 19
#define M5 20
#define M5_ 21
#define M6 22
#define M6_ 23
#define M7 24
#define H1 25
#define H1_ 26
#define H2 27
#define H2_ 28
#define H3 29
#define H4 30
#define H4_ 31
#define H5 32
#define H5_ 33
#define H6 34
#define H6_ 35
#define H7 36
//频率
unsigned int FreqTable[]={
0,
63472,63584,63697,63797,63897,63987,64074,64156,64233,64307,64376,64441,
64502,64560,64615,64667,64715,64761,64805,64846,64885,64921,64956,64989,
65020,65048,65076,65102,65126,65149,65171,65191,65210,65229,65246,65262
};
//乐谱
unsigned char code Music[]={
//1
P, 4, P, 4, P, 4, M6, 2, M7, 2,
H1, 4+2,M7, 2, H1, 4, H3, 4,
M7, 4+4+4, M3, 2, M3, 2,
//2
M6, 4+2,M5, 2, M6, 4, H1, 4,
M5, 4+4+4, M3, 4,
M4, 4+2,M3, 2, M4, 4, H1, 4,
//3
M3, 4+2,P, 2, H1, 2, H1, 2, H1, 2,
M7, 4+2,M4_,2, M4_,4, M7, 4,
M7, 4+4,P, 4, M6, 2, M7, 2,
//4
H1, 4+2,M7, 2, H1, 4, H3, 4,
M7, 4+4+4, M3, 2, M3, 2,
M6, 4+2, M5, 2, M6, 4, H1, 4,
//5
M5, 4+4+4, M2, 2, M3, 2,
M4, 4, H1, 2, M7, 2+2, H1, 2+4,
H2, 2, H2, 2, H3, 2, H1, 2+4+4,
//6
H1, 2, M7, 2, M6, 2, M6, 2, M7, 4, M5_,4,
M6, 4+4+4, H1, 2, H2, 2,
H3, 4+2,H2, 2, H3, 4, H5, 4,
//7
H2, 4+4+4, M5, 2, M5, 2,
H1, 4+2, M7, 2, H1, 4, H3, 4,
H3, 4+4+4+4,
//8
M6, 2, M7, 2, H1, 4, M7, 4, H2, 2, H2, 2,
H1, 4+2,M5, 2+4+4,
H4, 4, H3, 4, H2, 4, H1, 4,
//9
H3, 4+4+4, H3, 4,
H6, 4+4, H5, 4, H5, 4,
H3, 2, H2, 2, H1, 4+4, P, 2, H1, 2,
//10
H2, 4, H1, 2, H2, 2, H2, 4, H5, 4,
H3, 4+4+4, H3, 4,
H6, 4+4, H5, 4+4,
//11
H3, 2, H2, 2, H1, 4+4, P, 2, H1, 2,
H2, 4, H1, 2, H2, 2+4, M7, 4,
M6, 4+4+4, M6, 2, M7, 2,
0xFF //终止符号
};
//主函数
unsigned char FreqSelect,MusicSelect;
void main()
{
timer0_init();
while(1)
{
if(Music[MusicSelect]!=0xFF) //如果(不是停止标志位)
{
FreqSelect = Music[MusicSelect]; //选择音符对应的频率
MusicSelect++;
delayms(SPEED/4*Music[MusicSelect]); //选择音符对应的时长
MusicSelect++;
TR0 = 0;
delayms(5); //音符间短暂停顿
TR0 = 1;
}
else //如果(是停止标志位)
{
TR0 = 0; //停止播放
while(1);
}
}
}
//中断函数
void timer0_routine() interrupt 1
{
if(FreqTable[FreqSelect]) //如果(不是休止符)
{
/*取对应频率的重装值到定时器*/
TL0 = FreqTable[FreqSelect]%256; //设置定时初值
TH0 = FreqTable[FreqSelect]/256; //设置定时初值
buzzer=!buzzer; //反转蜂鸣器IO口
}
}
定时器函数 timer0.h
//定时器函数
#ifndef _timer0_h_
#define _timer0_h_
void timer0_init(void);
#endif
#include <REGX52.H>
void timer0_init(void) //1毫秒@11.0592MHZ
{
TMOD &= 0xF0; //设置定时器模式,1111 0000,&,高四位保留,低四位清零
TMOD |= 0x01; //设置定时器模式,0000 0001,|,高四位保留,设置模式为T0
TL0 = 0x66; //设置定时初始值,1ms,11.0592MHZ
TH0 = 0xFC; //设置定时初始值,1ms,11.0592MHZ
TF0 = 0; //清楚TF0标志
TR0 = 1; //定时器0开始计时
ET0=1; //打开定时器T0中断开关
EA=1; //打开中断系统总开关
PT0=0; //设置T0中断优先级,低
}
延时函数 delayms.h
#include <intrins.h>
void delayms(unsigned int xms) //@11.0592MHz
{
unsigned char i, j;
while(xms--)
{
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
·这张图片记录A-I 各种内容,我们可以根据音符来敲出我们想要的音乐代码,并在原代码中稍作改动即可。
·根据音符<——>索引来进行乐谱与代码的转换,此操作仅改变主程序 main中代码即可