amigenius 发表于 2020-1-2 15:04:02

开源伪和弦淫乐声的产生原理及电路,源码。

有位兄弟发帖问如何产生清脆的“丁丁”声音,手贱回了一帖,没想到引来更多兄弟对此的性趣。约下的炮,肯定要打完,在此奉上电路和源码。
其实,这种听起来比较悦耳的声音产生原理也非常简单。就是利用电容的放电产生一个渐弱的尾音,模拟出击打风铃的音色。
电路如下:

BUZ-H负责输出音频频率,BUZ-L负责对C12的充电作控制。
例如,要发出“叮~~~~”的一声,在BUZ-H输出2400Hz的方波,BUZ-L输出72ms的高电平,此段时间内,蜂鸣器将由幅值12V的频率驱动,发出类似击打瞬间的声音,同时对C12充电。72ms后,BUZ-L输出低电平,这个时候,蜂鸣器将由C12来提供驱动电流,并且随著电容放电,声音逐渐减弱,产生类似风铃尾音的效果。1秒后,关闭BUZ-H的输出。
这种发声方式,其实还是单音频发声,只是在单音频的基础上,用电容的充放电模拟了击打和尾音,产生比较丰满悦耳的听感,所以称之为“伪和弦”。
各位有兴趣的话,可以用多个蜂鸣器同时发出不同音调,组成多音的真和弦,一个音调输出占用一个定时器。俺以前10多年前蛋疼,搞过几十个蜂鸣器的(5和弦,蜂鸣器多个并联),并且并增加一个IO用作电容的放电回路来产生短音,听感还是不错的。真有空时回老家翻出来拍个视频给大家看看。
源码如下,带音量控制,带家电常用的音调组合,还附上一个超级玛丽的1UP声音,玩过的朋友肯定会觉得很亲切,哈哈。
源码不是整个工程,我也懒得整理了,生活艰苦,搬砖不易。
用法,在您的工程里面增加两个文件,一个名为Music.c,一个名为Music.h(头文件)。现在源码,使用的是STM32F1xx,主频72M,使用的定时器是TIM2(任意定时器均可,自己修改),使用硬件PWM输出。所以您单片机有N个定时器,则可以最多N-1个真和弦(留一个做主时基),做产品,通常一个伪和弦就够了。Music_Srv()这个函数,没4ms调用一次,您放中断也行,放主循环也行(前提是您主循环没有阻塞的占用)。需要发声的时候,任意地方放一句 Music_Triger=MUSIC_XXX;即可,不阻塞,也不用等它播完再调用,随传随叫春。
BUZ-L现在接的是PA1,这个任意IO即可,请自行修改。BUZ-H接的是PA0,这个随您用不同的TIM而不同,自己修改,例程用的是TIM2。

//*************************************************************************************************************************************
Music.h源码:

#ifndef __MUSIC_H_
#define __MUSIC_H_

//BUZ-L定义IO
#define BEEPL_1 GPIOA_DSRR=BIT1
#define BEEPL_0 GPIOA_DRR=BIT1
#define BEEPL_XOR {if(BitTst(GPIOA_ODR,BIT1)) BEEPL_0; else BEEPL_1;}

//音乐声定义
#define MUSIC_PWR_UP 1
#define MUSIC_TURN_ON 2
#define MUSIC_TURN_OFF 4
#define MUSIC_DING 3
#define MUSIC_UP 5
#define MUSIC_DOWN 6
#define MUSIC_1UP 7

extern volatileuint8Music_Triger;    //触发发声标志
extern uint8flg_MusicPlaying;         //非0表示正在发声


void Music_Srv(void);   //4ms调用一次
void Music_InitIO(void);    //初始化IO
void Music_Init(void);   //初始化Music模块。

#endif


//*************************************************************************************************************************************
Music.c源码:
#include "music.h"


