51单片机控制蜂鸣器播放音乐详解
创作时间:
作者:
@小白创作中心
51单片机控制蜂鸣器播放音乐详解
引用
CSDN
1.
https://m.blog.csdn.net/iFinder00159/article/details/145095984
本文将介绍如何使用51单片机控制蜂鸣器播放音乐。从蜂鸣器的原理开始讲解,详细介绍了有源蜂鸣器和无源蜂鸣器的区别,以及如何通过单片机控制蜂鸣器发出声音。文章还提供了具体的硬件电路图和代码示例,帮助读者理解和实现蜂鸣器发声的功能。
一、原理介绍
蜂鸣器分为有源蜂鸣器、无源蜂鸣器两种。
- 有源蜂鸣器:施加合适的电压之后就会发出特定频率的声音
- 无源蜂鸣器:需要提供特定频率的声音信号,才能发出声音
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 11
const 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 ms
void 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); // 停一段时间
}
}
热门推荐
如何在VB中有效使用ListBox控件?
车损的认定标准和处理流程是什么?这些因素如何影响理赔效率?
车损险价格计算方法:详解影响因素及计算公式
山地风味:探寻世界各地的特色饺子
铝外壳的清洁方法
中医建议喝米汤一天喝几次
70岁老人全口假牙怎么选?8种假牙类型一网打尽,又便宜又耐用
回迁房可以贷款吗,回迁房能买吗
商品房贷款怎么贷?全流程详解来了
墙面装修使用硅藻泥要注意什么?使用年限多久?
孕妇没有食欲怎么缓解
办公多屏布局软件有哪些
你知道吗?情绪不稳定竟然会「折磨」你的肠胃,甚至愁出胃病!
清爽健康,以蔬食蛋炒饭为主菜(蔬菜与谷物的完美结合)
I5-9400F评测:与I5-8400对比,哪个更强?
人民币国际化:多维度分析与未来展望
成长的伙伴:引导孩子建立积极的同伴关系,共同成长
勿轻易解压陌生压缩包,后门病毒或在其中
解酒最快的方法有哪些?这些科学解酒法值得收藏
哪个在线课程适合深度学习入门?
国足热身赛3-1击败科威特,新归化球员塞尔吉尼奥表现亮眼
秋天口鼻干、咳嗽、皮肤干燥?这几种养阴润燥的中药安排上
恒温恒湿培养箱在无菌培育实验中的应用及操作要点
乌灵胶囊上市25年,治疗失眠效果成色几何(附参考文献)
分析港股的方法有哪些?这些方法如何帮助投资者做出决策?
空调的制热与制冷,究竟哪个更耗电?答案可能出乎你的意料!
空调开27℃制冷和开27℃制热有什么区别?制冷和制热哪个更耗电?
优先债权是什么?一文详解优先债权的概念、分类与保护措施
什么是抵押权以及内容
增肌如何规划蛋白质需求