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); // 停一段时间
}
}
热门推荐
加班不让休息侵犯了什么权利?双休日加班费如何计算?
孕妇可不可以针灸?如何使用中医养生保健孕期健康?
五行与人的性情有着怎样关系?
十大低糖减肥水果排行榜 其实 吃低糖水果也是可以减肥的
部队贷款买房政策解析,助力军人解决购房难题
魏延与邓艾:战术能力的历史对比
催收系统对金融不良资产清收工作的积极促进意义
吉西他滨副作用
跑步:一项有力的策略——有效对抗青少年抑郁的运动
火影人物大全:全面解析忍者世界角色
打鸡血是什么意思怎么来的(形容身体亢奋会说“跟打了鸡血一样”的原因?)
日结工未发放工资,劳动者可以向12333劳动监察投诉
北宋与南宋:谁先谁后?有何不同?
专家解读新版职业教育专业教学标准:提升职教人才培养质量有了专业指南
团队目标管理的6种实用方法(附OKR模板)
汉阳老字号烧鸡公:传承经典,美味飘香
就医前必读:门诊特殊疾病报销政策全解析
做巴西市场的外贸员!必备的NCM编码知识
外贸报价单制作规范与技巧指南
被裁员怎么跟公司谈判?公司解散与外商独资企业责任全解析
时间管理:提升效率,减轻压力
多发性末梢神经炎的治疗方法有哪些
西藏各县城及主要湖泊海拔高度
武功山什么季节去玩最好?武功山适合几月份去?
银行的外汇交易点差和手续费的区别?
商业文案写作必修课:如何精准定位目标受众?
MSTR市值与BTC持有量的溢价显著下降
兼职劳动合同受法律保护吗
ABS塑料有哪些特性?主要应用在哪些方面?
春江水暖鸭先知全诗及翻译 作者是谁