STC89C52单片机学习——第25节: [11-1]蜂鸣器

写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难,但我还是想去做!

本文写于:2025.03.18

51单片机学习——第25节: [11-1]蜂鸣器

  • 前言
  • 开发板说明
  • 引用
  • 解答和科普
  • 一、蜂鸣器原理和驱动
  • 二、乐理部分
  • 三、按键提示音设置
  • 问题
  • 总结
  • 鸡汤时刻

前言

   本次笔记是用来记录我的学习过程,同时把我需要的困难和思考记下来,有助于我的学习,同时也作为一种习惯,可以督促我学习,是一个激励自己的过程,让我们开始51单片机的学习之路。
   欢迎大家给我提意见,能给我的嵌入式之旅提供方向和路线,现在作为小白,我就先学习51单片机了,就跟着B站上的江协科技开始学习了.
   在这里会记录下江协科技51单片机开发板的配套视频教程所作的实验和学习笔记内容,因为我之前有一个开发板,我大概率会用我的板子模仿着来做.让我们一起加油!
   另外为了增强我的学习效果:每次笔记把我不知道或者问题在后面提出来,再下一篇开头作为解答!

开发板说明

   本人采用的是慧净的开发板,因为这个板子是我N年前就买的板子,索性就拿来用了。不再另外购买视频中的普中开发板了。
   原理图如下
在这里插入图片描述
视频中的都用这个开发板来实现,如果有资源就利用起来。
仔细看了看:开发板的晶振为:11.0592Mhz;12Mhz晶振是用来给CH340G芯片外置晶振;

下图是实物图
在这里插入图片描述

引用

51单片机入门教程-2020版 程序全程纯手打 从零开始入门
还参考了下图中的书籍:
手把手教你学51单片机(C语言版)
在这里插入图片描述
STC89C52手册
在这里插入图片描述

解答和科普

一、蜂鸣器原理和驱动

在这里插入图片描述
可以看到我们使用的是无源蜂鸣器,我们控制震荡脉冲,通过调整提供振荡脉冲的频率,可以发出不同频率的声音。
在这里插入图片描述
我们要编这个音乐,首先需要去找到它的谱子,我们有了这个谱子呢,至少得知道这个谱子它在我们的钢铁键盘上,它是怎么样去按的,然后知道这个谱子对应钢琴键,它怎么按之后按多长时间,然后呢我们利用单片机去把每个键它背后的音给模拟出来。根据这个频率对照表,把每个按键它的音模拟出来,然后我们编写这个曲目,由谱曲到我们的蜂鸣器播放。这整个过程才能实现。那么我们单片机的任务呢就是模拟这个钢琴键盘,我们按下它按多长时间。
然后把它的频率发出来就好了,这就是我们代码的任务。那么还有一个任务呢就是,我们需要根据这个谱子,看到这个谱子之后,知道它是怎么对应的这个钢琴键盘上的。然后我们怎么去按。
在这里插入图片描述
我们首先来看一下这个蜂鸣器的介绍,第一句话是蜂鸣器是一种将电信号转化为声音信号的器件,那我知道这个分频器它通电会响,那么怎么响呢?
我们来看一下他想的用途呢是用来产生我们设备的按键音,报警音等提示信号。它可以分为有源蜂鸣器和无源蜂鸣器,有源蜂鸣器频率是固定的,不能随之改变。内部自带震荡源,那么它使用起来就是很简单,将正负极接上直流电压即可持续发生,频率固定。我们给他的是直流电,但直流电本身不能发声,它内部有电路产生的震荡,所以它发声,那因此呢它的频率也是固定的。因为它内部的震荡源它已经固定好了,它的频率就只有只有这么大。
三极管驱动:

在这里插入图片描述
在这里插入图片描述
低电平导通,高电平断开。之前已经分析过三极管(PNP)的驱动原理。
在这里如果P1^3输入低电平那么基极和发射极直接有电压差,就会控制发射极和集电极导通,因此就是蜂鸣器接上了电源,此时发声。
芯片驱动
在这里插入图片描述
控制P15的1或0,就能控制蜂鸣器是是否有电流
无源蜂鸣器不能一直通电,很容易烧毁,IO口上电默认为高电平,BZ默认为0;始终通电流。
在这里插入图片描述
在这里插入图片描述
给1取反为0,有驱动,给0取反为1,好像不行;
在这里插入图片描述
我们蜂鸣器原理和驱动部分就已经讲完了,接下来我们就呃给大家讲一下这个这个乐理部分。