#define TIM2_ARR (*((volatile uint16 *)(TIM2_BASE + 0x002c)))
#define TIM2_CR1 (*((volatile uint16 *)(TIM2_BASE + 0)))
#define TIM2_CCR1 (*((volatile uint16 *)(TIM2_BASE + 0x0034)))
#define TIM2_CCER (*((volatile uint16 *)(TIM2_BASE + 0x0020)))
#define TIM2_CNT   (*((volatile uint16 *)(TIM2_BASE + 0x0024)))
#define TIM2_CCR2 (*((volatile uint16 *)(TIM2_BASE + 0x0038)))




// 定义常用频率,数字多少就是多少Hz
#define _28 2850   
#define _24 2400
#define _22 2250
#define _21 2100
#define _18 1850
#define _16 1650


// 定义duo,rui,mi,fa,so等等
#define _l1 130
#define _l2 146
#define _l3 164
#define _l4 174
#define _l5 196
#define _l6 220
#define _l7 246

#define _1 261
#define _2 293
#define _3 329
#define _4 349
#define _5 392
#define _6 440
#define _7 494

#define _1d1 523
#define _2d1 587
#define _3d1 659
#define _4d1 698
#define _5d1 784
#define _6d1 880
#define _7d1 987

#define _1d2 1046
#define _2d2 1175
#define _3d2 1318
#define _4d2 1397
#define _5d2 1568
#define _6d2 1760
#define _7d2 1976

#define _1d3 (_1d2*2)
#define _2d3 (_2d2*2)
#define _3d3 (_3d2*2)
#define _4d3 (_4d2*2)
#define _5d3 (_5d2*2)
#define _6d3 (_6d2*2)
#define _7d3 (_7d2*2)


//定义不同的乐曲数组,0 结束
const uint16 Music1_FrqTab[]={//频率表,对应BUZ-H的输出频率,0 结束
        _18,        _18,        _21,        _21,        _24,        _24,        _28,        _28,        0,
};
const uint8 Music1_TimeTab[]={        //BUZ-L输出时间,偶数高电平,奇数为低电平尾音,x4ms,0 结束
        20,        30,        20,        30,        20,        30,        20,        255,        0,
};


const uint16 Music2_FrqTab[]={
        _21,        _21,        _22,        _22,        _24,        _24,        0
};
const uint8 Music2_TimeTab[] ={                //x4ms
        10,        18,        10,        18,        10,        255,        0,
};


constuint16 Music3_FrqTab[]={
        _24,        _24,        0,
};
constuint8 Music3_TimeTab[] ={                //x4ms
        18,        255,        0,
};


constuint16 Music4_FrqTab[] ={
        _28,        _28,        _24,        _24,        _21,        _21,        0
};
constuint8 Music4_TimeTab[]={                //x4ms
        10,        18,        10,        18,        10,        255,        0,
};


constuint16 Music5_FrqTab[] ={
        _16,        _16,        _18,        _18,        _21,        _21,        0
};
constuint8 Music5_TimeTab[] ={                //x4ms
        6,        16,        6,        16,        6,        255,        0,
};


constuint16 Music6_FrqTab[] ={
        _21,        _21,        _18,        _18,        _16,        _16,        0
};
constuint8 Music6_TimeTab[] ={                //x4ms
        6,        16,        6,        16,        6,        255,        0,
};




const uint16 Music7_FrqTab[]={
        1324,1324,1574,1574,2645,2645,        2114,2114,2347,2347,3154,3154,        0,
};
const uint8 Music7_TimeTab[]={                //x4ms
        15,          25,           15,          25,   15,    25,        15,   25        , 15 ,   25,15,255,        0,
};




uint8 Music_Vol=137;    //音量
volatile uint8Music_Triger=0;   //触发播放哪一支,例如播放“叮~~~”,则任意地方调用 Music_Triger=MUSIC_DING;
uint8flg_MusicPlaying=0;   //非零播放中。

//乐曲表指针
uint16 const*music_frq_tab;      
uint8 const*music_interval_tab;




TIM_TimeBaseInitTypeDef T2_TimeBaseStruct;
TIM_OCInitTypeDef T2_OCInitStruct;

