JackCin's blog JackCin's blog
首页
  • 页面

    • Html
    • CSS
  • 核心

    • JavaScript基础
    • JavaScript高级
  • 框架

    • Vue
  • jQuery
  • Node
  • Ajax
Linux
  • 操作系统
  • 数据结构与算法
  • 51单片机
  • CC2530
  • 网站
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

JackCin

前端小菜鸡(✪ω✪)
首页
  • 页面

    • Html
    • CSS
  • 核心

    • JavaScript基础
    • JavaScript高级
  • 框架

    • Vue
  • jQuery
  • Node
  • Ajax
Linux
  • 操作系统
  • 数据结构与算法
  • 51单片机
  • CC2530
  • 网站
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 51单片机

    • 51单片机及补充知识
    • LED
    • 独立按键
    • 数码管
    • LCD1602液晶显示器
    • 矩阵按键
    • 定时器
    • 串口
    • LED点阵屏
    • 蜂鸣器
      • 一、硬件部分
        • 1、蜂鸣器介绍
        • 2、驱动电路
      • 二、乐理
        • 1、音符
        • 2、音符与频率对照
        • 3、单片机的12分频
        • 4、计算周期以及重装载值
      • 三、代码
    • AT24C02存储器
    • AD与DA
    • DS18B20温度传感器
    • DS1302时钟
    • LCD1602液晶显示屏
    • 红外遥控
    • 呼吸灯与直流电机调速(PWM)
  • 单片机
  • 51单片机
JackCin
2023-09-13
目录

蜂鸣器

# 蜂鸣器

❗❗❗ 本章内容基本搬运了_花园宝宝小点点的博客-CSDN博客 (opens new window)前辈的博客,博主自己只做了极少的添加和修改

(13条消息) 蜂鸣器介绍_蜂鸣器模块_ONE_Day|的博客-CSDN博客 (opens new window)

# 一、硬件部分

# 1、蜂鸣器介绍

首先我们使用的是51单片机的蜂鸣器来实现的,所以先来介绍一下蜂鸣器吧,如下图所示!

  • 蜂鸣器是一种将电信号转换为声音信号的器件,常用来产生设备的按键音、报警音等提示信号
  • 蜂鸣器按驱动方式可分为有源蜂鸣器和无源蜂鸣器
  • 有源蜂鸣器:内部自带振荡源,将正负极接上直流电压即可持续发声,频率固定
  • 无源蜂鸣器:内部不带振荡源,需要控制器提供振荡脉冲才可发声,调整提供振荡脉冲的频率,可发出不同频率的声音

img

  • 在STM32 (opens new window)上的那个蜂鸣器是有源蜂鸣器,频率固定,就只能发声,而在我们的51单片机上的这个蜂鸣器是属于无源蜂鸣器,所以需要我们来调整频率,从而来实现发出不同频率的声音。

# 2、驱动电路

  • 之前的32是使用三极管进行驱动的,起到放大信号的作用(不清楚的可以去32的笔记看看)。而51单片机使用的是集成电路进行驱动的(ULN2003),接下来我们来简单介绍一下吧!

img

img

# 二、乐理

