单片机第一季:零基础8——蜂鸣器

news2024/11/18 9:49:30

蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于计算机、打印机、复印机、报警器、电子玩具、汽车电子设备、电话机、定时器等电子产品中作发声器件。

蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型。

想要压电式蜂鸣器发声,需提供一定频率的脉冲信号;想要电磁式蜂鸣器发声,只需提供电源即可。

我们开发板上使用的蜂鸣器是无源蜂鸣器,属于压电式蜂鸣器类型。这里说的有源和无源,并不是指电源的意思,而是指蜂鸣器内部是否含有振荡电路,有源蜂鸣器内部自带振荡电路,只需提供电源即可发声,而无源蜂鸣器则需提供一定频率的脉冲信号才能发声,频率大小通常在1.5-5KHz 之间。 

对于无源蜂鸣器,如果改变频率就可以调节蜂鸣器音调,产生各种不同音色、音调的声音。如果改变输出电平的高低电平占空比,则可以改变蜂鸣器的声音大小。

对于有源蜂鸣器,通常内部已经固定了频率,对于调节频率或占空比可能改变不了蜂鸣器的音调和音量,当然也有的有源蜂鸣器可以实现和无源蜂鸣器一样的效果。 

在前面章节中我们已经对51 单片机的GPIO 做了简单介绍,并且还使用了其中IO 口直接控制开发板上的LED。对于本章要实现蜂鸣器的控制,我们能否直接使用单片机的IO 口驱动呢?答案是否定的,因为51 单片机IO 口的驱动能力较弱(即使外接上拉电阻),而蜂鸣器驱动需要约30mA,所以非常困难,即使可以驱动,那对于整个芯片的其它IO 剩下驱动能力就更加弱甚至无法工作。所以我们不会直接使用IO 口驱动蜂鸣器,而是通过三极管把电流放大后再驱动蜂鸣器,这样51 单片机的IO 口只需要提供不到1mA 的电流就可控制蜂鸣器。所以我们也经常说到51 单片机是用来做控制的,而不是驱动。 

从图中可以看出,蜂鸣器模块独立,J7 端子可接任意IO 控制,因此可直接连接到51 单片机的管脚上。图中使用三极管进行电流放大,从而驱动蜂鸣器,当管脚输出高电平,三极管截止,蜂鸣器不得电;当管脚输出低电平,三极管导通,蜂鸣器得电。

开发板上使用的是无源蜂鸣器,它需要一定频率的脉冲(高低电平)才会发声,因此需要让单片机管脚以一定频率不断输出高低电平信号才能控制蜂鸣器发出声音。 

 两种控制蜂鸣器的程序代码:

第一种:

/********************************************************************
******************
实验名称:蜂鸣器实验
接线说明:
实验现象:下载程序后蜂鸣器发出声音,一段时间后关闭
注意事项:
*********************************************************************
******************/
#include "reg52.h"
typedef unsigned int u16; //对系统默认数据类型进行重定义
typedef unsigned char u8;
sbit BEEP=P0^0; //将P0.0 管脚定义为BEEP
/********************************************************************
***********
* 函数名: delay_10us
* 函数功能: 延时函数,ten_us=1 时,大约延时10us
* 输入: ten_us
* 输出: 无
*********************************************************************
**********/
void delay_10us(u16 ten_us)
{
	while(ten_us--);
}

void delay1ms(void)   //误差 0us
{
    unsigned char a,b;
    for(b=199;b>0;b--)
        for(a=1;a>0;a--);
}

/********************************************************************
***********
* 函数名: main
* 函数功能: 主函数
* 输入: 无
* 输出: 无
*********************************************************************
**********/
void main()
{
	u16 i=2000;
	while(1)
	{
		while(i--)//循环2000 次
		{
			BEEP=!BEEP;//产生一定频率的脉冲信号
			delay1ms();
		}
		i=0;//清零
		BEEP=0;//关闭蜂鸣器
	}
}

第二种:使用定时中断的方法

#include <reg51.h>

sbit buzzer =P0^0;

void buzzer_isr() interrupt 1 using 1	 //定时器T0中断执行程序
{
	TL0 = 0x17;                          //计数器重新赋值
	TH0 = 0xfc;
	buzzer = !buzzer;

}

void main()
{
	TMOD = 0x01;	 //工作模式1,16位定时/计数器
	TL0 = 0x17;		 //定时时间1ms
	TH0 = 0xfc;
	TR0 = 1;
	ET0 = 1;
	EA = 1;

	while(1);

}

可以让蜂鸣器唱歌的程序:

 