void Music_SetVolumn(uint8 vol){   //设置音量,并且初始化TIM输出
        uint32 lTmp;
        lTmp=T2_TimeBaseStruct.TIM_Period;
        lTmp*=vol;
        lTmp/=255;
        T2_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;            
        T2_OCInitStruct.TIM_Pulse = lTmp;
        T2_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
        T2_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
        TIM_OC1Init(TIM2, &T2_OCInitStruct);
}


/* ---------------------------------------------------------------
TIM2 Configuration: Output Compare Toggle Mode:
TIM2CLK = 72 MHz, Prescaler = 0x9, TIM2 counter clock = 7.2 MHz
--------------------------------------------------------------- */

void Music_SetFrq(uint16 frq){    //设置频率并初始化TIM
        uint32 clk;
        clk=7200000;
        clk/=frq;
        clk--;
        /* Time base configuration */
        T2_TimeBaseStruct.TIM_Period = clk;         
        T2_TimeBaseStruct.TIM_Prescaler = 0x9;      
        T2_TimeBaseStruct.TIM_ClockDivision = 0x0;   
        T2_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
        TIM_TimeBaseInit(TIM2, &T2_TimeBaseStruct);

        Music_SetVolumn(Music_Vol);
       
}


void Music_ChangeFrq(uint16 frq){    //改变频率。
        uint32 clk;
        clk=7200000;
        clk/=frq;
        clk--;
        /* Time base configuration */
        TIM2_ARR = clk;   
        clk*=Music_Vol;
        clk/=255;
        TIM2_CCR1=clk;
}


void Music_Frq_Enable(void){
        TIM2_CCER|=BIT0;
}

void Music_Frq_Diable(void){
        TIM2_CCER&=(~BIT0);
}



void Music_Init(void){
        Music_SetFrq(4000);

        TIM_ARRPreloadConfig(TIM2, ENABLE); // 这个记得要开

        //启用CCR1寄存器的影子寄存器(直到产生更新事件才更改设置)
        TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);

        Music_Frq_Diable();
        TIM_Cmd(TIM2, ENABLE);
}


void Music_InitIO(void){
        GPIO_InitTypeDef tmpGPIO;
       
        tmpGPIO.GPIO_Mode=GPIO_Mode_Out_PP;
        tmpGPIO.GPIO_Speed=GPIO_Speed_50MHz;

        tmpGPIO.GPIO_Pin=GPIO_Pin_1;
        GPIO_Init(GPIOA,&tmpGPIO);

        tmpGPIO.GPIO_Pin=GPIO_Pin_0;
        tmpGPIO.GPIO_Mode=GPIO_Mode_AF_PP;
        GPIO_Init(GPIOA,&tmpGPIO);
       
        BEEPL_1;
}


void Music_Select(void){
        switch(Music_Triger){
                default:       
                        flg_MusicPlaying=0;
                        return;
                case MUSIC_PWR_UP:
                        music_frq_tab=Music1_FrqTab;
                        music_interval_tab=Music1_TimeTab;
                        break;
                case MUSIC_TURN_ON:
                        music_frq_tab=Music2_FrqTab;
                        music_interval_tab=Music2_TimeTab;
                        break;
                case MUSIC_DING:
                        music_frq_tab=Music3_FrqTab;
                        music_interval_tab=Music3_TimeTab;
                        break;
                case MUSIC_TURN_OFF:
                        music_frq_tab=Music4_FrqTab;
                        music_interval_tab=Music4_TimeTab;
                        break;
                case MUSIC_UP:
                        music_frq_tab=Music5_FrqTab;
                        music_interval_tab=Music5_TimeTab;
                        break;
                case MUSIC_DOWN:
                        music_frq_tab=Music6_FrqTab;
                        music_interval_tab=Music6_TimeTab;
                        break;
                case MUSIC_1UP:
                        music_frq_tab=Music7_FrqTab;
                        music_interval_tab=Music7_TimeTab;
                        break;
        }
        flg_MusicPlaying=1;
}