二、乐理部分

在这里插入图片描述

首先我们来认识一下这个钢琴键盘,这钢琴键盘呢上面就是钢琴键盘。这个呢是五线谱,然后下面是简谱。然后呢钢键盘嗯它可以分组,小写字母也是一组,它命名方式一组有七个白键,五个黑键组成的。然后这个呢就叫做小字组。然后左边这个叫做大字组,如果左边还有人就大字一组,右边这个叫做小字二组,小字二组右边还有就是小字三组,在这里这里首先分为几组,这几组呢每一个都是单独的,就是常见的do re mi fa so la xi。然后呢每一个组的相同的音,比如说这个C1和C2相差8度.相邻的按键是半音。
然后呢我们来讲一下如何根据这个简谱去对应的这个键盘啊,就是再升高8度的话,那么这个一上面要加个点,然后呢如果降低8度呢,就是在下面在这个音的,在这个数字下面加点,降低两个8度,下面加两个点。那么升高两个8度呢,就上面加两个点。我们就可以把所有音高给表示出来。所有的白键音标就可以表示出来,然后如果我们想表示黑键的音高,我们就需要用到升音符号和降音符号这两个符号进行。
在这里插入图片描述
-表示时长延长, #表示升半个音,就是黑键,b为降音
有了这个数字上面加点,下面加点,然后再配合升降符号的话,就可以表示所有钢琴上的按键了。我们就可以把钢琴键盘所有的音高的表示出来了,然后呢有了音高之后,我们按钢琴这个键盘的时候,主要有音高和按的时长,主要有这两个因素。我们这写程序也按照这两个因素来。一个是音高,一个是时间。有了这两个部分,我们就能够演奏出这个音乐了。

在这里插入图片描述
在这里插入图片描述
4分音符 500us ,2分1s,8分音符250ms 16音符为125ms,5表示4分音符,5-表示2分音符;下面加一个横线是8分音符,加两条线是16分音符。他们时间都是二倍的关系,利用它们组合起来,我们就可以组合各种时长。在我们下面呢一般来说都是以四分音符为基准。
4/4是拍号,四分音符为一拍,每小节4拍;
1的上面加点表示音高,右边有点表示附点,延长原来的1/2,500+250,250,500,500;
——为连音,时长加起来;

我们直接写个数字,它就是我们的四分音符,如果想表示二分音符的话,那么这个数字后面再加一个横线,它就可以表示二分音符。如果是全音符的话,在后面加两条横线,我加三条横线,一共四倍的关系,这就是全音符。
然后如果想表示分开,比如说四分音符分成八分音符,那么就在下面加线,比这个六我下面加一个线,它就是四分音符时值的一半。如果下面加两条线呢,就是八分音符。在右边加线就增长,下面加线就缩短,就可以表示时长然后表示完时长之后,右边这个4/4就是我们的拍号从下往上读,它叫做以四分音符为一拍,每小节有四拍。
我们需要以一个音符时长为基准,就以四分音符为基准,就是写一个数字,画一条竖线就代表小节,一小节有4拍,这就是以四分音符为一拍,每小节四拍的意思。
==右边加点就是附点这个音符加上原来的一半,比如说这个四分音符是500ms,然后加个点它加原来500ms的一半,就是加上250ms,就是750ms。
在这里插入图片描述
弧度是延音线,按下去不放的, 为了识谱方便.
在这里插入图片描述
我们就是根据这个频率值,根据频率值去控制我们的定时器,产生一个相应频率的计时,有了频率就有了计时频率,计时的周期我们有了,然后去控制我们的中断,再去控制IO口的翻转,就可以控制我们的频率.
在这里插入图片描述
频率关系是:首先需要一个基准的频率,就是低音6,小子组的a为基准频率440,下一个a是880,左边的a是220,中间是以等比数列,也叫十二平分律。440*2^(1/12)是下一个频率。

利用定时器中断产生频率,依靠我们TH0、TL0,产生周期,周期等于1/f,然后是IO口,一个周期IO翻转两次,所以反正一次用的时间是半个周期,
在这里插入图片描述
12MHZ对应的重装载值

在这里插入图片描述
11.05926HZ对应的重装载值
在这里插入图片描述
其中的转化过程,因为时钟频率不同,机器周期不同,重装载值也不同。