/************************************************************************  
[文件名]  C51音乐程序(八月桂花)  
[功能]    通过单片机演奏音乐  
  
/**********************************************************************/   
#include <REG51.H>    
//#include <INTRINS.H>    
//本例采用89C52, 晶振为11.0592MHZ    
//关于如何编制音乐代码, 其实十分简单,各位可以看以下代码.    
//频率常数即音乐术语中的音调,而节拍常数即音乐术语中的多少拍;    
//所以拿出谱子, 试探编吧!    

sbit Beep =  P0^0 ; 			// 要根据实际的接线来修改
   
unsigned char n = 0;  //n为节拍常数变量    
unsigned char code music_tab[] = 
{   
	0x18, 0x30, 0x1C , 0x10, //格式为: 频率常数, 节拍常数, 频率常数, 节拍常数,    
	0x20, 0x40, 0x1C , 0x10,   
	0x18, 0x10, 0x20 , 0x10,   
	0x1C, 0x10, 0x18 , 0x40,   
	0x1C, 0x20, 0x20 , 0x20,   
	0x1C, 0x20, 0x18 , 0x20,   
	0x20, 0x80, 0xFF , 0x20,   
	0x30, 0x1C, 0x10 , 0x18,   
	0x20, 0x15, 0x20 , 0x1C,   
	0x20, 0x20, 0x20 , 0x26,   
	0x40, 0x20, 0x20 , 0x2B,   
	0x20, 0x26, 0x20 , 0x20,   
	0x20, 0x30, 0x80 , 0xFF,   
	0x20, 0x20, 0x1C , 0x10,   
	0x18, 0x10, 0x20 , 0x20,   
	0x26, 0x20, 0x2B , 0x20,   
	0x30, 0x20, 0x2B , 0x40,   
	0x20, 0x20, 0x1C , 0x10,   
	0x18, 0x10, 0x20 , 0x20,   
	0x26, 0x20, 0x2B , 0x20,   
	0x30, 0x20, 0x2B , 0x40,   
	0x20, 0x30, 0x1C , 0x10,   
	0x18, 0x20, 0x15 , 0x20,   
	0x1C, 0x20, 0x20 , 0x20,   
	0x26, 0x40, 0x20 , 0x20,   
	0x2B, 0x20, 0x26 , 0x20,   
	0x20, 0x20, 0x30 , 0x80,   
	0x20, 0x30, 0x1C , 0x10,   
	0x20, 0x10, 0x1C , 0x10,   
	0x20, 0x20, 0x26 , 0x20,   
	0x2B, 0x20, 0x30 , 0x20,   
	0x2B, 0x40, 0x20 , 0x15,   
	0x1F, 0x05, 0x20 , 0x10,   
	0x1C, 0x10, 0x20 , 0x20,   
	0x26, 0x20, 0x2B , 0x20,   
	0x30, 0x20, 0x2B , 0x40,   
	0x20, 0x30, 0x1C , 0x10,   
	0x18, 0x20, 0x15 , 0x20,   
	0x1C, 0x20, 0x20 , 0x20,   
	0x26, 0x40, 0x20 , 0x20,   
	0x2B, 0x20, 0x26 , 0x20,   
	0x20, 0x20, 0x30 , 0x30,   
	0x20, 0x30, 0x1C , 0x10,   
	0x18, 0x40, 0x1C , 0x20,   
	0x20, 0x20, 0x26 , 0x40,   
	0x13, 0x60, 0x18 , 0x20,   
	0x15, 0x40, 0x13 , 0x40,   
	0x18, 0x80, 0x00   
};   

 // T0定时控制的是音乐的节拍(某一个音节持续的时间)而不管音调(频率)
 // 音调是直接使用delay做出来的。
void int0()  interrupt 1   //采用中断0 控制节拍    
{  
	TH0 = 0xd8;   
   	TL0 = 0xef;   
   	n--;   
}   
   
void delay (unsigned char m)   //控制频率延时    
{   
 	unsigned i = 3 * m;   
 	while (--i);   
}   
   
void delayms(unsigned char a)  //豪秒延时子程序    
{   
  	while (--a);                  //采用while(--a) 不要采用while(a--); 各位可编译一下看看汇编结果就知道了!    
}   
   