void Music_Srv(void){
        static uint8PlayStep=0;
        static uint8PlayCt=0;
        uint8 cTmp;

        if(Music_Triger){
                Music_Select();
                Music_Triger=0;
                PlayStep=0;
                PlayCt=0;
               
                Music_ChangeFrq(music_frq_tab);
                Music_Frq_Enable();

                BEEPL_1;
        }
        if(flg_MusicPlaying){
                cTmp=music_interval_tab;
                PlayCt++;
                if(PlayCt>=cTmp){
                        PlayCt=0;
                        PlayStep++;
                        Music_ChangeFrq(music_frq_tab);
                        if(music_interval_tab==0){
                                flg_MusicPlaying=0;       
                        }
                        else{
                                BEEPL_XOR;
                        }
                }
               
        }
        else{
                BEEPL_0;
                Music_Frq_Diable();
        }
}



HappySmile 发表于 2020-1-2 15:05:38

楼主好人,1024。

chunjiu 发表于 2020-1-2 15:05:42

赞哦,支持兄弟的奉献! {:lol:}

ssaiwo 发表于 2020-1-2 15:06:30

顶楼主,感兴趣

qq854149876 发表于 2020-1-2 15:07:19

感谢分享,谢谢

hzpyl 发表于 2020-1-2 15:08:18

好人 1024

our2008 发表于 2020-1-2 15:09:15


楼主好人,1024。

talkingbeast 发表于 2020-1-2 15:09:17


好人 1024

Mrp_Young 发表于 2020-1-2 15:10:10

楼主给力,赞

落叶知秋 发表于 2020-1-2 15:10:49

约下的炮,肯定要打完
对于这种负责任的态度,表示“钦敬” {:biggrin:}

SUPER_CRJ 发表于 2020-1-2 15:11:38

今晚约一下!

nokia007 发表于 2020-1-2 15:12:17

赞,这得花不少功夫研究

amigenius 发表于 2020-1-2 15:14:10

盖楼速度有点快,补充一下,最好使用TDK的17mm的无源蜂鸣器,声音非常悦耳,某商城有卖。

xymxym 发表于 2020-1-2 15:14:45

楼主好人,一晚几十炮。{:lol:}

lrzxc 发表于 2020-1-2 15:16:31

本帖最后由 lrzxc 于 2020-1-2 15:46 编辑

问下楼主,图中的buz是无源的蜂鸣器?
============================
看到了,为仔细看帖,原来13楼有关于蜂鸣器的说明

lzg1987 发表于 2020-1-2 15:17:22

给力,祝楼主新年快乐。

gdoujiajia 发表于 2020-1-2 15:18:00

楼主厉害,标题很劲爆

ljq77402 发表于 2020-1-2 15:24:57

这个供电电压要12V,,,3.3V或者5~6V不行吗?很多手持设备没12V的

amigenius 发表于 2020-1-2 15:26:47

ljq77402 发表于 2020-1-2 15:24
这个供电电压要12V,,,3.3V或者5~6V不行吗?很多手持设备没12V的

多少伏都行,3.3也行,声音小一些而已,听感一样的。

zzj2009a1 发表于 2020-1-2 15:27:56

不错,多谢分享!

PCBBOY1991 发表于 2020-1-2 15:28:15

给大佬点赞。

tim 发表于 2020-1-2 15:32:51

求贴效果录音听听

wowangru 发表于 2020-1-2 15:34:31

祝楼主一晚几十炮

pisgah 发表于 2020-1-2 15:37:10

给楼主赞一个{:victory:}

tiger_wu 发表于 2020-1-2 15:37:50

强!多谢分享!

XA144F 发表于 2020-1-2 15:39:00

战略性马克!祝楼主一夜七次狼。

powermeter 发表于 2020-1-2 15:40:18

来听听淫乐声{:lol:}

chendy6868 发表于 2020-1-2 15:40:24

好人 1024

weare 发表于 2020-1-2 15:43:42

