【51单片机】蜂鸣器演奏音乐《机里太美》-附仿真文件

本文介绍了使用C语言编程,通过蜂鸣器来演奏音乐的基础知识和代码实现。涉及了乐理中的音符、时值和频率对照,以及定时器中断在音乐播放中的应用。作者分享了一段演奏《机里太美》的简化代码,并提供了相关函数库和Proteus仿真相册的链接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

 一、基本乐理知识

1、键盘与音符对照

 2、音符时值

 3、索引与频率对照表

 二、乐谱

 三、代码

1、main.c

2、Timer0.c

3、Timer0.h

4、Delay.c

5、Delay.h


闲的没事干,我试着用蜂鸣器演奏《机里太美》,与想象中的有点不一样,莫得灵魂【捂脸】。 

 一、基本乐理知识

1、键盘与音符对照

 2、音符时值

 3、索引与频率对照表

 二、乐谱

 三、代码

只演奏精华部分

1、main.c
#include <REGX52.H>
#include "Delay.h"
#include "Timer0.h"

typedef unsigned int u16;
typedef unsigned char u8;

#define SPEED 500		//播放速度,值为四分音符的时长(ms)

sbit Buzzer = P2^5; //蜂鸣器端口定义

//音符与索引对应表,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

//索引与频率对照表
u16 FreqTable[] = {0, 63628,63731,63835,63928,64021,64103,64185,64260,64331,
					  64400,64463,64524,64580,64633,64684,64732,64777,64820,
				      64860,64898,64934,64968,65000,65030,65058,65085,65110,
				      65134,65157,65178,65191,65217,65235,65252,65268,65283};	
//乐谱
u8 code Music[] = {
    //音符, 时值,
	P,  2,
	L6, 1,
	L6, 1,
	M3, 2,
	M3, 2,
	
	L6, 4,
	P,  4,
	P,  4,
	P,  2,
	L6, 1,
	
	L6, 1 + 2,
	
	P,  2,
	P,  4, 
	P,  2,
	L6, 1,
	L6, 1,
	M3, 2,
	M3, 2,
	
	L6, 4,
	P,  4,
	P,  4,
	P,  2,
	
	L6, 1 + 2,
	
	P,  2,
	P,  2,
	L6, 1,
	L6, 1,
	L6, 2,
	L6, 1,
	L6, 1,
	M3, 2,
	M3, 2,
	
	L6, 4,
	P,  4,
	P,  4,
	P,  2,
	L6, 1,
	
	L6, 1 + 2,
	
	P,  2,
	P,  4,
	P,  2,
	L6, 1,
	L6, 1,
	M3, 2,
	M3, 2,
	
	L6, 4,
	P,  4,
	P,  4,
	P,  2,
	L6, 1,
	L6, 1,
	
	0xFF	//终止标志
};

unsigned char 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;
			Delay(50);
			TR0 = 1;
			MusicSelect = 0;									//停顿后循环播放
		}
	}
}

void Timer0_Routine() interrupt 1
{
	if(FreqTable[FreqSelect])							//如果不是休止符
	{
		/*取对应频率值的重装载值到定时器*/
		TL0 = FreqTable[FreqSelect]%256;		//设置定时初值 //第二次中断实现
		TH0 = FreqTable[FreqSelect]/256;		//设置定时初值//
		Buzzer=!Buzzer;	//翻转蜂鸣器IO口
	}
}
2、Timer0.c
#include <REGX52.H>

/**
  * @brief  定时器0初始化,1毫秒@12.000MHz
  * @param  无
  * @retval 无
  */
void Timer0Init(void)
{
	TMOD &= 0xF0;		 //设置定时器模式
	TMOD |= 0x01;		 //设置定时器模式
	TL0 = 0x18;		 	 //设置定时初值
	TH0 = 0xFC;		   //设置定时初值
	TF0 = 0;		     //清除TF0标志
	TR0 = 1;		     //定时器0开始计时
	ET0 = 1;
	EA = 1;
	PT0 = 0;
}
3、Timer0.h
#ifndef __TIMER0_H__
#define __TIMER0_H__

void Timer0Init(void);

#endif
4、Delay.c
void Delay(unsigned int xms)
{
	unsigned char i, j;
	while(xms--)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}
5、Delay.h
#ifndef __DELAY_H__
#define __DELAY_H__

void Delay(unsigned int xms);

#endif

proteus 仿真图

需要自取

链接:https://pan.baidu.com/s/1Hkmg-aNB7FRnZRUVNjMH_Q?pwd=6664 
提取码:6664

此文为个人笔记,而且我对乐理并不算了解,如果有错漏还请各位看官指正。

我可以为您提供一个简单的c51单片机蜂鸣器歌曲示例程序,您可以根据需要进行修改。 ```c #include<reg52.h> #define uint unsigned int #define uchar unsigned char sbit beep=P1^5; //定义蜂鸣器控制引脚 //定义简单的音符和节拍 uchar code song[]={ 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x01, //音符 0x01,0x02,0x03,0x04,0x04,0x05,0x06,0x01, //音符 0x03,0x03,0x04,0x05,0x06,0x06,0x07,0x01, //音符 0x05,0x06,0x07,0x01,0x02,0x03,0x02,0x01, //音符 0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04, //音符 0x05,0x05,0x06,0x06,0x07,0x07,0x01,0x01, //音符 0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05, //音符 0x06,0x06,0x07,0x07,0x01,0x01,0x02,0x02, //音符 0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06, //音符 0x07,0x07,0x01,0x01,0x02,0x02,0x03,0x03, //音符 0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07, //音符 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, //音符 }; uchar code time[]={ 1,1,1,1,1,1,2,1, //节拍 1,1,1,1,1,1,2,1, //节拍 1,1,1,1,1,1,2,1, //节拍 1,1,1,1,1,1,2,1, //节拍 1,1,1,1,1,1,1,1, //节拍 1,1,1,1,1,1,2,1, //节拍 1,1,1,1,1,1,1,1, //节拍 1,1,1,1,1,1,2,1, //节拍 1,1,1,1,1,1,1,1, //节拍 1,1,1,1,1,1,2,1, //节拍 1,1,1,1,1,1,1,1, //节拍 1,1,1,1,1,1,1,1, //节拍 }; void delay(uint z) //延时函数 { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } void main() { uchar i,j; while(1) { for(i=0;i<72;i++) //循环播放歌曲 { for(j=0;j<time[i];j++) //根据节拍播放音符 { beep=0; delay(song[i]*10); beep=1; delay(1); } delay(10); //每个音符之间的间隔 } } } ``` 这个示例程序使用了一个简单的歌曲,可以通过修改 `song[]` 和 `time[]` 数组来播放不同的歌曲。同时,根据需要还可以修改每个音符的持续时间和间隔时间。
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值