STM32CubeMx使用教程(五)—— 使用PWM控制蜂鸣器演唱孤勇者

本章节将讲解如何使用STM32CubeMx配置定时器,并使用PWM控制无源蜂鸣器频率演奏

 前言

1.软件准备:STM32CubeMx、Keil5_ MDK

2.硬件准备:STM32F103最小系统板、无源蜂鸣器模块、杜邦线若干

本实验所使用的所有器件清单和工程源码已上传至百度网盘

链接:https://pan.baidu.com/s/11HC05dnI-CEzDaU9OL2ugA?pwd=80o8 
提取码:80o8

一、蜂鸣器发声原理

 如图所示为蜂鸣器电路。

一般来说,3.3V直流产生的电信号功率很小,不足以驱动蜂鸣器发出可听见的响声,所以整个模块中有一个电流放大模块,这便是图中的晶体三极管。图中的放大电路是典型的共发射极接法,蜂鸣器接在集电极上,就实现了电流的放大(详细的晶体管放大电路原理请见《模拟电子技术》)

蜂鸣器分为有源和无源两种。所谓的源,指的是其中内部的振荡源,有源蜂鸣器中的振荡器一般是多谐振荡器,其原理就是模拟电路中RC振荡器的一般原理(放大电路、正反馈、相位差90°、稳压电路),有源蜂鸣器内部的振荡源频率是固定的,所以使用时不可调频,且输入的电信号必须是直流。

相比之下,无源蜂鸣器没有内部振荡源,发声的基本原理是电磁感应,其内部的基本结构是一匝匝线圈以及一个微型扬声器。由于没有振荡源,且内部的主要结构是线圈,所以其工作时输入的电信号必须是交流,而不能是频率很低的直流(直流不能通过无负载的线圈,负责线圈会因为短路而被烧坏)。与有源蜂鸣器一样,无源蜂鸣器也必须使用放大电路来增大输入信号的功率。

二、PWM脉冲宽度调制信号

脉冲宽度调制(PWM) 是一种数字信号,最常用于控制电路。该信号在预定义的时间和速度中设置为高(5v或3.3v)和低(0v)。通常,我们将PWM的高电平称为1,低电平为0。

PWM主要有 PWM频率(f)、 PWM周期(T)、 PWM占空比等参数。

PWM频率:是指一秒钟内从高电平时间在到低电平时间,再从低电平跳到高电平的瞬间次数,也就是一秒钟内有多少个PWM的周期。f = T / 1(HZ)。

PWM周期:是指一秒钟内从高电平时间在到低电平时间,T = f / 1(s)。

 PWM占空比:是指一个周期内高电平时间和总时间的比值。

例如:PWM的周期为1ms,高电平时间为0.5ms,低电平时间为0.5ms,则频率就为1kHz,占空比就为百分之五十。

如图所示,为示波器

pwm的调节作用来源于对“占周期”的宽度控制,“占周期”变宽,输出的能量就会提高,通过阻容变换电路所得到的平均电压值也会上升,“占周期”变窄,输出的电压信号的电压平均值就会降低,通过阻容变换电路所得到的平均电压值也会下降

也就是,在一定的频率下,通过不同的占空比即可得到不同的输出模拟电压,由此,我们可以通过控制PWM输出频率控制蜂鸣器发出不同音调。

三、音调的转化

查看源图像

如图所示为不同音调对应的频率,我们通过修改定时器psc即可修改不同频率对应的音调。

 

为计算所得产生中断周期,其中为自动重装载值,为预分频,为对应时钟频率。

若要使音调对应定时器频率,以低音DO为例,将 带入上述公式,即可求出的值,修改不同的对应不同的音调。 

由定时器周期计算公式我们可知,Tclk为定时器挂靠时钟总线频率,arr为设定定时器自动重装载值,f已知为不同音调频率,图中“dao”频率为262,通过计算得出psc赋给定时器以获得不同音调。

将所有音调计算出来,放在.h文件宏定义。

四、简单的乐谱知识

(一)音调

音阶分为中音、高音、低音,点在上面为高音,没有点为中音,点在下面为低音

(二)音长

简谱对应音阶下无横线为一拍,有单横线为半拍,双横线为1/4拍。音阶数字后有点加半拍音长,有横线加一拍。

五、程序实现

本次实验同样通过STM32CubeMx实现,

打开之前创建的工程

设置psc和arr,因为本次实验是通过修改psc控制定时器频率,所以初始化psc的值可任意 ,arr的值会影响到占空比的大小,一般设置为1000,方便自己计算即可。

 设置占空比为50%,其余设置保持默认即可。设置完成后生成代码。

