问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

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);	  //  停一段时间
    }
}
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号