STM32 蜂鸣器介绍 配置 播放音节

蜂鸣器一般被分为两类:有源蜂鸣器无源蜂鸣器其中源是振荡源。有源蜂鸣器内部有振荡电路,可以把直流电源转换为一定频率的脉冲信号。因为它一直输出一定的频率,我们无法改变频率,所以声音只有一种,我们只能通过电源,控制它发不发声。

无源蜂鸣器没有内部的振荡源,我们给它一个信号,控制其频率就能发出不同的声音。而我们平时听到的音乐都是有音节的,音节又是受频率控制,所以我们只要控制其频率就能发出所需要的音节和音乐。市面上大部分的电子琴,也是这种原理。

在控制无源蜂鸣器的时候,只给它一个低电平或者高电平,它是不会响的。必须给他一个频率或者说是一个方波,它才会发声。

cpp 复制代码
	TIM_TimeBaseStructure.TIM_Period = 999;  
	TIM_TimeBaseStructure.TIM_Prescaler = 71;  

此时分频PSC为72,ARR为1000,所以此时定时器为1MHz,因为音节的频率不一样,所以我们只需要更改TIM_Period,调整它的频率既可以。

举个例子,我们现在需要发出中 1 DO,f=523HZ。

从上面两行代码可以知道,此时定时器的PSC是72,并且我们知道STM32F10x的总线时钟最大为是72MHz,所以现在定时器为1MHz,所以而我们想要把1MHz时间设置为1us,即为1/1000,设x=ARR。众所周知,频率等于周期的倒数,得ARR*单次时间=总时间,即,可以计算出x=1000,所以我们可以知道当ARR=1000的时候,定时器周期为1ms。

我们现在反过来,可以知道频率=单次时间/ARR,而需要的频率是523,即,计算机按一下大概就是1912,所以ARR=1912。

这里不理解可以看看这个,STM32 TIM定时器,配置,详解(1)-CSDN博客

代码中的占空比记得要改。

cpp 复制代码
void TIM4_PWM_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	TIM_OCInitTypeDef TIM_OCInitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	TIM_TimeBaseStructure.TIM_Period = 1911;  
	TIM_TimeBaseStructure.TIM_Prescaler = 71;  
	//TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
	
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OCInitStructure.TIM_Pulse = 1912/2;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OC3Init(TIM4, & TIM_OCInitStructure);
	
	TIM_Cmd(TIM4, ENABLE);
}

我们先把需要的音节找出来 523, 587, 659, 698, 784, 880, 988。

我们设置一个数组把这些音节的频率先放进去。

cpp 复制代码
unsigned int tone[]= {523, 587, 659, 698, 784, 880, 988};

通过之前的计算我们可以知道,我们只需要改ARR的值而ARR=1000000/音节频率。而占空比设为50%,即为ARR/2.所以我们可以可以写出一个函数,去自动计算和输入ARR和CCR3。

cpp 复制代码
void sound(unsigned int fre)
{
	TIM4->ARR = 1000000 / fre;
	TIM4->CCR3 = 500000 / fre;
}
/* Set the Capture Compare Register value */
//  TIMx->CCR3 = TIM_OCInitStruct->TIM_Pulse;
cpp 复制代码
int main(void)
{
	SysTick_Configuration();
	
	TIM4_PWM_Configuration();	 
	
	while(1)
	{	
		sound(tone[0]);  
		Delay_us(1000000);
		sound(tone[1]);
		Delay_us(1000000);
		sound(tone[2]);  
		Delay_us(1000000);
		sound(tone[3]);
		Delay_us(1000000);
		sound(tone[4]);
		Delay_us(1000000);	
		sound(tone[5]);  
		Delay_us(1000000);
		sound(tone[6]);
		Delay_us(1000000);	
	}
}
相关推荐
知识分享小能手3 小时前
React学习教程,从入门到精通, React 属性(Props)语法知识点与案例详解(14)
前端·javascript·vue.js·学习·react.js·vue·react
EkihzniY5 小时前
OCR 证件识别:驱动澳门酒店自助入住智能化
嵌入式硬件·ocr
鹿鹿学长5 小时前
2025年全国大学生数学建模竞赛(C题) 建模解析|婴儿染色体数学建模|小鹿学长带队指引全代码文章与思路
c语言·开发语言·数学建模
好家伙VCC5 小时前
数学建模模型 全网最全 数学建模常见算法汇总 含代码分析讲解
大数据·嵌入式硬件·算法·数学建模
伴杯猫5 小时前
【ESP32-IDF】基础外设开发2:系统中断矩阵
c语言·单片机·嵌入式硬件·mcu·物联网·github
搬砖的小码农_Sky5 小时前
常见的显示器接口技术
嵌入式硬件·计算机外设·显示器
茯苓gao5 小时前
STM32G4 速度环开环,电流环闭环 IF模式建模
笔记·stm32·单片机·嵌入式硬件·学习
是誰萆微了承諾6 小时前
【golang学习笔记 gin 】1.2 redis 的使用
笔记·学习·golang
利刃大大6 小时前
【高并发内存池】五、页缓存的设计
c++·缓存·项目·内存池
DKPT6 小时前
Java内存区域与内存溢出
java·开发语言·jvm·笔记·学习