蜂鸣器-播放音乐
- 一、原理介绍
- 1.硬件电路
- 二、练习
- 1.让蜂鸣器发声
- 2.尝试演奏小星星
一、原理介绍
蜂鸣器分为有源蜂鸣器、无源蜂鸣器两种。
有源蜂鸣器:施加合适的电压之后就会发出特定频率的声音
无源蜂鸣器:需要提供特定频率的声音信号,才能发出声音
1.硬件电路
这里的ULN2003芯片是提高单片机驱动蜂鸣器能力的,可以暂时不用关注
通过原理图可以知道,让P25(P15)管脚交替的输出高低电平就可以让蜂鸣器发出声音
二、练习
1.让蜂鸣器发声
无源蜂鸣器需要输入一个频率才能发生,这里通过改变P1^5引脚的高低电平来使蜂鸣器发声
(有些板子好像是P2^5,这个可以实际测试下)
#include "reg52.h"sbit BEEP = P1^5; void delay_10us(int time_us) {while(time_us--);
}void start_beep(int fre) {int delay = 90;while(delay){BEEP = 0;delay_10us(fre); BEEP = 1;delay_10us(fre);delay--;}
}void main() {while(1) {start_beep(300);start_beep(600);}
}
2.尝试演奏小星星
参考了两篇博客将音高和频率对应的数据先生成
简书:音高、频率速查
CSDN:音符频率算法
先用C写了计算音高的实例
#include <stdio.h>
#include <math.h>#define FRE_COL 8
#define FRE_ROW 11const float STABDARD_FRE = 440.0;
// C C# D D# E F# G G# A A# B
float freMap[FRE_COL][FRE_ROW]; // 11个为一组算出音高-频率对应关系
float timeMap[FRE_COL][FRE_ROW]; // 11个为一组算出音高-周期对应关系 t=1000/fre msvoid initFre() {for(int i = 0;i < FRE_COL;i++) {for(int j = 0;j < FRE_ROW;j++) {int index = (i * FRE_ROW) + j + 60;float fre = (STABDARD_FRE / 32.0) * pow(2, (index - 9.0) / 12.0);freMap[i][j] = fre;timeMap[i][j] = 1000 / fre;}}
}void printFre() {for(int i = 0;i < FRE_COL;i++) {for(int j = 0;j < FRE_ROW;j++) {// printf("%lf ", freMap[i][j]);printf("%lf ", timeMap[i][j]);}printf("\n");}
}int main() {initFre();printFre();return 0;
}
但是由于单片机内存限制,放不下这么大的数组,只能改成int数组,来存储声音数据
最终的实现代码如下
#include <reg52.h>
#include <intrins.h>sbit BEEP = P1^5;// 三组音高 1-7
int usTimeArr[3][7] = {{382, 340, 303, 286, 255, 227, 214},{202, 180, 160, 151, 135, 120, 113},{56, 50, 45, 42, 37, 33, 31}
};void delay_100us() {unsigned char i;_nop_();i = 26;while (--i);
}void delay_me(int time) {while(--time) {delay_100us();}
}void start_beep(int time, float delay) {while(--delay){BEEP = 0;delay_me(time/2);BEEP = 1;delay_me(time/2); }
}void main() {int note[14] = {1, 1, 5, 5, 6, 6, 5, 4, 4, 3, 3, 2, 2, 1}; // 小星星简谱int time[14] = {1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2}; // 每个音的时while(1) {int i = 0;while(i < 14) { start_beep(usTimeArr[2][note[i] - 1], time[i] * 121);i++;}start_beep(5000, 5); // 停一段时间}
}
源码+实验程序
学习视频来源:B站-普中官方视频