STM32F4上的蜂鸣器引脚为PF8
蜂鸣器外部有上拉电源,因此引脚给1,只是为了有微小的驱动电源,通过三极管放大电流后驱动蜂鸣器。因此引脚为推挽下拉输出
不能IO口直接驱动大功率器件
IO口的电流很小,一般只做判断或基本驱动,一般会在外部接入三极管放大电流
stm32的IO口默认状况为浮空
1 void playTone(int beats, int tune){ 2 int time = 500000/tune; //计算频率半周期,us 3 if (tune != -1){ 4 for(int beat = 0; beat < beats; beat++){ 5 GPIO_SetBits(GPIOF, GPIO_Pin_8); 6 delay_us(time); 7 GPIO_ResetBits(GPIOF, GPIO_Pin_8); 8 delay_us(time); 9 } 10 11 } 12 else{ 13 GPIO_ResetBits(GPIOF, GPIO_Pin_8); 14 for(int beat = 0; beat < beats; beat++){ 15 delay_ms(2); 16 } 17 } 18 }
此代码为播放单音频率和延时函数,输入节拍数和音调频率
在这里需要将频率转化成半周期的时长,us
1.如何控制音调
通过delay_us(time)函数,一般里面为500-3000us秒左右,在经过快速的for循环的时候,达到播放音效的目的
2.如何控制声音播放时间
通过for()循环,众所周知,for循环在循环时有一定的时长,通过这个时长播放声音时间,一般来说当beats=400左右时,大概时间为0.5-1.5s左右
3.单音时长时间计算
如果发Do音(294)和So音(441),在4/4拍中的其中一个小节单独发声,假设一个拍子的beats=400,可以估算发Do的声音时长为(500000/294)*2*400/1000/1000=1.36s,而So音的声音时间长度为(500000/441)*2*400/1000/1000=0.9s。不难看出,其实此代码在同一节拍,播放相同时长的声音是比较困难的,因为每个音的发生频率都不一样,即延时不同,延时不同造成在同一时长节拍下,频率高的播放时间相对较短
4.if判断语句
if判断语句是用来检验是否有空闲非唱歌时间,在另外的代码里,空闲时会传入int 型数字-1,因此需要判断停止是否停止发声