楼主无私奉献,收藏点赞!!!

磊磊映画 发表于 2020-1-2 15:45:38

amigenius 发表于 2020-1-2 15:14
盖楼速度有点快,补充一下,最好使用TDK的17mm的无源蜂鸣器,声音非常悦耳,某商城有卖。 ...

楼主说到做到,好样的 点赞

Name_006 发表于 2020-1-2 15:51:36

学习学习长见识了

weiwei4 发表于 2020-1-2 15:54:31

amigenius 发表于 2020-1-2 15:14
盖楼速度有点快,补充一下,最好使用TDK的17mm的无源蜂鸣器,声音非常悦耳,某商城有卖。 ...

看来这个很重要

我是一个大白菜 发表于 2020-1-2 15:58:34

楼主好人,以后约炮肯定都是大美女

jackjiao 发表于 2020-1-2 16:00:02

楼主好人,学习学习,小小蜂鸣器玩法挺多

nic_911 发表于 2020-1-2 16:00:53

楼主好人啊,非常感谢~~~

2avr 发表于 2020-1-2 16:02:10

楼主好人,1024。

jackrich 发表于 2020-1-2 16:03:25

楼主真好,学习了,点赞!

plc_avr 发表于 2020-1-2 16:03:52

楼主这次约的都是老男人,下次约美女,{:titter:}

xiaomu 发表于 2020-1-2 16:05:23

学习了,楼主 1024!

moouse 发表于 2020-1-2 16:05:40

祝楼主炮火连天

jzjia 发表于 2020-1-2 16:09:42

好人 1024

lovejp1981 发表于 2020-1-2 16:10:17

祝楼主炮火连天

cyjkai 发表于 2020-1-2 16:10:49

谢谢楼主分享

amigenius 发表于 2020-1-2 16:11:32

tim 发表于 2020-1-2 15:32
求贴效果录音听听

等有兄弟弄出来,就请他上传一下吧,我也懒得回老家翻以前的项目垃圾了,估计要翻个半天才能找到

eastbest 发表于 2020-1-2 16:14:27

好东西,多谢楼主分享!

kebaojun305 发表于 2020-1-2 16:14:39

amigenius 发表于 2020-1-2 15:14
盖楼速度有点快,补充一下,最好使用TDK的17mm的无源蜂鸣器,声音非常悦耳,某商城有卖。 ...

在严谨点,应该说无源压电蜂鸣器,因为无源 还有电磁式的。有点班门弄斧了。{:lol:}

amigenius 发表于 2020-1-2 16:15:38

看看春节有没有时间回老家翻出以前的项目垃圾,里面有周华健的爱相随 的3和弦,在此基础上加个液晶或OLED配上淫乐,做个电子情书撩妹应该不错。

seti 发表于 2020-1-2 16:18:02

楼主好人,1024{:titter:}

cc1987 发表于 2020-1-2 16:21:12

{:biggrin:}不错

风的微笑 发表于 2020-1-2 16:21:41

LZ好人 顶顶

foxpro2005 发表于 2020-1-2 16:26:21

感谢楼主分享,有空折腾一下玩玩

MyAVR 发表于 2020-1-2 16:29:34

怎么想到的啊,LZ利害啊,

touch_mcu 发表于 2020-1-2 16:33:25


祝楼主炮火连天!

wmm20031015 发表于 2020-1-2 16:41:06

感谢楼主,有时间搭个电路试试{:lol:}

亽亼 发表于 2020-1-2 16:45:55

楼主好人,mark

qtechzdh 发表于 2020-1-2 16:49:05

楼主好人,祝楼主夜夜做新郎

0712 发表于 2020-1-2 16:50:10

LZ这个蜂鸣器不用无源电磁式的吗?

zzz123456 发表于 2020-1-2 16:58:29

收藏了,谢谢分享

JnzGoto 发表于 2020-1-2 17:00:55

哇咧,这个妙妙妙

Mercurzy 发表于 2020-1-2 17:16:45