三、按键提示音设置

3.1 main.c

#include <REGX52.H>
#include <INTRINS.H>
#include "Delay.h"
#include "Key.h"
#include "Timer0.h"
#include "LCD1602.h" 
#include "Init.h"
#include "Nixie.h"sbit  Buzzer = P2^3;
unsigned char KeyNum;
unsigned int i;
void main()
{DianZhengGuan();			//关闭点阵while(1){KeyNum=Key();if(KeyNum){for(i=0;i<500;i++)	//2ms一个周期,500HZ 的频率响500ms{						//f=1/T=1/0.002=500hzBuzzer=!Buzzer;Delay(1);}Nixie(1,KeyNum);}}
}

3.2 Key.c

#include <REGX52.H>
#include "Delay.h"/*** @brief    独立按键获取键码值* @param  	无* @retval 	按下的键码值,范围1-8,没有独立按键按下是为0*/
unsigned char Key()
{unsigned char KeyNumber=0;if(P3_0==0){Delay(20);while(P3_0==0);Delay(20);KeyNumber=1;}if(P3_1==0){Delay(20);while(P3_1==0);Delay(20);KeyNumber=2;}if(P3_2==0){Delay(20);while(P3_2==0);Delay(20);KeyNumber=3;}if(P3_3==0){Delay(20);while(P3_3==0);Delay(20);KeyNumber=4;}if(P3_4==0){Delay(20);while(P3_4==0);Delay(20);KeyNumber=5;}if(P3_5==0){Delay(20);while(P3_5==0);Delay(20);KeyNumber=6;}if(P3_6==0){Delay(20);while(P3_6==0);Delay(20);KeyNumber=7;}if(P3_7==0){Delay(20);while(P3_7==0);Delay(20);KeyNumber=8;}return KeyNumber;}
#ifndef		__KEY_H
#define 	__KEY_Hunsigned char Key();#endif

3、Nixie.c

#include <REGX52.H>
#include "Delay.h"sbit  	wei= P2^1;
sbit	duan=P2^0;
unsigned char NixieDuanTable[]= {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x00};
unsigned char NixieWeiTable[]={0xFF,0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};void Nixie(unsigned char WeiNum, DuanNum)	//动态显示 
{duan=1;P0=NixieDuanTable[DuanNum];duan=0;wei=1;P0=NixieWeiTable[WeiNum];wei=0;Delay(1);                                                                                                                                                                                                                                      
}
#ifndef		__NIXIE_H
#define 	 __NIXIE_Hvoid Nixie(unsigned char WeiNum, DuanNum);#endif

实验现象:

按键提示音(蜂鸣器)

对蜂鸣器设置私有化延迟函数
1、main.c

#include <REGX52.H>
#include <INTRINS.H>
#include "Delay.h"
#include "Key.h"
#include "Timer0.h"
#include "LCD1602.h" 
#include "Init.h"
#include "Nixie.h"
#include "Buzzer.h"unsigned char KeyNum;void main()
{DianZhengGuan();			//关闭点阵while(1){KeyNum=Key();if(KeyNum){Buzzer_Time(100);			//1Khz响100msNixie(1,KeyNum);}}
}

2.Buzzer.c

#include <REGX52.H>
#include <INTRINS.H>
#include "Delay.h"sbit  Buzzer = P2^3;		//蜂鸣器端口/*** @brief    蜂鸣器私有延迟函数  //@11.0592MHz  500us* @param  	无* @retval 	无*/
void Buzzer_Delay500us()		//@11.0592MHz
{unsigned char i;_nop_();i = 227;while (--i);
}/*** @brief      蜂鸣器鸣响 * @param  	xms :发声的时间* @retval 	无*/
void Buzzer_Time(unsigned int xms)
{unsigned int i;for(i=0;i<xms*2;i++)	//1ms一个周期,1000HZ 的频率响xms{Buzzer=!Buzzer;Buzzer_Delay500us();}
}
#ifndef		__BUZZER_H
#define 	 __BUZZER_Hvoid Buzzer_Time(unsigned int ms);#endif

问题

1、就是还是对乐理部分有点乱。

总结