img

  首先,每8个一组(C~B),也就是哆唻咪发嗦啦西,分为4组,每一组比上一组高8度。黑键与白键相差半个音调,白色与白色相差一个音调。简谱对应相应的音调也在图中有对应关系,就不一一举出了。但是要介绍一下升音符号(#)以及降音符号(b),比如“#1”就是中央C升高半音,就是右上角的黑键。

# 1、音符

音符是用来记录不同长短的音的进行符号。全音符 (opens new window)、二分音符 (opens new window)、四分音符 (opens new window)、八分音符 (opens new window)、十六分音符 (opens new window)是最常见的音符,具体的内容大家可以点击超链接去康康。其中四分音符一般是一个时间基准(500毫秒),后面加一个横线就是二分音符,下面加一个横线就是八分音符,以此类推。

img

# 2、音符与频率对照

img

# 3、单片机的12分频

  • 标准51单片机是12T的
    • 单片机中的12分频 是单片机的标准运算速度是晶振的12分之1。
    • 12分频就是频率除以12频率的12分之一。
    • 比如接的晶振是12mhz的12分频后就是1mhz,周期就是1/1mhz=1us也就是计数器经过1us加1

# 4、计算周期以及重装载值

  • 周期:12/11.0592/B2*1000000(因为我是11.0592MHZ的晶振,所以是这样)
    • 一个机器周期是振荡周期(晶振频率)的 1/12 。
    • 所以一个机器周期 T=1/f=1/262*1000000=3816.793(约等于了),因为我们的板子是11.0592HZ,所以 3816.793 * 12 / 11.0592 = 4141.486
    • 因为一个周期就是有一次翻转,(高电平和低电平的变化),所以重装载值就是一个周期的一半(重装载值就是定时器的初值,我们通过262频率计算出对应高低电平持续的时间,或者说是高低电平翻转的一次时间)
  • 重装载值:65536-D2(65536-周期一半)

如下图所示:

img

# 三、代码

img

// Buzzer.c
#include <REGX52.H>
#include <INTRINS.H>
 
//蜂鸣器端口:
sbit Buzzer=P1^5;
 
/**
  * @brief  蜂鸣器私有延时函数,延时500us
  * @param  无
  * @retval 无
  */
void Buzzer_Delay500us()		//@11.0592MHz
{
	unsigned char i;
 
	_nop_();
	i = 227;
	while (--i);
}
 
 
/**
  * @brief  蜂鸣器发声
  * @param  ms 发声的时长,范围:0~32767
  * @retval 无
  */
void Buzzer_Time(unsigned int ms)
{
	unsigned int i;
	for(i=0;i<ms*2;i++)
	{
		Buzzer=!Buzzer;
		Buzzer_Delay500us();
	}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// main.c
#include <REGX52.H>
#include "Delay.h"
#include "Time0.h"
#include "Buzzer.h"
 
//蜂鸣器端口:
sbit Buzzer=P1^5;
 
#define SPEED 460
//音符与索引对应表,P:休止符,L:低音,M:中音,H:高音,下划线:升半音符号#
#define P	0
#define L1	1
#define L1_	2
#define L2	3
#define L2_	4
#define L3	5
#define L4	6
#define L4_	7
#define L5	8
#define L5_	9
#define L6	10
#define L6_	11
#define L7	12
#define M1	13
#define M1_	14
#define M2	15
#define M2_	16
#define M3	17
#define M4	18
#define M4_	19
#define M5	20
#define M5_	21
#define M6	22
#define M6_	23
#define M7	24
#define H1	25
#define H1_	26
#define H2	27
#define H2_	28
#define H3	29
#define H4	30
#define H4_	31
#define H5	32
#define H5_	33
#define H6	34
#define H6_	35
#define H7	36
unsigned int FreqTable[] = {0,
	64303 ,63577 ,63691 ,63792 ,63892 ,63981 ,64070 ,64152 ,64229 ,64303 ,64372 ,64437 ,
	64499 ,64557 ,64612 ,64664 ,64713 ,64759 ,64803 ,64844 ,64883 ,64919 ,64954 ,64987 ,
	65018 ,65047 ,65074 ,65100 ,65125 ,65148 ,65169 ,65190 ,65209 ,65228 ,65245 ,65261
};
 
 
// 第一个H2意思是频率;第二个4,代表一个4分音符;code是把代码放到Flash里面。
unsigned char code Music[]={
	H2,4,
	M7,4,
	H1,4,
	M6,4,
	
	H2,4,
	M7,4,
	H1,4,
	M6,4,
//	// 注释部分是高潮的前面部分
//	M3,4+4+4+4,
//	P,4+4,	
//	P,2,	
//	M1,2,
//	M2,2,
//	M1,2,
//	M3,4+4+4+4,
//	P,4+2,
//	M1,2,
//	M2,2,
//	M1,2,
//	M2,2,
//	M3,2,
//	//
//	L6,4+2,
//	M1,2,
//	L6,4+2,
//	M1,2,
//	
//	L6,4+2,
//	M1,2,
//	M2,4,
//	M1,4,
//	
//	L7,4+4+4+4,
//	P,4+4+4+4,
//	
//	//
//	M3,4+4+4+4,
//	P,4+4,	
//	P,2,	
//	M1,2,
//	M2,2,
//	M1,2,
//	M3,4+4+4+4,
//	P,4+2,
//	M1,2,
//	M2,2,
//	M1,2,
//	M2,2,
//	M3,2,
//	//
//	L6,4+2,
//	M1,2,
//	L6,4+2,
//	M1,2,
//	
//	L6,4+2,
//	M1,2,
//	M3,4,
//	M1,2,
//	M2,2,
//	
//	L7,4+4+4+4,
//	P,4+4+4+4,
	//
//	H6,2,
//	M1,2,
//	M6,4+2+2+2,
//	M5, 2,
//	
//	M6,4+2,
//	M5,2,
//	M6,2,
//	M5,2,
//	M6,2,
//	
//	M5,2+2,
//	M3,2+2+4+4,
//	P,4+4+4,
//	H6,2,
//	M1,2,
	//
//	M6,4+2+2,
//	M5,2,
//	M6,2,
//	M5,2,
 
//	M7,4+2+2,
//	M6,2,
//	M7,2+2,
//	M6,4,
//	M3,2+2+4,
//	
//	P,4+4+2,
//	M3,2,
//	M5,2,
//	M3,2,
	//
//	M2,4+2,
//	M3,2,
//	M2,4+2,
//	M3,2,
 
//	M2,4+2,
//	M3,2,
//	M5,2,
//	M3,2,
//	M5,2,
//	M3,2,
//	
//	M2,4+2,
//	M3,2,
//	M2,4+2,
//	M3,2,
//	
//	M2,4+4+4,
//	M1,2,
//	M2,2,
//	//
//	M3,4,
//	M6,4,
//	M1,4,
//	M3,2,
 
//	M2,4+2,
//	M3,2,
//	M2,4,
//	M1,4,
	
//	M6,4+4+4+4,
 
 
 
 
 
// 高潮部分
	P,4+4+4,
	M6,2,
	M7,2,
	//
	M1,2,
	M2,2,
	M7,2,
	M1,2+4+2,
	M7,2,
	
	M1,2,
	M2,2,
	M7,2,
	M1,2+4+2,
	M2,2,
	
	M3,2,
	M2,2,
	M3,2,
	M2,2,
	M3,4+2,
	M2,2,
	
	M3,4,
	M5,4,
	M3,4,
	M6,2,
	M7,2,
	//
	M1,2,
	M2,2,
	M7,2,
	M1,2+4+2,
	M7,2,
	
	M1,2,
	M2,2,
	M7,2,
	M1,2+4+2,
	M2,2,
	
	M3,2,
	M2,2,
	M3,2,
	M2,2,
	M3,4+2,
	M2,2,
	
	M3,4,
	M5,4,
	M3,4,
	M5,4,
	//
	M3,2+4,
	M5,2,
	M3,2+4,
	M5,2,
	
	M3,2,
	M5,2,
	M6,2,
	M3,2,
	M5,4,
	M5,4,
	
	M3,2+4,
	M5,2,
	M3,2+4,
	M5,2,
//	
	M3,2,
	M5,2,
	M6,2,
	M3,2,
	M5,4,
	M5,2+2,
//
	M3,4,
	M2,4,
	M2,4,
	M1,2,
	M3,2,
	
	M3,4,
	M2,4,
	M2,4,
	M1,2,
	M1,2,
	
	L6,4+4+4+4,
	P,4+4+4,
	M5,2+2,
 
	//
	M3,4,
	M2,4,
	M2,4,
	M1,2,
	M3,2,
	
	M3,4,
	M2,4,
	M2,4,
	M1,2,
	M1,2,
	
	L6,4+4+4+4,
	P,4+4+4+4,
	
	0xFF
};
	
 
 
 
unsigned char FreqSelect,MusicSelect;
void main(){
	// 初始化定时器
	Timer0Init();
	while(1){
		// 判断是否是休止符
		if(Music[MusicSelect] != 0xFF){
			//发声
		FreqSelect = Music[MusicSelect];
		MusicSelect++;
			//持续时长
		Delay(SPEED/4*Music[MusicSelect]);
		MusicSelect++;
		TR0 = 0;
		Delay(5);
		TR0 = 1;
		}else{
			TR0 = 0;
		while(1);
	}
	}
		
	}
 
 
void Timer0_Routine() interrupt 1
{
if(FreqTable[FreqSelect]){
	TL0 = FreqTable[FreqSelect] % 256;		//设置定时初始值
	TH0 = FreqTable[FreqSelect] / 256;	
	Buzzer =! Buzzer; // 响
}
		
	}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
编辑 (opens new window)
上次更新: 2023/09/13, 12:29:52
LED点阵屏
AT24C02存储器

← LED点阵屏 AT24C02存储器→

最近更新
01
51单片机及补充知识
09-13
02
独立按键
09-13
03
LCD1602液晶显示器
09-13
更多文章>
Theme by Vdoing | Copyright © 2019-2023 Evan Xu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式