[STM32F1]

使用STM32F103控制蜂鸣器发声播放音乐

[复制链接]
1773|6
手机看帖
扫描二维码
随时随地手机跟帖
纠结的那些年|  楼主 | 2024-1-29 15:25 | 显示全部楼层 |阅读模式
一、有源蜂鸣器与无源蜂鸣器的区别
首先大家要了解有源和无源这里的“源”不是指电源,而是指震荡源。也就是说,有源蜂鸣器内部带震荡源,所以只要一通电就会叫。而无源内部不带震荡源,所以如果用直流信号无法令其鸣叫。必须用2K~5K的方波去驱动它。有源蜂鸣器往往比无源的贵,就是因为里面多个震荡电路。这就是通过驱动原理来分别的方法。

然后我们再来看看外观上区别吧(如下图)

8798265b752c948e05.png

从图a、b外观上看,两种蜂鸣器好像一样,但仔细看,两者的高度略有区别,有源蜂鸣器a,高度为9mm,而无源蜂鸣器b的高度为8mm。如将两种蜂鸣器的引脚郡朝上放置时,可以看出有绿色电路板的一种是无源蜂鸣器,没有电路板而用黑胶封闭的一种是有源蜂鸣器。

万用表测电阻区别

用万用表电阻档Rxl档测试:用黑表笔接蜂鸣器 "+"引脚,红表笔在另一引脚上来回碰触,如果触发出咔、咔声的且电阻只有8Ω(或16Ω)的是无源蜂鸣器;如果能发出持续声音的,且电阻在几百欧以上的,是有源蜂鸣器。同时有源蜂鸣器直接接上额定电源(新的蜂鸣器在标签上都有注明)就可连续发声;而无源蜂鸣器则和电磁扬声器一样,需要接在音频输出电路中才能发声。

使用特权

评论回复
纠结的那些年|  楼主 | 2024-1-29 15:25 | 显示全部楼层
无源蜂鸣器的优点是:

1、便宜

2、声音频率可控,可以做出“多来米发索拉西”的效果

3、在一些特例中,可以和LED复用一个控制口

有源蜂鸣器的优点是:程序控制方便。

因为无源蜂鸣器便宜,所以大部分人手里拿到的都是无源蜂鸣器,我这里使用的是也是无源蜂鸣器。

使用特权

评论回复
纠结的那些年|  楼主 | 2024-1-29 15:25 | 显示全部楼层
二、编程思路
这里思路很简单,就是做一个可变时间的延时开控制发声,关于延时可以使用定时器来做,但是这里为了简便,就是用了一个简单的延时来完成。

延时时间的长短可以改变声音的频率,这是本程序的关键。

但是这里有一个问题,如果要播放频率变化特别快的音乐,比如下面的《红尘情歌》,必须控制输出电流大小,直接连接单片机IO口是不行的,加一个100K欧姆的电阻可以听出来,但是声音特别小,不适合做提示。所以,定义了一个简单的提示音数组melody,来完成功能。

使用特权

评论回复
纠结的那些年|  楼主 | 2024-1-29 15:26 | 显示全部楼层
如下图所示,是蜂鸣器与STM32连接的电路图,程序中的“PBeep”就是图中的“BEEP”IO口的宏定义,一般在头文件中进行定义:
#define PBeep PBout(8)
4434865b7531957c15.png

使用特权

评论回复
纠结的那些年|  楼主 | 2024-1-29 15:26 | 显示全部楼层
三、相关代码
这里代码还是非常简单的,这里贴出beep.c文化和beep.h两个文件的代码,main.c文件可以调用相关函数,非常简单,就不贴出了。

后期如果有改进的话,会继续更新相关代码。

使用特权

评论回复
纠结的那些年|  楼主 | 2024-1-29 15:27 | 显示全部楼层
beep.c文件

#include "beep.h"

int melody[] = {50, 50, 50, 50, 200, 200, 200, 400, 400, 500, 500, 500};

void BEEP_Init(void)
{   
    GPIO_InitTypeDef  GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);         //使能A端口时钟
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;         
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
    GPIO_Init(GPIOB, &GPIO_InitStructure);          //初始化GPIOD3,6
    GPIO_SetBits(GPIOB,GPIO_Pin_5);       
}

void Sound(u16 frq)
{
        u32 time;
        if(frq != 1000)
        {
                time = 500000/((u32)frq);
                PBeep = 1;
                delay_us(time);
                PBeep = 0;
                delay_us(time);
        }else
                delay_us(1000);
}
void Sound2(u16 time)
{
    PBeep = 1;
    delay_ms(time);
    PBeep = 0;
    delay_ms(time);
}
void play_successful(void)
{
    int id=0;
    for(id = 0 ;id < 12 ;id++)
    {
        Sound2(melody[id]);
    }
}
void play_failed(void)
{
    int id=0;
    for(id = 11 ;id >=0 ;id--)
    {
        Sound2(melody[id]);
    }
}
void play_music(void)
{
        //              低7  1   2   3   4   5   6   7  高1 高2 高3 高4 高5 不发音
        uc16 tone[] = {247,262,294,330,349,392,440,294,523,587,659,698,784,1000};//音频数据表
        //红尘情歌
        u8 music[]={5,5,6,8,7,6,5,6,13,13,//音调
                5,5,6,8,7,6,5,3,13,13,
                2,2,3,5,3,5,6,3,2,1,
                6,6,5,6,5,3,6,5,13,13,

                5,5,6,8,7,6,5,6,13,13,
                5,5,6,8,7,6,5,3,13,13,
                2,2,3,5,3,5,6,3,2,1,
                6,6,5,6,5,3,6,1,       

                13,8,9,10,10,9,8,10,9,8,6,
                13,6,8,9,9,8,6,9,8,6,5,
                13,2,3,5,5,3,5,5,6,8,7,6,
                6,10,9,9,8,6,5,6,8};       
        u8 time[] = {2,4,2,2,2,2,2,8,4, 4, //时间
                2,4,2,2,2,2,2,8,4, 4,
                2,4,2,4,2,2,4,2,2,8,
                2,4,2,2,2,2,2,8,4 ,4,

                2,4,2,2,2,2,2,8,4, 4,
                2,4,2,2,2,2,2,8,4, 4,
                2,4,2,4,2,2,4,2,2,8,
                2,4,2,2,2,2,2,8,

                4, 2,2,2, 4, 2,2,2, 2,2,8,
                4, 2,2,2,4,2,2,2,2,2,8,
                4, 2,2,2,4,2,2,5,2,6,2,4,
                2,2 ,2,4,2,4,2,2,12};       
        u32 yanshi;
        u16 i,e;
        yanshi = 10;
        for(i=0;i<sizeof(music)/sizeof(music[0]);i++){
                for(e=0;e<((u16)time[i])*tone[music[i]]/yanshi;e++){
                        Sound((u32)tone[music[i]]);
                }       
        }
}

使用特权

评论回复
纠结的那些年|  楼主 | 2024-1-29 15:27 | 显示全部楼层
beep.h文件

#ifndef __BEEP__H
#define __BEEP__H

#include "sys.h"
#include "stdlib.h"          
#include "delay.h"

//定义GPIOB的位地址变量宏,位输入宏,输出宏
#define PBeep PBout(5)

void BEEP_Init(void);
void Sound(u16 frq);
void Sound2(u16 time);
void play_music(void);
void play_successful(void);
void play_failed(void);

#endif


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

43

主题

675

帖子

0

粉丝