本节课主要学了蜂鸣器的原理和驱动,学习了音乐相关的乐理知识。让我们看着简谱去弹钢琴,主要是音高和音长,这两点,其中有#升音、头上加点,b降音底部加点;下面加——,一半音,右边——延长,还有附点延长一半,还有弧度延音键为了看拍子数,这样基本解决了音高和音长两个关键。
接下来为了让单片机发出对应的音高,单片机不能控制频率,通过频率得到计数频率,所以通过控制周期,得到计数频率也就得到了技术周期,半个周期触发中断,进行一次IO变换,一个周期IO变换两次==(高电平半个周期,低电平半个周期)==,那么我们通过频率最后到达计算重装值。其中还进行了11.0592Mhz的转换。就剩下如何实现了。

鸡汤时刻

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/35966.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux上的`i2c-tools`工具集的详细介绍;并利用它操作IMX6ULL的I2C控制器进而控制芯片AP3216C读取光照值和距离值

IC-Tools 工具集介绍 i2c-tools 是 Linux 下用于 IC 设备调试 的用户空间工具集(你也可以把它看成是一个库&#xff0c;类似于之前自己用过的触摸屏库tslib库、FreeType矢量字符库)&#xff0c;它提供了一系列命令行工具&#xff0c;可以扫描、读取、写入 IC 设备&#xff0c;…

《CircleCI:CircleCI:解锁软件开发持续集成(CI)和持续部署(CD)高效密码》:此文为AI自动生成

《CircleCI&#xff1a;CircleCI&#xff1a;解锁软件开发持续集成&#xff08;CI&#xff09;和持续部署&#xff08;CD&#xff09;高效密码》&#xff1a;此文为AI自动生成 一、CircleCI 初印象 在当今软件开发的快节奏赛道上&#xff0c;持续集成&#xff08;CI&#xff0…

LinuX---Shell脚本创建和执行

概述&#xff1a; 它是一个命令行解释器&#xff0c;接收应用程序/用户命令&#xff0c;然后调用操作系统内核。 Shell还是一个功能强大的编程语言&#xff0c;易编写、易调试、灵活性强。 Linux提供的Shell解析器有 atguiguubuntu:~$ cat /etc/shells # /etc/shells: valid …

再学:Solidity数据类型

目录 1.uint&#xff1a;无符号整型 2.引用类型 3.数组 4.注意gas的消耗 ​编辑 5.映射 1.uint&#xff1a;无符号整型 注意能容纳的最大值和最小值 2.引用类型 值类型赋值 相当于 拷贝 若拷贝开销过大&#xff0c;可以考虑引用类型。 memory&#xff1a;只存在于函数内部…

Docker Desktop配置国内镜像源教程

在使用 Docker 时&#xff0c;由于默认镜像源在国外&#xff0c;经常会遇到下载速度慢、连接超时等问题。本文将详细介绍如何在 Windows 系统中为 Docker 配置国内镜像源&#xff0c;以提升镜像拉取速度。 常用国内镜像源 https://docker.1ms.run清华镜像源 https://docker.m…

C#中SerialPort 的使用

最近在学习C#的SerialPort &#xff0c;关于SerialPort 的使用&#xff0c;做如下总结&#xff1a; 1.可以通过函数System.IO.Ports.SerialPort.GetPortNames() 将获得系统所有的串口名称。C#代码如下&#xff1a; string[] sPorts SerialPort.GetPortNames(); foreach(stri…

深度学习 Deep Learning 第2章 线性代数

深度学习 第2章 线性代数 线性代数是深度学习的语言。 张量操作是神经网络计算的基石&#xff0c;矩阵乘法是前向传播的核心&#xff0c;范数约束模型复杂度&#xff0c;而生成空间理论揭示模型表达能力的本质。 本章介绍线性代数的基本内容&#xff0c;为进一步学习深度学习做…

EDID读取学习

简介 Video BIOS可以被认为是一个具有独立硬件抽象层的操作系统。它不会阻止或监视操作系统、应用程序或设备驱动程序对硬件的直接访问。虽然不推荐,但一些DOS应用程序确实可以改变基本的硬件设置,而根本不需要通过视频BIOS。大多数现代应用程序和操作系统都避免直接使用硬件…

基于SpringBoot的在线拍卖系统

摘 要 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统&#xff0c;主要的模块包括管理员&#xff1b;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…

Android audio(8)-native音频服务的启动与协作(audiopolicyservice和audioflinger)

音频策略的构建 1、概述 2、AudiopolicyService 2.1 任务 2.2 启动流程 2.2.1 加载audio_policy.conf&#xff08;xml&#xff09;配置文件 2.2.2 初始化各种音频流对应的音量调节点 2.2.3 加载audio policy硬件抽象库 2.2.4设置输出设备 ps:audiopatch流程简介 2.2.5打开输出设…

Springdoc 全部注解一文解释清楚

文章目录 **1. 核心注解****Tag-Class类上** **2. 方法级别注解****Operation-方法描述****ApiResponse 和 ApiResponses-方法的返回结果** **3. 参数相关注解****Parameter-方法参数****Parameters方法参数&#xff08;单个&#xff09;** **4. 实体模型相关注解****Schema-描…

Git的基本指令

一、回滚 1.git init 在项目文件夹中打开bash生成一个.git的子目录&#xff0c;产生一个仓库 2.git status 查看当前目录下的所有文件的状态 3.git add . 将该目录下的所有文件提交到暂存区 4.git add 文件名 将该目录下的指定文件提交到暂存区 5.git commit -m 备注信…

通过qemu仿真树莓派系统调试IoT固件和程序

通过qemu仿真树莓派系统调试IoT固件和程序 本文将介绍如何使用 QEMU 模拟器在 x86 架构的主机上运行 Raspberry Pi OS&#xff08;树莓派操作系统&#xff09;。我们将从下载镜像、提取内核和设备树文件&#xff0c;到启动模拟环境&#xff0c;并进行一些常见的操作&#xff0…

DeepSeek大模型在政务服务领域的应用

DeepSeek大模型作为国产人工智能技术的代表&#xff0c;近年来在政务服务领域的应用呈现多点开花的态势。通过多地实践&#xff0c;该技术不仅显著提升了政务服务的效率与智能化水平&#xff0c;还推动了政府治理模式的创新。以下从技术应用场景、典型案例及发展趋势三个维度进…

【HarmonyOS Next之旅】DevEco Studio使用指南(三)

目录 1 -> 一体化工程迁移 1.1 -> 自动迁移 1.2 -> 手动迁移 1.2.1 -> API 10及以上历史工程迁移 1.2.2 -> API 9历史工程迁移 1 -> 一体化工程迁移 DevEco Studio从 NEXT Developer Beta1版本开始&#xff0c;提供开箱即用的开发体验&#xff0c;将SD…

FPGA中级项目4——DDS实现

FPGA中级项目4——DDS实现 DDS简介 DDS&#xff08;直接数字频率合成器&#xff0c;Direct Digital Frequency Synthesis&#xff09;是一种基于数字信号处理技术的频率合成方法&#xff0c;广泛应用于通信、雷达、仪器仪表等领域。在 FPGA中实现 DDS 具有灵活性高、集成度强、…

SAP的WPS导出找不到路径怎么办;上载报错怎么办

一.打开注册编辑器 二.输入以下地址 计算机\HKEY_CLASSES_ROOT\ExcelWorksheet\Protocol\StdFileEditing\Server 去除掉EXE后面的命令即可 二&#xff1a;WPS上载文件没反应怎么办 如何切换整合模式或多组件模式-WPS学堂 根据官方操作把整合模式改成多组件模式

STM32 DAC详解:从原理到实战输出正弦波

目录 一、DAC基础原理1.1 DAC的作用与特性1.2 DAC功能框图解析 二、DAC配置步骤2.1 硬件配置2.2 初始化结构体详解 三、DAC数据输出与波形生成3.1 数据格式与电压计算3.2 正弦波生成实战3.2.1 生成正弦波数组3.2.2 配置DMA传输3.2.3 定时器触发配置 四、常见问题与优化建议4.1 …

MVC_Publish-Subscriber 模式中的事件处理程序

MVC_Publish-Subscriber 模式中的事件处理程序 MVC 中的事件处理&#xff1a;发布者-订阅者模式 程序启动时&#xff0c;controlRecipes将被传入addHandlerRender; addHandlerRender会侦听事件&#xff08;addEventListener&#xff09;,并使用controlRecipes作为回调&#xf…

网络华为HCIA+HCIP 以太网链路聚合与交换机堆叠、集群

网络可靠性 网络的可靠性指当设备或者链路出现单点或者多点故障时保证网络服务不间断的能力。网络的可靠性可以从单板、设备、链路多个层面实现。 单板可靠性 以S12700E-8为例&#xff0c;设备提供8个线路板槽位、4个交换网板槽位、2个主控板槽位、6个电源模块槽位、4个风扇…