运用有源蜂鸣器,只能宣布固定的”滴滴“声,当然不能满意于此呀。运用无源蜂鸣器,只需输出不同频率的PWM波,即可宣布不同的音符。不同的音符组合起来便是一个曲子了。
1 曲谱简析
1.1 音阶
音阶是音乐必不可少的要素,首要由声响的频率决议。经过给蜂鸣器不同频率的音频脉冲,能够发生不同的音阶,而要发生某频率的音频脉冲,最简略的方法是算出该音频的周期,然后将此周期除以2即为半周期的时刻。经过程序操控单片机某引脚半周期为“高”、半周期为“低”,不断替换改换,即可发生该频率的矩形波,接到蜂鸣器上就可宣布该频率的声响。若想改动音阶,只需求改动半周期时刻即可。下表为各腔调音符频率对照表,据此可发生不同音阶的音符。“#”表明半音,用于上升或下降半个音,乘以2就提高该声响一个8度音阶,折半则降一个8度。
1.2 节拍
若要构成音乐,光有音阶是不行的,还需求节拍,也便是音符继续时刻的长短,一般用拍数表明。至于1拍是多少秒,没有严厉的规则,只需节拍适合,声响动听即可。假设某首歌曲的节奏是每分钟120拍,那么1拍为0.5 s,1/4拍为0.125 s,以此类推可得到其他节拍对应的时长。这样,运用不同的频率,加上与拍数对应的延时,就构成了乐曲。
2 STM32中的守时器
音阶的发生与声响频率有关,为了完成不同音阶,有必要能为蜂鸣器供给不同频率的脉冲。为此,挑选STM32芯片,运用其自带的守时器,经过PWM发生脉冲信号。STM32中一共有11个守时器,包含2个高档操控守时器、4个一般守时器、2个根本守时器,以及2个看门狗守时器和1个体系滴答守时器SysTIek。其间,TIM1和TIM8是高档守时器,时钟由APB2的输出发生。TIM2~TIM5是一般守时器,TIM6和TIM7是根本守时器,这6个守时器的时钟由APB1的输出发生。
2.1 守时时长的核算
守时器的一个首要功用便是到指守时刻就会发生一个溢出事情,这个时刻的设置与守时器时钟有关,在守时器时钟基础上进行预分频,设置计数溢出巨细即可。
2.1.1 体系时钟设置
要保证守时的准确性,有必要先保证体系时钟的设置是咱们所预期的。守时器时钟分配可检查数据手册。经过编程使SYSCLK为72 MHz,APB1预分频后得到PCLK1为36 MHz,再经TIM2~TIM7倍频器得到TIM2~TIM7时钟72 MHz。时钟源多选用HSE(外部时钟源),关于STM32F103,其外部时钟为8 MHz,而STM32F107外部时钟为25 MHz,因而,在运用HSE做时钟源时,这两种器材发生SYSCLK的分频和倍频方法不同,需求运用者引起留意。
2.1.2 守时器相关参数设置
守时器的参数由结构体TimeBaselnitTypeDef界说,首要包含预分频系数、时钟切割、计数器形式、计数溢出巨细等。例如,要由TIM3(守时器3)发生一个时长为1 s的守时,首要,应进行体系时钟的设置,得到TIM3CLK=72MHz,然后进行守时器设置。其间,预分频系数为35 999,此刻,TIM3时钟为72 MHz/36 000=2 kHz,无时钟切割。设置计数溢出巨细为1 999,即每计2 000个数就发生一个更新事情,输出频率为2 kHz/2 000=1 Hz。
2.2 STM32的PWM输出
脉冲宽度调制(Pulse Width Modulation,PWM)是运用微处理器的数字输出来对模仿电路进行操控的一种十分有用的技能,简而言之,便是完成对输出信号脉冲宽度的操控,一般用来操控步进电机等。STM32的守时器除了TIM6和TIM7之外,其他的守时器都能够用来发生PWM输出,其间,高档守时器TIM1和TIM8能够发生3对PWM互补输出,而TIM2~TIM5也能一起发生4路的PWM输出。
2.2.1 PWM输出引脚
STM32给不同的守时器分配了不同的输出引脚,考虑到引脚复用功用,STM32还提出了一个“重映像”的概念,便是经过设置某一些相关的寄存器,使得在其他非原始指定的引脚上也能输出PWM波形,可是这种重映像不是随意的,运用方法可参照参考文献。例如,TIM3的通道2,在没有重映像的时分,指定的引脚是PA7。假如设置部分重映像之后,输出就被映像到PB5上了;假如设置彻底重映像的话,输出就被映像到PC7上。
2.2.2 占空比的核算
占空比(Duty Ratio)有如下意义:在一串抱负的脉冲周期序列(如方波)中,正脉冲的继续时刻与脉冲总周期的比值。
当TIM_Period为1 999时,若想得到占空比50%,则TIM_Pulse应设置为(1999+1)/2=1000。
3.2 程序规划
改动PWM的腔调,能够输出Do re mi fa so la si do这样的7个音符,还能够输出不同腔调的Do re mi fa so la si do。
在实例程序里边,我界说了低中高三个音阶。音符的频率则是mbed供给的。现已宏界说好了。
只需改动PWM的输出周期,即可宣布不同的腔调(频率是周期的倒数)。
为了便利起见,写了一个音阶类(Pitch),虚基类。里边有一个perform函数,参数是音符和继续时刻。例如要宣布Do这个声响,继续0.5s,只需perform(1,0.5)就好。
还有一个Stop函数,中止响声0.5s则stop(0.5),无参数则直接中止。后边的Low、Mid、High类则是派生类,完成了Pitch的虚函数。
程序里边包含:
1、宣布低中高三个腔调的Do re mi fa so la si do音。
2、中音版的小星星。
3、低声版的小星星。
#include “mbed.h”
#define NOTE_B031
#define NOTE_C133
#define NOTE_CS1 35
#define NOTE_D137
#define NOTE_DS1 39
#define NOTE_E141
#define NOTE_F144
#define NOTE_FS1 46
#define NOTE_G149
#define NOTE_GS1 52
#define NOTE_A155
#define NOTE_AS1 58
#define NOTE_B162
#define NOTE_C265
#define NOTE_CS2 69
#define NOTE_D273
#define NOTE_DS2 78
#define NOTE_E282
#define NOTE_F287
#define NOTE_FS2 93
#define NOTE_G298
#define NOTE_GS2 104
#define NOTE_A2110
#define NOTE_AS2 117
#define NOTE_B2123
#define NOTE_C3131
#define NOTE_CS3 139
#define NOTE_D3147
#define NOTE_DS3 156
#define NOTE_E3165
#define NOTE_F3175
#define NOTE_FS3 185
#define NOTE_G3196
#define NOTE_GS3 208
#define NOTE_A3220
#define NOTE_AS3 233
#define NOTE_B3247
#define NOTE_C4262
#define NOTE_CS4 277
#define NOTE_D4294
#define NOTE_DS4 311
#define NOTE_E4330
#define NOTE_F4349
#define NOTE_FS4 370
#define NOTE_G4392
#define NOTE_GS4 415
#define NOTE_A4440
#define NOTE_AS4 466
#define NOTE_B4494
#define NOTE_C5523
#define NOTE_CS5 554
#define NOTE_D5587
#define NOTE_DS5 622
#define NOTE_E5659
#define NOTE_F5698
#define NOTE_FS5 740
#define NOTE_G5784
#define NOTE_GS5 831
#define NOTE_A5880
#define NOTE_AS5 932
#define NOTE_B5988
#define NOTE_C61047
#define NOTE_CS6 1109
#define NOTE_D61175
#define NOTE_DS6 1245
#define NOTE_E61319
#define NOTE_F61397
#define NOTE_FS6 1480
#define NOTE_G61568
#define NOTE_GS6 1661
#define NOTE_A61760
#define NOTE_AS6 1865
#define NOTE_B61976
#define NOTE_C72093
#define NOTE_CS7 2217
#define NOTE_D72349
#define NOTE_DS7 2489
#define NOTE_E72637
#define NOTE_F72794
#define NOTE_FS7 2960
#define NOTE_G73136
#define NOTE_GS7 3322
#define NOTE_A73520
#define NOTE_AS7 3729
#define NOTE_B73951
#define NOTE_C84186
#define NOTE_CS8 4435
#define NOTE_D84699
#define NOTE_DS8 4978
//7个音符组成了美好的音乐
//低Do re mi fa so la si do
int melody[] = {NOTE_C4, NOTE_D4,NOTE_E4, NOTE_F4, NOTE_G4,NOTE_A4,NOTE_B4,NOTE_C5};
//中Do re mi fa so la si do
int melody2[] = {NOTE_C5, NOTE_D5,NOTE_E5, NOTE_F5, NOTE_G5,NOTE_A5,NOTE_B5,NOTE_C6};
//高
int melody3[] = {NOTE_C6, NOTE_D6,NOTE_E6, NOTE_F6, NOTE_G6,NOTE_A6,NOTE_B6,NOTE_C7};
//PWM输出口
PwmOut m(PB_13);
//腔调类
class Pitch{
public:
virtual void perfrom(int,double)=0;
void stop(double time = 0){
if(time==0)
m = 1;
else{
m = 1;
wait(time);
}//end else
}//end stop
};
class Low:public Pitch{
public:
void perfrom(int index,double time){
m.period_us(1000000/melody[index-1]);
m.write(0.5);
wait(time);
}
}
来历;21ic