【STM32】嵌入式实验二 GPIO 实验:蜂鸣器发声

蜂鸣器发声

蜂鸣器电路:

8d45c676d7444ed2ba17f0a1c0c1c7d0.png

 

 pb8输入,端口模式:

6792559132914062ab2400a3272ba58c.png

实验内容:5、编写程序,控制蜂鸣器鸣叫,尝试改变蜂鸣器的声音高低。 

蜂鸣器发声就是输入不同频率的方波,根据频率可以算出周期,然后用延时就可以了。这里对这个单片机不熟的人比较坑的就是用cubemx创建项目时,时钟树一定要设置成下面的样子:

fe393d13063f412285d9c7f289f2220a.png

按照这个流程配置: 

 c4d130c34f73494f8133043da200054a.png

输入就是简单的输入,配置不再说了。

要用蜂鸣器播放一首歌曲,那么就要有一个频率表,表示音调;还有一个持续时间,表示节拍,也就是一个音调的持续时间。频率决定了输入方波的频率,持续时间是这个音调到下个音调经过的时间。

每个音调,输出占空比为50%的方波,即高电平半个周期,低电平半个周期,你需要注意每个电平延时的时间是周期的一半,所以代码里面是500000。因为是us级,1s=1000 000us,频率的倒数是周期,但是单位要化成us,并且还要除以二。

代码示例

生日歌代码:

unsigned int SONG_tone[]={212,212,190,212,159,169,212,212,190,212,142,159,212,212,106,126,159,169,190,119,119,126,159,142,159,0};
  unsigned int SONG_long[]={9,3,12,12,12,24,9,3,12,12,12,24,9,3,12,12,12,12,12,9,3,12,12,12,24,0};

for(int i=0;i<25;i++)
		for(int j=0;j<SONG_long[i]*150;j++){
		HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_8);
			for(int k=0;k<SONG_tone[i]*12;k++);}

天空之城(实现微秒级延时函数,音更准,musicnote这里没用,是音调表):

void HAL_Delay_us(uint32_t us)
{
    HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / 1000000);
    HAL_Delay(us - 1);
    HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / 1000);
}	
	
static void Sound(uint16_t frq)
{
	uint32_t time;
	if(frq != 0)
	{
		//time = 500/((uint32_t)frq);		//Ƶµĵ¹ʽ¼´ʇʱ¼䣬Ȼº󴋴¦¼Ƌ㵄ʇT/2µĊ±¼䣬˹ҔΪ500000
		time = 500000/((uint32_t)frq);
		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,1);
		//HAL_Delay(time);
		HAL_Delay_us(time);
		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,0);
		//HAL_Delay(time);
		HAL_Delay_us(time);
	}else
		HAL_Delay(1);
}
static void play_music(void)
{



//                  低7      高1  高2 不发音
	uint16_t MusicalNote[] = {247,
	                          262,294,330,349,392,440,494,//1   2   3   4   5   6   7
							              523,587,659,698,784,880,988,//中1 中2 中3 中4 中5 中6 中7
							              1046,1175,1318,1397,1568,1760,1976,0};


	uint16_t music[]={	
			441,495,525,495,525,661,495,330,441,
393,441,525,393,330,330,350,330,350,
525,330,294,330,525,495,371,350,495,
441,495,525,495,525,661,495,330,441,
393,441,525,393,294,330,350,525,495,
525,589,661,525,525,495,441,495,417,
441,525,589,661,589,661,786,589,393,
393,525,495,525,661,441,495,525,495,
525,589,525,393,700,661,589,525,661,
661,661,882,786,661,589,525,589,525,
589,786,661,882,786,661,589,525,589,
525,589,495,441

		};
	

	uint8_t time[] = {
		2, 2, 6, 2, 4, 4, 12, 4, 6,
2, 4, 4, 12, 2, 2, 6, 2, 2,
6, 6, 2, 2, 6, 6, 2, 4, 16,
2, 2, 6, 2, 4, 4,12, 4, 6,
2, 4, 4, 12, 2, 2, 4, 4, 2,
6, 4, 4, 8, 2, 2, 4, 4, 4,
12, 2, 2, 6, 2, 4, 4, 12, 2,
2, 6, 2, 4, 20, 2, 2, 4, 2,
2, 4, 6, 10, 4, 4, 4, 4, 12,
2,2, 8,8, 2,2,12, 12, 6,2,
4,4,16,8,8,2,2,12,6,
2,4,4,12
		};
	
	int32_t delayT;
	int16_t i,e;
	delayT = 10;
	for(i=0;i<sizeof(music)/sizeof(music[0]);i++)
        {
		for(e=0;e<((uint16_t)time[i])*music[i]/delayT;e++){
			Sound((uint32_t)music[i]);
		}
		HAL_Delay(40);
	}
}

int main(void)
{

  HAL_Init();

  SystemClock_Config();

  MX_GPIO_Init();


  unsigned int SONG_tone[]={212,212,190,212,159,169,212,212,190,212,142,159,212,212,106,126,159,169,190,119,119,126,159,142,159,0};
  unsigned int SONG_long[]={9,3,12,12,12,24,9,3,12,12,12,24,9,3,12,12,12,12,12,9,3,12,12,12,24,0};

	
   
  while (1)
  {
    /* for(int i=0;i<25;i++)
		for(int j=0;j<SONG_long[i]*150;j++){
		HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_8);
			for(int k=0;k<SONG_tone[i]*12;k++);} */
		play_music();
    	
  }
 
}

参考了以下视频(主要是它提到的公众号里的代码):

【无源蜂鸣器如何播放音乐?原理+代码解析】 https://www.bilibili.com/video/BV1kt421E7mQ/?share_source=copy_web&vd_source=9332b8fc5ea8d349a54c3989f6189fd3

天空之城的表来自微机实验指导书。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

guts350

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

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值