您的位置:首页 > 科技 > IT业 > 在线视频制作网站_网络营销推广的ppt_谷歌应用商店_会员营销

在线视频制作网站_网络营销推广的ppt_谷歌应用商店_会员营销

2025/6/30 1:16:43 来源:https://blog.csdn.net/gantengsheng/article/details/147008542  浏览:    关键词:在线视频制作网站_网络营销推广的ppt_谷歌应用商店_会员营销
在线视频制作网站_网络营销推广的ppt_谷歌应用商店_会员营销

目录

  • 系列文章目录
  • 前言
  • 一、效果展示
  • 二、原理分析
  • 三、各模块代码
    • 1、音乐数据头文件
    • 2、定时器0
    • 3、定时器1
  • 四、主函数
  • 附录

系列文章目录


前言

之前有做过一个生日礼物:
基于51单片机的心形流水灯+无源蜂鸣器播放音乐

能播放流水灯,同时播放生日快乐歌,现在做一个只有音乐播放的。

用的是普中A2开发板,单片机是STC89C52RC,用到了板上的无源蜂鸣器。

【频率】12T@11.0592MHz

效果查看/操作演示:B站搜索“甘腾胜”或“gantengsheng”查看。
源代码下载:B站对应视频的简介有工程文件下载链接。

一、效果展示

在这里插入图片描述

二、原理分析

1、声音的产生

声音的产生是由于物体的振动,例如,人说话是靠声带振动。无源蜂鸣器也是一样,通电的时候,电流流过蜂鸣器内部的线圈,线圈产生磁场,把内部的永磁体吸过来,断电的时候,线圈无磁场,永磁体回到原来位置,永磁铁带动振动薄膜来回运动。如果通电0.5ms,断电0.5ms,再通电0.5ms,如此反复,则振动的周期是1ms,就会发出1KHz的声音,改变通电或断电的时间,就可以改变频率了。

2、音符、时值

不同的音符对应不同的频率,不同的频率对应不同的定时器初值(通过定时器中断函数让无源蜂鸣器的引脚的电平翻转),这个需要提前计算好数据。不懂的建议看一下江协科技的51单片机入门教程,讲得很详细。

时值就是每个音符持续的时间,以《阳光彩虹小白马》为例,♩=96,表示1分钟有96个四分音符,即每个四分音符的时长为60/96s=0.625s=625ms,即16分音符的时长为625ms/4=156.25ms,取整为156ms(由于音符之间有短暂的停顿和代码运行误差,节奏偏慢,本代码中改成了145ms),以此为最小单位(因为简谱中有16分音符)。

定时器0控制时值,定时器1控制音符,并且要设置定时器1的优先级较高,否则无源蜂鸣器的发声会收到影响。

用这两个定时器就可以控制无源蜂鸣器发出音乐了,主函数的主循环中可以执行其他代码。

文末有《阳光彩虹小白马》的简谱。

3、注意事项

相邻两个音符之间需要有一定的间隔,否则如果两个相邻的音符是一样的话,就分不出是两个音符了。代码中设置了5ms的时间间隔,这个也是上面所说的节奏偏慢的原因之一。

三、各模块代码

1、音乐数据头文件

h文件