根据音调表对应频率宏定义音调

#define  proport          72000 	//Tclk/(arr+1)=72000000/(1000)

//根据Tout= ((arr+1)*(psc+1))/Tclk推出psc值就是本句define定义的值,Tout为音调频率131Hz的倒数,Tclk=72MHz                                                
#define  L1       ((proport/262)-1)//低调 do 的频率
#define  L2       ((proport/296)-1)//低调 re 的频率
#define  L3       ((proport/330)-1)//低调 mi 的频率
#define  L4       ((proport/349)-1)//低调 fa 的频率
#define  L5       ((proport/392)-1)//低调 sol 的频率
#define  L6       ((proport/440)-1)//低调 la 的频率
#define  L7       ((proport/494)-1)//低调 si 的频率
                                               
#define  M1       ((proport/523)-1)//中调 do 的频率
#define  M2       ((proport/587)-1)//中调 re 的频率
#define  M3       ((proport/659)-1)//中调 mi 的频率
#define  M4       ((proport/699)-1)//中调 fa 的频率
#define  M5       ((proport/784)-1)//中调 sol的频率
#define  M6       ((proport/880)-1)//中调 la 的频率
#define  M7       ((proport/988)-1)//中调 si 的频率

#define  H1       ((proport/1048)-1)//高调 do 的频率
#define  H2       ((proport/1176)-1)//高调 re 的频率
#define  H3       ((proport/1320)-1)//高调 mi 的频率
#define  H4       ((proport/1480)-1)//高调 fa 的频率
#define  H5       ((proport/1640)-1)//高调 sol的频率
#define  H6       ((proport/1760)-1)//高调 la 的频率
#define  H7       ((proport/1976)-1)//高调 si 的频率

#define  Z0       0//

 到此为止,底层基本书写完毕,接下来就是寻找歌曲简谱,实现功能

这里推荐乐谱查询网址陈奕迅《孤勇者》吉他谱_G调吉他弹唱谱_高清六线谱_玩吉他 (wanjita.com)

 对应音调编写以下代码

《孤勇者》

/**
* NAME: void Solitary_brave(void)
* FUNCTION : Solitary_brave
*/
void Solitary_brave(void)
{
	int16_t solitary_brave[]=
	{
		M6,50,M7,50,H1,50,H2,50,M7,50,H1,50,H1,100,Z0,10,	//爱你孤身走暗巷
		H1,50,M7,50,H1,50,H2,50,M7,50,H1,50,H1,100,Z0,10, 	//爱你不跪的模样
		H1,50,H2,50,H3,50,H2,50,H3,50,H2,50,H3,100,H3,50,H3,50,H2,50,H3,100,H5,100,H3,100,Z0,10 //爱你对峙过绝望不肯哭一场
		
	};
	int length = sizeof(solitary_brave)/sizeof(solitary_brave[0]);
	for(uint8_t i=0;i<(length/2);i++)
	{
		buzzer_on(solitary_brave[i*2],200);
		HAL_Delay(5*solitary_brave[i*2+1]);
	}
}

《起风了》 

