凌亂的DSP筆記(3)-蜂鳴器播放音樂


1. 蜂鳴器介紹

蜂鳴器是一種一體化結構的電子訊響器,采用直流電壓供電,廣泛應用於計算機、 打印機、 復印機、 報警器、 電子玩具、 汽車電子設備、 電話機、 定時器等電子產品中作發聲器件。蜂鳴器主要分為壓電式蜂鳴器和電磁式蜂鳴器兩種類型。

壓電式蜂鳴器(無源蜂鳴器)主要由多諧振盪器、 壓電蜂鳴片、 阻抗匹配器及共鳴箱、 外殼等組成。 多諧振盪器由晶體管或集成電路構成, 當接通電源后( 1.5~15V 直流工作電壓),多諧振盪器起振,輸出 1.5~5kHZ 的音頻信號, 阻抗匹配器推動壓電蜂鳴片發聲。

電磁式蜂鳴器(有源蜂鳴器)由振盪器、 電磁線圈、 磁鐵、 振動膜片及外殼等組成。接通電源后,振盪器產生的音頻信號電流通過電磁線圈, 使電磁線圈產生磁場, 振動膜片在電磁線圈和磁鐵的相互作用下,周期性地振動發聲。

2. 硬件設計

image

image

ULN2003 是高壓大電流達林頓晶體管陣列系列產品,具有電流增益高、工作電壓高、溫度范圍寬、帶負載能力強等特點,適應於各類要求高速大功率驅動的系統。

image

3. 軟件設計

3.1 beep

首先仿照LED建立beep.c和beep.h。

/*
 * beep.c
 *
 *  Created on: 2020-4-6
 *      Author: lenovo
 */

#include "beep.h"

/*******************************************************************************
* 函 數 名         : BEEP_Init
* 函數功能           : 蜂鳴器初始化
* 輸    入         : 無
* 輸    出         : 無
*******************************************************************************/
void BEEP_Init(void)
{
    EALLOW;
    SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1;// 開啟GPIO時鍾
    //BEEP端口配置
    GpioCtrlRegs.GPAMUX1.bit.GPIO6=0;
    GpioCtrlRegs.GPADIR.bit.GPIO6=1;
    GpioCtrlRegs.GPAPUD.bit.GPIO6=0;

    EDIS;

    GpioDataRegs.GPACLEAR.bit.GPIO6=1;

}
/*
 * beep.h
 *
 *  Created on: 2020-4-6
 *      Author: lenovo
 */

#ifndef BEEP_H_
#define BEEP_H_

#include "DSP2833x_Device.h"     // DSP2833x 頭文件
#include "DSP2833x_Examples.h"   // DSP2833x 例子相關頭文件


#define BEEP_ON            (GpioDataRegs.GPASET.bit.GPIO6=1)
#define BEEP_OFF        (GpioDataRegs.GPACLEAR.bit.GPIO6=1)
#define BEEP_TOGGLE        (GpioDataRegs.GPATOGGLE.bit.GPIO6=1)

void BEEP_Init(void);

#endif /* BEEP_H_ */

#define L1 0
#define L2 2
#define L3 4
#define L4 5
#define L5 7
#define L6 9
#define L7 11
#define M1 12
#define M2 14
#define M3 16
#define M4 17
#define M5 19
#define M6 21
#define M7 23
#define H1 24
#define H2 26
#define H3 28
#define H4 29
#define H5 31
#define H6 33
#define H7 35

音調按照十二平均律進行計算,方法在下面給出。

3.2 main.c

/*
 * main.c
 *
 *  Created on: 2020年4月6日
 *      Author: lenovo
 */
#include "DSP2833x_Device.h"     // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h"   // DSP2833x Examples Include File
#include "beep.h"