撸主好人一生平安,1024,收藏了

hell-prototypes 发表于 2020-1-2 17:22:05

楼主牛逼,收藏学习

gzwirelesss 发表于 2020-1-2 17:25:40

好人 1024

wangchin1988 发表于 2020-1-2 17:26:18

好帖,必须收藏。

041012js 发表于 2020-1-2 17:28:17

楼主厉害了

OOXX110 发表于 2020-1-2 17:28:40

楼主好人,1024{:lol:}

gwj221 发表于 2020-1-2 17:29:10

怎么想到的啊,LZ利害啊,

gqjxy 发表于 2020-1-2 17:29:14

楼主强人,顶你

Pupil 发表于 2020-1-2 17:30:59

楼主好人,1024

et009tw 发表于 2020-1-2 17:31:35

好資料,多謝分享。

security 发表于 2020-1-2 17:33:16

楼主好人

蛋定 发表于 2020-1-2 17:37:37

楼主好人,1024。

我是谁712 发表于 2020-1-2 17:44:13

感觉好厉害,楼主这是你原创的吗,佩服一下

rclong 发表于 2020-1-2 17:57:43

看起来这个很厉害啊
我看B站上大部分的蜂鸣器视频还停留在基本的旋律上
老哥这个代码完爆他们的

leijiayou 发表于 2020-1-2 17:59:09

1024   mark下

huangqi412 发表于 2020-1-2 18:01:33

这次约了一群抠脚大汉{:titter:}

ycwjl728 发表于 2020-1-2 18:03:29

楼主牛逼,学习了。

dcl_yufeimen 发表于 2020-1-2 18:12:23

楼主好人 1024

Pjm2008 发表于 2020-1-2 18:16:41

谢谢分享,好人一生平安

tuy0326 发表于 2020-1-2 18:17:39

楼主牛逼,学习了。

谭春林 发表于 2020-1-2 18:24:29

楼主牛掰,想看下楼主当年拍的视频{:lol:}

ddz123abcdef 发表于 2020-1-2 18:27:37

楼主好人,学习了

FireBrain 发表于 2020-1-2 18:32:17

要产生不同的乐声,是不是还得学习下乐理知识

huangguimina4 发表于 2020-1-2 18:46:53

楼主好人,1024

fuu 发表于 2020-1-2 18:51:50

好人一生平安,1024

hanbing333444 发表于 2020-1-2 18:52:29

楼主好人,蜂鸣器多了一种玩法。

了无 发表于 2020-1-2 18:56:57

楼主好人一生平安,1024

nsj21n 发表于 2020-1-2 19:00:26

感谢楼主奉献,学到了,这玩意儿还有这样的玩法,高

负西弱 发表于 2020-1-2 19:00:54

楼主好人,1024

Frank.Dong 发表于 2020-1-2 19:03:29

学习了,多谢

kexiao 发表于 2020-1-2 19:09:22

超级棒,哪位再配个实物音频就更棒了!

skype 发表于 2020-1-2 19:21:33


感谢楼主奉献

genhao2 发表于 2020-1-2 19:35:24

音乐贺卡效果?

skynet 发表于 2020-1-2 19:38:05

感谢,实用,好用,方便

yanyanyan168 发表于 2020-1-2 19:48:27

撸主好人一生平安,1024,收藏了

lnso 发表于 2020-1-2 19:50:32

感谢楼主无私

my2jia 发表于 2020-1-2 20:15:03

楼主好人1024

ibichao 发表于 2020-1-2 20:25:10

支持分享,收藏备用,谢谢。

biezhen 发表于 2020-1-2 20:28:32

感谢,实用,好用,方便

eyancool 发表于 2020-1-2 20:29:31

学习了,谢谢!

heimareed 发表于 2020-1-2 21:37:58

HappySmile 发表于 2020-1-2 15:05
楼主好人,1024。

有种走错了地方的赶脚~{:lol:}
页: [1] 2 3
查看完整版本: 开源伪和弦淫乐声的产生原理及电路,源码。