void Wind_Rises(void)
{
	int wind_rise[]=
	{	
		//前奏
		L7,25,M1,25,M2,25,M3,25,L3,50,M5,25,M3,25,M3,50,Z0,150, L7,25,M1,25,M2,25,M3,25,L2,50,M5,25,M3,25,M2,25,M3,25,M1,25,M2,25,L7,25,M1,25,L5,25,Z0,25, L7,25,M1,25,M2,25,M3,25,L3,50,M5,25,M3,75,Z0,150,L7,25,M1,25,M2,25,M3,25,L2,50,M5,25,M3,25,M2,25,M3,25,M1,25,M2,25,Z0,20,
		//这一路上走走停停 顺着少年漂流的痕迹
		M2,50,M2,50,M1,25,M2,50,M2,50,M1,25,M2,50,M3,50,M5,50,M3,50, M2,50,M2,50,M1,25,M2,50,M2,50,M1,25,M2,25,M3,25,M2,25,M1,25,L6,100,Z0,10,
		//迈出车站的前一刻 竟有些犹豫
		M2,50,M2,50,M1,25,M2,50,M2,50,M1,25,M2,50,M3,50,M5,50,M3,50, M2,50,M2,50,M3,25,M2,50,M1,50,M2,100,Z0,50,
		//不仅笑着这近乡情怯 仍无法避免
		M2,50,M2,50,M1,25,M2,50,M2,50,M1,25,M2,50,M3,50,M5,50,M3,50, M2,50,M2,50,M3,25,M2,50,M1,50,L6,100,Z0,10
		//而长野的天 依旧那么暖 风吹起了从前
		M3,25,M2,25,M1,25,M2,25,M1,100, M3,25,M2,25,M1,25,M2,25,M1,50,M1,50, M5,25,M3,25,M2,25,M1,25,M2,25,M1,100,M1,150,Z0,30
		//从前初识这世间 万般留恋 看着天边似在眼前 也甘愿赴汤蹈火去走它一遍
		M1,50,M2,50,M3,50,M1,50,M6,50,M5,25,M6,25,M6,50,M6,50, M1,25,M7,50,M6,25,M7,25,M7,100,Z0,5, M7,50,M6,25,M7,25,M7,50,M3,50,H1,25,H2,25,H1,25,M7,25,M6,50,M5,50, M6,50,M5,25,M6,25,M6,25,M5,25,M6,25,M5,25,M6,50,M5,25,M2,25,M2,25,M5,50,M5,50,M3,100,M3,100,Z0,25,
		//如今走过这世间 万般留恋 翻过岁月不同侧脸 措不及防闯入你的笑颜
		M1,50,M2,50,M3,50,M1,50,M6,50,M5,25,M6,25,M6,50,M6,50, M1,25,M7,50,M6,25,M7,25,M7,100,Z0,5, M7,50,M6,25,M7,25,M7,50,M3,50,H1,25,H2,25,H1,25,M7,25,M6,50,M5,50, M6,50,H3,25,H3,25,H3,50,M5,50,M6,50,H3,25,H3,25,H3,25,M5,50,M6,25,M6,100,M6,100,M6,100,Z0,25,
		//我曾难自拔于世界之大 也沉溺于其中梦话
		H1,50,H2,50,H3,50,H6,25,H5,25,H5,50,H6,25,H5,25,H5,50,H6,25,H5,25,H5,50,H2,25,H3,25,H3,50, H6,25,H5,25,H5,50,H6,25,H5,25,H5,50,H6,25,H5,25,H5,25,H3,50,H3,50,
		//不得真假 不做挣扎 不惧笑话
		H2,50,H1,25,M6,25,M6,25,H1,50, M6,25,H2,25,H1,25,M6,50,M6,25,H1,50,H1,50, H3,100,H3,25,H4,25,H3,50,H3,25,H2,50,H2,50,Z0,25,
		//我曾将青春翻涌成她 也曾指尖弹出盛夏 心之所动且就随缘去吧
		H1,50,H2,50,H3,50,H6,25,H5,25,H5,50,H6,25,H5,25,H5,50,H6,25,H5,25,H5,50,H2,50, H3,50,H6,25,H5,25,H5,50,H6,25,H5,25,H5,50,H6,25,H5,25,H5,50,H3,50,H3,50, H2,50,H1,25,M6,25,M6,25,H3,50,H3,50, H2,50,H1,25,M6,25,M6,25,H1,50,H1,50,H1,100,H1,100,Z0,10,
		//短短的路走走停停  也有了几分的距离
		M2,50,M2,50,M1,25,M2,50,M2,50,M1,25,M2,50,M3,50,M5,50,M3,50, M2,50,M2,50,M1,25,M2,50,M2,50,M1,25,M2,25,M3,25,M2,25,M1,25,L6,100,Z0,10,
		//不知抚摸的是故事还是段心情
		M2,50,M2,50,M1,25,M2,50,M2,50,M1,25,M2,50,M3,50,M5,50,M3,50, M2,50,M2,50,M3,25,M2,50,M1,50,M2,100,Z0,50,
		//也许期待的不过是与时间为敌
		M2,50,M2,50,M1,25,M2,50,M2,50,M1,25,M2,50,M3,50,M5,50,M3,50, M2,50,M2,50,M3,25,M2,50,M1,50,L6,100,Z0,10,
		//再次见到你 微凉晨光里 笑的很甜蜜
		M3,25,M2,25,M1,25,M2,25,M1,100, M3,25,M2,25,M1,25,M2,25,M1,50,M1,50, M5,25,M3,25,M2,25,M1,25,M2,25,M1,100,M1,150,Z0,30,
		//从前初识这世间 万般留恋 看着天边似在眼前 也甘愿赴汤蹈火去走它一遍
		M1,50,M2,50,M3,50,M1,50,M6,50,M5,25,M6,25,M6,50,M6,50, M1,25,M7,50,M6,25,M7,25,M7,100,Z0,5, M7,50,M6,25,M7,25,M7,50,M3,50,H1,25,H2,25,H1,25,M7,25,M6,50,M5,50, M6,50,M5,25,M6,25,M6,25,M5,25,M6,25,M5,25,M6,50,M5,25,M2,25,M2,25,M5,50,M5,50,M3,100,M3,100,Z0,25,
		//如今走过这世间 万般留恋 翻过岁月不同侧脸 措不及防闯入你的笑颜
		M1,50,M2,50,M3,50,M1,50,M6,50,M5,25,M6,25,M6,50,M6,50, M1,25,M7,50,M6,25,M7,25,M7,100,Z0,5, M7,50,M6,25,M7,25,M7,50,M3,50,H1,25,H2,25,H1,25,M7,25,M6,50,M5,50, M6,50,H3,25,H3,25,H3,50,M5,50,M6,50,H3,25,H3,25,H3,25,M5,50,M6,25,M6,100,M6,100,M6,100,Z0,25,
		//我曾难自拔于世界之大 也沉溺于其中梦话
		H1,50,H2,50,H3,50,H6,25,H5,25,H5,50,H6,25,H5,25,H5,50,H6,25,H5,25,H5,50,H2,25,H3,25,H3,50, H6,25,H5,25,H5,50,H6,25,H5,25,H5,50,H6,25,H5,25,H5,25,H3,50,H3,50,
		//不得真假 不做挣扎 不惧笑话
		H2,50,H1,25,M6,25,M6,25,H1,50, M6,25,H2,25,H1,25,M6,50,M6,25,H1,50,H1,50, H3,100,H3,25,H4,25,H3,50,H3,25,H2,50,H2,50,Z0,25,
		//我曾将青春翻涌成她 也曾指尖弹出盛夏 心之所动且就随缘去吧
		H1,50,H2,50,H3,50,H6,25,H5,25,H5,50,H6,25,H5,25,H5,50,H6,25,H5,25,H5,50,H2,50, H3,50,H6,25,H5,25,H5,50,H6,25,H5,25,H5,50,H6,25,H5,25,H5,50,H3,50,H3,50, H2,50,H1,25,M6,25,M6,25,H3,50,H3,50, H2,50,H1,25,M6,25,M6,25,H1,50,H1,50,H1,100,H1,100,Z0,10,
		//逆着光行走任风吹雨打吧
		M6,25,H3,50,H3,50,H2,50,H1,25,M6,25,M6,25,H3,50,H2,50,H1,25,M6,25,M6,25,H1,50,H1,50,H1,50,H1,100,Z0,25,
		//晚风吹起你鬓间的白发 抚平回忆留下的疤
		H1,50,H2,50,H2,25,H3,50,H6,25,H5,25,H5,50,H6,25,H5,25,H5,50,H6,25,H5,25,H5,50,H2,25, H3,25,H3,50,H6,25,H5,25,H5,50,H6,25,H5,25,H5,50,H6,25,H5,25,H5,25,H3,50,H3,50,Z0,5,
		//你的眼中明暗交杂 一笑生花 暮色遮住你蹒跚的步伐
		H2,50,H1,25,M6,25,M6,25,H1,50,M6,25,H2,25,H1,25,M6,50,M6,50, H1,50,H1,50,H3,100,H3,25,H4,25,H3,50,H3,25,H2,50,H2,50,H1,100,H2,100,H3,100,H6,25,H5,25,H5,50,H6,25,H5,25,H5,50,H6,25,H5,25,H5,50,H2,50,
		//走进床头藏起的画 画中的你(低着头说话)
		H3,50,H6,25,H5,25,H5,50,H6,25,H5,25,H5,50,H6,25,H5,25,H3,100,H3,50,H2,50,H1,25,M6,25,M6,25,H3,50,H3,50,H2,50,H1,25,M6,25,M6,25,H1,100,H1,50,Z0,5,
		//我仍 了 以爱之名你还愿意吗(衔接头有问题)
		H1,50,H2,50,H1,50,H1,100,M6,25,H3,50,H3,50,H2,50,H1,25,H6,25,H6,25,H3,50,H3,50,H2,50,H1,25,H6,25,H6,25,H1,50,H1,50,H1,100,Z0,5
	};
	int length = sizeof(wind_rise)/sizeof(wind_rise[0]);
	
	for(int i=0;i<(length/2);i++)
	{
		buzzer_on(wind_rise[i*2],260);
		HAL_Delay(wind_rise[i*2+1]*5);
	}
}