int tune[]=                 //根據簡譜列出各頻率
{
  M3,M3,M3,M2,M3,M5,M5,M5,
  M6,M6,M6,M5,M3,M6,M5,M5,
  H1,H1,H1,M6,H2,H1,M5,M5,

  M6,M6,M6,H1,M6,M5,M3,M2,
  M3,M3,M3,M2,M3,M5,M5,M5,
  M6,M6,M6,M5,M3,M5,M6,M5,

  H1,H1,M6,H2,H1,M5,M5,
  M6,M6,M6,M5,M6,H3,H2,
  H2,M5,H1,H2,
  H3,H2,H1,M7,H1,M7,M6,M5,

  M6,0,0,H1,H2,
  H3,H2,H1,M7,H1,M7,M3,M5,
  M6,0,M6,M5,
  M6,H1,H1,0,H1,H2,

  H3,H1,H2,H1,H1,M6,M6,
  H4,H3,H2,H1,H4,H4,H3,H2,H1,
  H2,H3,H2,H1,
  H1,H1,H2,H3,H1,

  H6,H5,H3,H2,H1,M6,
  0,M5,H1,H3,H5,H6,H3,H3,H2,H1,
  M6,H1,H1,H2,H1,H1
};

float beat[]=                   //根據簡譜列出各節拍
{
  0.25,0.25,0.25,0.25,0.5,0.25,0.25,2,
  0.25,0.25,0.25,0.25,0.5,0.25,0.25,2,
  0.25,0.25,0.25,0.25,0.5,0.25,0.25,2,

  0.25,0.25,0.25,0.25,0.25,0.5,0.25,2,
  0.25,0.25,0.25,0.25,0.5,0.25,0.25,2,
  0.25,0.25,0.25,0.25,0.5,0.25,0.25,2,

  0.25,0.5,0.25,0.5,0.25,0.25,2,
  0.25,0.25,0.25,0.25,0.5,0.5,2,
  0.5,0.5,0.5,0.5,
  0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,

  2,1,0.5,0.25,0.25,
  0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,
  3,0.5,0.25,0.25,
  0.5,0.5,1,0.5,1,0.5,

  0.5,0.5,0.5,0.5,1.5,0.25,0.25,
  0.5,0.5,0.5,0.25,0.25,0.5,0.5,0.5,0.5,
  3,0.5,0.25,0.25,
  1,0.5,0.5,1.5,0.5,

  0.5,0.5,0.25,0.25,0.5,2,
  0.5,0.5,0.5,0.5,0.5,0.25,0.25,0.25,0.25,0.5,
  0.5,0.5,0.25,0.5,0.25,2
};

/*******************************************************************************
* 函 數 名         : main
* 函數功能           : 主函數
* 輸    入         : 無
* 輸    出         : 無
*******************************************************************************/
void main()
{
    //不同音調的延時時長
    double tab[36]={1918};
    double rate=1.059463;//2^(1/12)
    int n;
    for(n=1;n<36;n++)
    {
        tab[n]=tab[n-1]/rate;
    }

    InitSysCtrl();
    BEEP_Init();

    int len;//音符個數
    len=sizeof(tune)/sizeof(tune[0]);
    while(1)
    {
        int i,j;
        for(i=0;i<len;i++)
        {
            if(tune[i]==0)
            {
                DELAY_US(beat[i]*800000);
            }
            else
            {
                for(j=0;j<beat[i]*800000/tab[tune[i]];j++)
                {
                    BEEP_TOGGLE;
                    DELAY_US(tab[tune[i]]);
                }
                DELAY_US(25000);//音符之間間隔0.025s
            }
        }
        DELAY_US(2000000);//播放結束延時2s
    }
}

首先,將“我只在乎你”簡譜轉換為音調tune和時長beat數組。

image

然后根據十二平均律,從低音do的1918us翻轉一次(260.7Hz),依次乘以${2^{1/12}}{\rm{ = }}1.059463$,得到數組tab。

之后進行循環播放。

4. 效果

https://www.bilibili.com/audio/au1470042?type=1?type=6


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM