C51单片机播放音乐《起风了》

单片机控制蜂鸣器发声的基本原理和方法:只需对驱动口输出驱动电平并通过放大电路放大驱动电流就能使蜂鸣器发出声音。改变引脚的频率,就可以调整蜂鸣器的音调,产生各种不同的声音。
同时改变输出电平的高低电平占空比,则可以控制蜂鸣器的声音大小

下面给出代码

main.c

(这里注意要把数组类型从char改为int要不然字符数组存不下,音乐不会完整播放),更改SPEED可改变曲子的播放速度。

#include <REGX52.H>

#include "Delay.h"
#include "Timer0.h"
 
//蜂鸣器端口定义
sbit Buzzer=P2^5;
 
//播放速度,值为四分音符的时长(ms)
#define SPEED	700
 
//音符与索引对应表,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,
	63628,63731,63835,63928,64021,64103,64185,64260,64331,64400,64463,64528,
	64580,64633,64684,64732,64777,64820,64860,64898,64934,64968,65000,65030,
	65058,65085,65110,65134,65157,65178,65198,65217,65235,65252,65268,65283,
};
 
//乐谱
unsigned int code Music[]={
	//音符,时值,
	
	//1

	M2,3,
	M1,1,
	M2,3,
	M1,1,
	M2,2,
	M3,2,
	M5,2,
	M3,2,
	
	M2,3,
	M1,1,
	M2,3,
	M1,1,
	M2,1,
	M3,1,
	M2,1,
	M1,1,
	L5,2,
	P,2,
	
	M2,3,
	M1,1,
	M2,3,
	M1,1,
	M2,2,
	M3,2,
	M5,2,
	M3,2,
	
	M2,3,
	M3,1,
	M2,2,
	M1,1,
	M2,5,
	P,4,
	
	M2,3,
	M1,1,
	M2,3,
	M1,1,
	M2,2,
	M3,2,
	M5,2,
	M3,2,
	
	M2,3,
	M3,1,
	M2,2,
	M1,1,
	L6,3,
	P,2,
	M3,1,
	M2,1,
	M1,1,
	M2,1,
	
	M1,2,
	P,2,
	M3,1,
	M2,1,
	M1,1,
	M2,1,
	M1,2,
	P,2,
	M3,1,
	M2,1,
	M1,1,
	M2,1,
	
	M1,4,
	P,6,
	M1,2,
	M2,2,
	M3,2,
	
	M1,2,
	M6,2,
	M5,1,
	M6,3,
	P,1,
	M1,1,
	M7,2,
	M6,1,
	M7,3,
	
	P,2,
	M7,2,
	M6,1,
	M7,3,
	M3,2,
	H1,1,
	H2,1,
	H1,1,
	M7,1,
	M6,2,
	
	M5,2,
	M6,2,
	M5,1,
	M6,2,
	M5,1,
	M6,1,
	M5,1,
	M6,2,
	M5,1,
	M2,2,
	M5,1,
	
	M5,1,
	M3,5,
	P,4,
	M1,2,
	M2,2,
	M3,2,
	
	M1,2,
	M6,2,
	M5,1,
	M6,3,
	P,1,
	M1,1,
	M7,2,
	M6,1,
	M7,3,
	
	P,2,
	M7,2,
	M6,1,
	M7,3,
	M3,2,
	H1,1,
	H2,1,
	H1,1,
	M7,1,
	M6,2,
	
	M5,2,
	M6,2,
	H3,4,
	M5,2,
	M6,2,
	H3,3,
	M5,1,
	
	M5,1,
	M6,11,
	P,2,
	H1,2,
	
	H2,2,
	H3,2,
	H6,1,
	H5,3,
	H6,1,
	H5,3,
	H6,1,
	H5,3,
	
	H2,1,
	H3,3,
	H6,1,
	H5,3,
	H6,1,
	H5,3,
	H6,1,
	H5,2,
	H3,1,
	
	H3,3,
	H2,2,
	H1,1,
	M6,2,
	H1,3,
	H2,2,
	H1,1,
	M6,2,
	
	H1,2,
	H3,6,
	H2,1,
	H3,1,
	H2,2,
	P,2,
	H1,2,
	
	
	
	H2,2,
	H3,2,
	H6,1,
	H5,3,
	H6,1,
	H5,3,
	H6,1,
	H5,2,
	P,1,
	
	H2,1,
	H3,2,
	H6,1,
	H5,3,
	H6,1,
	H5,3,
	H6,1,
	H5,2,
	H3,2,
	
	H3,1,
	H2,2,
	H1,1,
	M6,2,
	H3,2,
	H2,2,
	H1,1,
	M6,3,
	H1,2,
	
	H1,8,
	M6,1,
	H3,3,
	H2,2,
	H1,1,
	M6,1,
	
	M6,1,
	H3,2,
	H2,2,
	H1,1,
	M6,3,
	H1,7,
	
	H1,8,
	P,8,
	
	0xFF
	//终止标志
};
 
unsigned int FreqSelect,MusicSelect;
 
void main()
{
	Timer0Init();
	while(1)
	{
		if(Music[MusicSelect]!=0xFF)	//如果不是停止标志位
		{
			FreqSelect=Music[MusicSelect];	//选择音符对应的频率
			MusicSelect++;
			Delay(SPEED/4*Music[MusicSelect]);	//选择音符对应的时值
			MusicSelect++;
			TR0=0;
			Delay(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.c

#include <REGX52.H>

/**
  * @brief 定时器0初始化
  * @param无
  * @retval 无  
  */
void Timer0Init()//1毫秒@11.0592MHz
{
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x01;		//设置定时器模式
	TL0 = 0x66;		//设置定时初始值
	TH0 = 0xFC;		//设置定时初始值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0=1;			//打开定时器0中断
	EA=1;			//开总中断
	PT0=0;
}

/*定时器终端模板函数
void Timer0_Routine() interrupt 1
{
	static unsigned int T0Count;
	TL0 = 0x66;		//设置定时初始值
	TH0 = 0xFC;		//设置定时初始值
	T0Count++;
	if(T0Count>=1000)
	{
		T0Count=0;
		P2_0=~P2_0;
	}
}
*/

Timer0.h

#ifndef __TIMER0_H__//防重复定义
#define __TIMER0_H__


void Timer0Init();

#endif

Delay.c

#include <REGX52.H>
void Delay(unsigned int xms)		
{
	unsigned char i, j;
	while(xms--){
	i = 2;
	j = 239;
	do
	{
		while (--j);
	} while (--i);
  }
}

Delay.h

#ifndef __DELAY_H__
#define __DELAY_H__

void Delay(unsigned int xms);


#endif

  • 16
    点赞
  • 63
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值