#ifndef	__MUSIC_H__
#define	__MUSIC_H__//十六分音符的时长(ms)
//一分钟96个四分音符,根据计算,十六分音符的时长约为156ms(156.25ms)
//实测播放偏慢,所以将时长改小一点,改成145ms
# define Duration 145//音符与索引对应表,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 code FreqTable[]={
0,	//休止符,即进入定时器1中断程序后之后,蜂鸣器电平不翻转
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,65198,65217,65235,65252,65268,65283,
};//乐谱
unsigned char code Music[]={//两个一组,分别是音符和时值
//音符(频率对应的定时器重装值)
//时值(十六分音符时长的倍数)/*《阳光彩虹小白马》*/
//原来是G调,这里按C调播放0,	//第0个数据为0,目的是主函数中开启中断后,能立刻进入定时器0的中断函数进行频率和时值的赋值//怎么能
P,4,P,4,P,2,L5,2,L6,2,M1,2,//哭呢,一切会
M5,2,M3,6,P,2,M5,2,M2,2,M1,2,//好哒,一切都
M3,2,M2,6,P,2,M5,2,M2,2,M1,2,//去吧,你就得
M2,2,M2,6,P,2,M3,2,M1,2,L6,2,//想着。既然没
M2,2,M1,6,P,2,L5,2,L6,2,M1,2,//办法,还很他
M5,2,M3,6,P,2,M5,2,M2,2,M1,2,//干嘛,还管它
M3,2,M2,6,P,2,M5,2,M2,2,M1,2,//干嘛,心里要
M3,2,M2,6,P,2,M3,2,L6,2,M1,2,//记得。你是
M1,2,M1,6,P,4,P,2,M3,1,M4,1,//内内个内内内个内个内内
M5,2,M5,1,M3,1,M5,2,M5,2,M5,1,M3,1,M5,1,M6,1,M5,2,M5,2,//内内个内内内个内个内内
M5,2,M5,1,M3,1,M5,2,M5,2,M5,1,M3,1,M5,1,M6,1,M5,2,M5,2,//阳光彩虹小白马,
M5,2,M3,2,M2,2,M1,2,L5,2,M1,2,M1,4,//滴滴哒滴滴哒。
M3,2,M3,1,M2,1,M3,2,M2,2,M1,6,P,2,0xFF,	//终止标记};#endif

2、定时器0

h文件

#ifndef __TIMER0_H__
#define __TIMER0_H__void Timer0_Init(void);#endif

c文件

#include <REGX52.H>/*** 函    数:定时器0初始化* 参    数:无* 返 回 值:无*/
void Timer0_Init(void)
{	
//	AUXR&=0x7F;	//定时器时钟12T模式(STC89C52RC是12T单片机,无需设置)TMOD&=0xF0;	//设置定时器模式(高四位不变,低四位清零)TMOD|=0x01;	//设置定时器模式(通过低四位设为16位不自动重装)TL0=0x18;	//设置定时初值,定时1ms,12T@11.0592MHzTH0=0xFC;	//设置定时初值,定时1ms,12T@11.0592MHzTF0=0;	//清除TF0标志TR0=1;	//定时器0开始计时ET0=1;	//打开定时器0中断允许EA=1;	//打开总中断PT0=0;	//当PT0=0时,定时器0为低优先级,当PT0=1时,定时器0为高优先级
}/*定时器中断函数模板
void Timer0_Routine() interrupt 1	//定时器0中断函数
{static unsigned int T0Count;	//定义静态变量TL0=0x18;	//设置定时初值,定时1ms,12T@11.0592MHzTH0=0xFC;	//设置定时初值,定时1ms,12T@11.0592MHzT0Count++;if(T0Count>=1000){T0Count=0;}
}
*/

3、定时器1

h文件

#ifndef __TIMER1_H__
#define __TIMER1_H__void Timer1_Init(void);#endif

c文件

#include <REGX52.H>/*** 函    数:定时器1初始化* 参    数:无* 返 回 值:无*/
void Timer1_Init(void)
{
//	AUXR&=0xBF;	//定时器时钟12T模式(STC89C52RC是12T单片机,无需设置)TMOD&=0x0F;	//设置定时器模式(低四位不变,高四位清零)TMOD|=0x10;	//设置定时器模式(通过高四位设为16位不自动重装的模式)TL1=0x66;	//设置定时初值,定时1ms,12T@11.0592MHzTH1=0xFC;	//设置定时初值,定时1ms,12T@11.0592MHzTF1=0;	//清除TF1标志TR1=1;	//定时器1开始计时ET1=1;	//打开定时器1中断允许EA=1;	//打开总中断PT1=1;	//当PT1=0时,定时器1为低优先级,当PT1=1时,定时器1为高优先级
}/*定时器中断函数模板
void Timer1_Routine() interrupt 3	//定时器1中断函数
{static unsigned int T1Count;	//定义静态变量TL1=0x66;	//设置定时初值,定时1ms,12T@11.0592MHzTH1=0xFC;	//设置定时初值,定时1ms,12T@11.0592MHzT1Count++;if(T1Count>=1000){T1Count=0;}
}
*/

四、主函数

main.c

/*by甘腾胜@20250330
【效果查看/操作演示】B站搜索“甘腾胜”或“gantengsheng”查看
【单片机】STC89C52RC
【频率】12T@11.0592MHz
【外设】无源蜂鸣器
【简单的原理分析】https://blog.csdn.net/gantengsheng/article/details/143581157
*/#include <REGX52.H>
#include "Music.h"
#include "Timer0.h"
#include "Timer1.h"sbit Buzzer=P2^5;unsigned char FreqSelect;	//频率选择变量
unsigned int MusicSelect;	//音乐选择变量,用来选择音符的频率和时长
bit TimeIntervalFlag=1;	//控制音符之间短暂间隔(5ms)的标志/*** 函    数:主函数(有且仅有一个)* 参    数:无* 返 回 值:无* 说    明:主函数是程序执行的起点,负责执行整个程序的主要逻辑‌*/
void main()
{P0=0x00;	//防止开发板的数码管亮Timer0_Init();  //定时器0初始化Timer1_Init();  //定时器1初始化while(1){}
}/*** 函    数:定时器0中断函数* 参    数:无* 返 回 值:无*/
void Timer0_Routine() interrupt 1
{static unsigned int T0Count1,T0Count2;	//定义静态变量TL0=0x18;	//设置定时初值,定时1ms,12T@11.0592MHzTH0=0xFC;	//设置定时初值,定时1ms,12T@11.0592MHzT0Count1++;T0Count2++;if(T0Count1>=Music[MusicSelect]*Duration)	//控制每个音符持续的时长{	//如果上一个音符的时长到了(即如果时间=倍数*十六分音符的时长),则进入此函数,重新赋值T0Count1=0;//如果是终止标志0xFF,则音乐选择变量清零,重新开始播放if(Music[MusicSelect+1]==0xFF){MusicSelect=0;}MusicSelect++;	//音乐选择变量自增,此时对应Music数组里音符频率的索引FreqSelect=Music[MusicSelect];	//将音符的频率的索引赋值给频率选择变量FreqSelect//音乐选择变量自增,此时对应Music数组里↑上面频率的时长数据(十六分音符时长的倍数)//用来控制从现在到下次进入此函数的时间长度MusicSelect++;TimeIntervalFlag=1;	//控制音符之间短暂间隔(5ms)的标志置1TR1=0;	//定时器1暂停计时,蜂鸣器不发声T0Count2=0;	//T0Count2清零}if(T0Count2>=5 && TimeIntervalFlag==1)	//5ms{T0Count2=0;TimeIntervalFlag=0;	//控制音符之间短暂间隔(5ms)的标志置0,在置1前不会进入此函数TR1=1;	//定时器1继续计时,蜂鸣器继续发声}
}/*** 函    数:定时器1中断函数* 参    数:无* 返 回 值:无*/
void Timer1_Routine() interrupt 3
{if(FreqTable[FreqSelect])	//如果不是休止符{/*取对应频率值的重装载值到定时器*/TL1 = FreqTable[FreqSelect]%256;	//设置定时初值TH1 = FreqTable[FreqSelect]/256;	//设置定时初值Buzzer=!Buzzer;	//翻转蜂鸣器IO口}
}

附录

《阳光彩虹小白马》简谱
在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com