void main()   
{ 
	unsigned char p, m;   // m为频率常数变量    
  	unsigned char i = 0;   

  	TMOD &= 0x0f;   
  	TMOD |= 0x01;  		// timer0 工作在模式1,16位定时器下 
  	TH0 = 0xd8;
	TL0 = 0xef;   		// 这个TH和TL的值合起来定了1个10ms左右的一个时间
  	IE = 0x82;   
play:   
   	while (1)   
    {   
a: 		p = music_tab[i];   
       	if (p == 0x00)   		// 一遍播放完了,延时1s后自动开始下一遍    
		{ 
			i=0, delayms(1000); 
			goto play;
		}     //如果碰到结束符,延时1秒,回到开始再来一遍    
       	else if (p == 0xff)  
		{ 
			i = i + 1;
			delayms(100), TR0 = 0; 
			goto a;
		}  //若碰到休止符,延时100ms,继续取下一音符    
        else         
		{
			m = music_tab[i++], n = music_tab[i++];
		}  // m取频率常数 和 n取节拍常数    
		TR0 = 1;                              //开定时器1    
		while (n != 0)
		{ 
			Beep = ~Beep;
			delay(m);        	//等待节拍完成, 通过P1口输出音频(可多声道哦!)    
       	}
		TR0 = 0;                         	//关定时器1    
    }   
}
  

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用Gataway设置全局过滤器

说明&#xff1a;Gateway网关是所有微服务统一的入口&#xff0c;通过网关技术&#xff0c;可以实现请求转发、权限控制和限流。全局过滤器是Gateway请求转发、权限控制的一个体现。比如对所有请求进行过滤&#xff0c;判断请求是否携带有效的token&#xff0c;对请求放行或者拦…

Java 装箱拆箱原理 包装类型缓存池

JAVA中的基本数据类型 byteshortintlongfloatdoublebooleanchar 为了让上述基本数据类型可以转为对象&#xff0c;Java在1.5推出了一系列包装类&#xff0c;基本类和包装类互相转换的过程&#xff0c;称为装箱和拆箱 缓存池 缓存池也叫常量池。它是事先存储一些常量数据用以…

reverse

b,a,0x7d65都能轻易的转成字符串&#xff0c;就是这个负数需要看汇编&#xff0c;在汇编层面是加了两个数实现的减法效果。 a[galf,saE{,er_y,3r0v,}e] for each in a:print(each[::-1],end) # flag{Easy_rev0r3e}

华为OD机试真题 Java 实现【路灯照明问题】【2022Q4 100分】,感谢fly晨发现这个问题,并提供更优质的算法

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路特别鸣谢&#xff1a;感谢fly晨发现这个问题&#xff0c;并提供更优质的算法。解题思路如下&#xff1a; 五、Java算法源码六、效果展示1、输入2、输出3、思路 专栏导读 本专栏收录于《华为OD机试&#xff08;J…

【USRP X310】如何查找USRP X310的 LabVIEW 案例 Demo

环境 Windows 10LabVIEWUSRP 支持的硬件 USRP-2900USRP-2901USRP-2920USRP-2921USRP-2922USRP-2930USRP-2932USRP-2940 40 MHzUSRP-2940 120 MHzUSRP-2942 40 MHzUSRP-2942 120 MHzUSRP-2943 40 MHzUSRP-2943 120 MHzUSRP-2944USRP-2945USRP-2950 40 MHzUSRP-2950 120 MHzUS…

轻奢分销商城pc/h5小程序开源版开发

轻奢分销商城pc/h5小程序开源版开发 商城系统&#xff1b;包含小程序商城、H5商城、公众号商城、PC商城、App&#xff0c;支持秒杀、优惠券、积分、分销、会员等级。 功能列表&#xff1a; 用户注册和登录&#xff1a;用户可以通过手机号码或第三方登录方式注册和登录账号。…

RPM包详解以及如何制作RPM包

RPM包简介 RPM 全名 RedHat Package Managerment&#xff0c;一开始只是Red Hat Linux的软件包格式&#xff0c;它最初的名字为Red Hat软件包管理程序。从那以后&#xff0c;RPM逐渐称为许多其他Linux发行版所接受的一种软件包格式。Linux标准化规范将RPM作为其官方软件包格式…

gdb调试产生code文件以及遇到的“file format not recognized”问题解决

一、调试 core 文件的配置 1.1 开启core文件 —— ulimit 有时候&#xff0c;服务器程序运行一段时间后会突然崩溃&#xff0c;这并不是我们希望看到的&#xff0c;需要 解决这个问题。只要程序在崩溃的时候有 core 文件产生&#xff0c;就可以使用这个 core 文件 来定位崩溃…

数据结构(王道)——线性表的存储结构之双链表