可以打开视频看到演示效果 

蜂鸣器演奏孤勇者

  • 21
    点赞
  • 94
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 25
    评论
<h3>回答1:</h3><br/>STM32CubeMX是一款用于STM32控制器的图形化配置工具,可以帮助开发者快速生成初始化代码。PWM是一种用于控制电机、LED等设备亮度的技术。下面是使用STM32CubeMX配置PWM的步骤: 1. 打开STM32CubeMX,选择对应的芯片型号。 2. 在Pinout & Configuration选项卡中,选择需要使用PWM引脚,将其配置为Alternate Function模式。 3. 在Configuration选项卡中,选择TIMx(x为定时器编号),并将其配置为PWM模式。 4. 配置PWM的频率、占空比等参数。 5. 生成代码并导入到开发环境中,即可使用PWM控制设备的亮度。 需要注意的是,不同芯片型号和不同的PWM引脚可能需要不同的配置方式,具体操作请参考STM32CubeMX的官方文档。 <h3>回答2:</h3><br/>stm32cubemx是一个集成了STM32控制器的软件,它集成了STM32的所有功能。PWM(脉冲宽度调制)是模拟电路中常用的一种方法,通过改变周期内高电平的占空比,可以控制电压大小。 在stm32cubemx中,我们可以通过配置对应的GPIO功能,来实现使用定时器作为pwm输出。下面是具体的步骤: 1. 打开stm32cubemx,新建一个工程。 2. 在左侧的peripherals中选择你要使用的GPIO,并且将它设置为TIMx,x表示选择的定时器。 3. 在右侧的上下文菜单栏中,选择TIMx的参数配置。 4. 在定时器中的高级参数配置中,选择TIM Channel x,这里的x表示可选择的更多通道,通常为1或2。 5. 在TIM Channel x中,选择ocxref,此时它会自动载入输出比较的设置。 6. 将三个参数进行设置,分别为 a. 频率:即波形输出的频率,以Hz为单位,由TIMx的时钟频率和计数器的分频系数来计算。 b. 占空比:占空比是高电平占总周期的比率,以百分比表示,可以通过调整定时器的CCR值来改变。 c. 模态:可以选择pwm模式或者强制输出模式。其中pwm模式可以通过外部引脚输出波形,强制输出模式只输出一种级别。 通过这些设置,我们就可以在stm32cubemx中实现pwm输出。另外,还需要在主函数中添加初始化设置和开启定时器的语句。 总之,在使用stm32cubemx时,理解GPIO和定时器的基本原理,再结合具体的参数配置,就可以很方便地实现pwm输出并控制输出电压大小,为实际应用提供了很好的技术支持。 <h3>回答3:</h3><br/>STM32CubeMX是一款用于生成STM32控制器项目代码的图形化工具,它可以帮助开发人员快速设计和配置MCU的外设资源,并生成相应的初始化代码。PWM(脉冲宽度调制)模块是一种常见的外设资源,它可以实现输出一定的占空比和频率的PWM信号,通常应用于电机控制、LED调光、音频处理等领域。 STM32CubeMX提供了丰富的PWM模块配置选项,可以满足不同的工程需求。下面是几个常见的使用步骤: 1. 在工程中选择使用PWM模块,可以多选或单选。在“时钟配置”选项中,设置PWM时钟源和时钟分频系数,以确定PWM信号的频率。例如,选择TIM2模块,时钟源为内部时钟(APB1),时钟分频系数为72,则PWM信号的频率为1MHz(APB1时钟频率为72MHz)。 2. 在“通道配置”选项中,设置PWM输出通道和其对应的引脚。例如,选择通道1,引脚为PA0,则会在PA0引脚上输出PWM信号。 3. 在“TIM2参数设置”选项中,可以设置PWM的工作模式、计数器周期、自动重载预装载、PWM输出比较模式等参数。例如,选择PWM模式1、计数器周期为500、自动重载预装载开启,则PWM信号的占空比可以在0-1000之间调节。 4. 在“时序图”选项中,可以预览PWM信号的波形,以及计算各种参数的数值。例如,选择通道1,占空比为50%,则可以看到PA0引脚上输出的PWM信号为50%高电平和50%低电平的交替波形。 5. 最后点击“生成代码”按钮,即可自动生成PWM初始化代码,包括时钟初始化、GPIO初始化、TIM初始化等。可以直接复制到工程中使用,简化了代码编写的过程。 总的来说,STM32CubeMXPWM配置十分灵活和方便,可以快速实现PWM信号的输出功能。不过还需要开发者结合具体的应用场景,进行参数的调试和优化。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宝玺

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值