双链表和单链表的对比 一、从无到有创建一个双链表及其基础操作 带头结点 的双链表 初始化 双链表的后插操作&#xff1a; 从后插可以拓展到按位序插入&#xff0c;和前插操作。 因为双链表的特性&#xff0c;如果按位序插入或者前插操作&#xff0c;只需要找到插入的位置的前…

传统企业的数据管理:如何高效管理分散的数据?

在数字时代&#xff0c;数据管理已经成为一个重要的议题。大多数企业已经意识到数据是他们业务运营的重要组成部分。然而&#xff0c;许多传统企业还在使用过时的数据管理模式&#xff0c;这些模式并不具备高效管理分散数据的能力。随着企业的膨胀和数据规模的逐渐增加&#xf…

AI工程师:未来时代的主流工程师

自从以ChatGPT为主的人工智能&#xff08;AI&#xff09;大模型层出不穷&#xff0c;越来越多人开始意识到AI的潜力&#xff0c;甚至预测“所有行业都将通过AI来进行重塑”&#xff0c;正是基于该原因&#xff0c;各国各企业如火如荼建设AI事业&#xff0c;作为把AI造出来的AI工…

配合LaTex使用的“工具”

先介绍两个工具&#xff0c;比如公式的书写等&#xff0c;会大大提高书写论文的速度。 第一个&#xff1a;Mathpix Snip(生成公式)。官网&#xff1a;https://mathpix.com 【先去官网注册一个账号&#xff08;注册时遇到的问题见文章Mathpix上半部分&#xff09;然后去安装该软…

Python 列表 pop()函数使用详解

「作者主页」&#xff1a;士别三日wyx 「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;小白零基础《Python入门到精通》 pop函数使用详解 1、按照索引删除元素1.1、正数索引1.2、负数索引1.3、不指定索引…

docker k8s

Docker docker到底与一般的虚拟机有什么不同呢&#xff1f; 我们知道一般的linux系统即GNU/Linux系统包括两个部分&#xff0c;linux系统内核GNU提供的大量自由软件&#xff0c;而centos就是众多GNU/Linux系统中的一个。 虚拟机会在宿主机上虚拟出一个完整的操作系统与宿主机完…

vue+openlayers 点击地图查询geoserver发布的WMS/WMTS图层的信息[矢量(点、线、面)+栅格]

一、基本介绍 网络地图服务 (WMS) 、网络地图切片服务 (WMTS) &#xff0c;根据用户的请求返回相应的地图&#xff08;包括PNG&#xff0c;GIF&#xff0c;JPEG等栅格形式或者是SVG和WEB CGM等矢量形式&#xff09;。 下面是常见的geoserver发布的图层格式&#xff0c;有矢量…

ODX(ISO22901)进阶——Intorduction to ODX

文章目录 前言一、Vehicle Diagnostic是什么?二、Diagnostic Data in ODX(诊断数据在ODX数据库)三、ODX企标概述(ODX Authoring Guidelines)总结前言 今天是2023年7月15日,距离2024年只剩下半年时间。伴随着各地疫情政策逐渐发开,三年的疫情终于迎来了不一样的变化。期…

AI绘画Stable Diffusion实战操作: 62个咒语调教-时尚杂志封面

今天来给大家分享&#xff0c;如何用sd简单的咒语输出好看的图片的教程&#xff0c;今天做的是时尚杂志专题&#xff0c;话不多说直入主题。 还不会StableDiffusion的基本操作&#xff0c;推荐看看这篇保姆级教程&#xff1a; AI绘画&#xff1a;Stable Diffusion 终极炼丹宝…

C++并发编程(1):基本概念、线程管控

学习视频与书籍 学习视频 c11并发与多线程视频课程 学习书籍 我本来打算去图书馆借《C新经典》的&#xff0c;偶然发现这本书&#xff0c;如获至宝 书挺新的&#xff0c;我看译者序是21年10月这本书挺贵的&#xff0c;后面写着139.80&#xff0c;大家还是去图书馆借吧作为基础…

Linux驱动之字符设备驱动框架与示例模板

目录 一、字符设备驱动简介 二、字符设备驱动开发步骤 1.确定设备号 2.定义 file_operations 结构体 3.实现操作函数 4.注册和注销字符设备 5.编译和加载模块 6.用户空间交互&#xff1a; 三、字符设备驱动示例模板 四、字符设备驱动开发总结 一、字符设备驱动简介 字…

未来Mac下载站怎么打不开了

重要公告&#xff1a; 未来软件园因业务需要现更换域名 原域名&#xff1a;Mac.orsoon.com 更为新域名&#xff1a;未来mac下载-Mac软件-mac软件下载-mac软件大全 程序已全面转移&#xff0c;请访问新域名