摘要:MAXQ3210微控制器集成了一个压电扬声器驱动器,以固定频率驱动高音扬声器。本应用笔记演示了怎样改动扬声器驱动器反馈单元,利用软件来产生各种频率信号。
早期的计算机和电子游戏使用压电扬声器产生的各类声音,从单音、汽笛音到白噪声等。和早期相比,个人计算机的声音产生技术有了很大的进步。今天,系统即使增加了多通道、数字声音和音乐,以及基于MIDI的音乐合成器系统,仍然使用简单的压电扬声器。汽车报警、烟雾探测器、销售点(PoS)终端、小型电子玩具和游戏以及很多应用都依靠压电声发生器来产生单音、大分贝报警音效。
对于只需要一路频率输出的应用,可以对压电扬声器进行优化,以一定的音频振荡。通过加入反馈网络和逆变器,扬声器在接通后以共振频率开始自激振荡。这类网络通常用于在烟雾探测器、二氧化碳传感器和安防系统中产生大分贝报警音。
Maxim的MAXQ3210微控制器集成了这类压电扬声器驱动电路(图1)。软件界面非常简单,包括一个控制位,用于打开或者关断扬声器。输出音的频率和音量完全由压电扬声器和反馈网络元件决定。
图1. MAXQ3210微控制器的压电音驱动电路
在软件控制下迅速接通和关断扬声器可以产生各种嘀哒、啁啾等声音效果,但是输出频率不变。怎样才能产生各种不同的输出频率呢?
为改变输出频率,必须去掉自动反馈环路,直接通过端口引脚来控制扬声器输出。数字扬声器的输入可以在固定电压和地之间切换,微控制器的数字I/O引脚可直接驱动它。根据压电扬声器输出大小和所需的分贝数,可能需要专门的驱动电路或者IC来处理压电扬声器引脚的高压,或者将大电流驱动到扬声器中,以产生高音。在这些情况下,微控制器I/O引脚被用于打开或者关断扬声器,设置输出频率。I/O引脚不直接驱动压电单元。
MAXQ3210还可用于产生多个扬声器输出频率。反馈输入引脚直接连接到器件的一个其他端口引脚上。只要内置扬声器逆变器能够跟上端口引脚驱动的频率,按照合适的速率触发端口引脚都可以产生所需的音调。
注意:本应用笔记的源代码可以下载(ZIP, 4.5kB)。
表1. 音符和接近的声音频率
以一定频率来接通和关断MAXQ3210端口引脚最简单的方法是使用软件循环。使用微控制器的单周期指令执行频率来计算内循环延时,该频率典型值为3.57MHz。
MAXQ3210集成了计数器/定时器功能。在一种模式下,定时器可以在端口引脚上产生某一频率的输出波形。利用这种模式,将定时器输出引脚连接至反馈输入,微控制器在音符开始时启动定时器,在音符结束时关掉它。
定时器还可以用于控制音符本身的持续时间。MAXQ3210含有另一个长周期定时器,非常适合完成这一任务。通过在每一音符间隔开始产生一个中断,定时器查找预编码的音符查找表,以更少的空间来编码时间更长的音乐。
引言
压电蜂鸣器或扬声器使用压电晶体单元,压电晶体在加电时会出现轻微变形,将电信号转换为声音。晶体单元连在扬声器锥体或面板,当施加快速变化的电压时,它会快速振动。这种振动激发出空气中的声波,从而产生频率基于电波频率的音调。早期的计算机和电子游戏使用压电扬声器产生的各类声音,从单音、汽笛音到白噪声等。和早期相比,个人计算机的声音产生技术有了很大的进步。今天,系统即使增加了多通道、数字声音和音乐,以及基于MIDI的音乐合成器系统,仍然使用简单的压电扬声器。汽车报警、烟雾探测器、销售点(PoS)终端、小型电子玩具和游戏以及很多应用都依靠压电声发生器来产生单音、大分贝报警音效。
改动硬件驱动扬声器
对系统中的压电扬声器增加硬件非常简单。对于只需要一路频率输出的应用,可以对压电扬声器进行优化,以一定的音频振荡。通过加入反馈网络和逆变器,扬声器在接通后以共振频率开始自激振荡。这类网络通常用于在烟雾探测器、二氧化碳传感器和安防系统中产生大分贝报警音。
Maxim的MAXQ3210微控制器集成了这类压电扬声器驱动电路(图1)。软件界面非常简单,包括一个控制位,用于打开或者关断扬声器。输出音的频率和音量完全由压电扬声器和反馈网络元件决定。
图1. MAXQ3210微控制器的压电音驱动电路
在软件控制下迅速接通和关断扬声器可以产生各种嘀哒、啁啾等声音效果,但是输出频率不变。怎样才能产生各种不同的输出频率呢?
为改变输出频率,必须去掉自动反馈环路,直接通过端口引脚来控制扬声器输出。数字扬声器的输入可以在固定电压和地之间切换,微控制器的数字I/O引脚可直接驱动它。根据压电扬声器输出大小和所需的分贝数,可能需要专门的驱动电路或者IC来处理压电扬声器引脚的高压,或者将大电流驱动到扬声器中,以产生高音。在这些情况下,微控制器I/O引脚被用于打开或者关断扬声器,设置输出频率。I/O引脚不直接驱动压电单元。
MAXQ3210还可用于产生多个扬声器输出频率。反馈输入引脚直接连接到器件的一个其他端口引脚上。只要内置扬声器逆变器能够跟上端口引脚驱动的频率,按照合适的速率触发端口引脚都可以产生所需的音调。
注意:本应用笔记的源代码可以下载(ZIP, 4.5kB)。
音乐合成器
为能够产生简单的音乐信号,扬声器必须接通一段时间,然后关断相同的时间。产生的声音频率由下面的公式给出:输出频率 = 1/(长周期 + 短周期)为能够产生一定时间长度的声音,需要计算进行驱动的完整周期数:
周期数 = (声音持续时间 × 输出频率)以中C基本钢琴音标音频为例。对这些频率进行调谐,音符“中C的A”等于440Hz。表1中列出的值是近似值。
表1. 音符和接近的声音频率
Note | Frequency (Hz) |
Middle C | 261 |
C sharp/D flat | 277 |
D | 294 |
D sharp/E flat | 311 |
E | 330 |
F | 349 |
F sharp/G flat | 370 |
G | 392 |
G sharp/A flat | 415 |
A | 440 |
A sharp/B flat | 466 |
B | 494 |
C (next octave up) | 523 |
以一定频率来接通和关断MAXQ3210端口引脚最简单的方法是使用软件循环。使用微控制器的单周期指令执行频率来计算内循环延时,该频率典型值为3.57MHz。
move HRNC, #1 ; Turn the piezoelectric horn driver on. ;; Play Middle C for one second. move LC[1], #261 ; Outer loop counter = 261 cycles (1s * 261Hz) middleC: move PO0.0, #1 ; Switch output high. move LC[0], #6839 ; Half period : (1/261Hz) / (1/3.57MHz) / 2 djnz LC[0], $ ; Decrement and jump, if not zero, to current ; instruction. move PO0.0, #0 ; Switch output low. move LC[0], #6839 ; Half period : (1/261Hz) / (1/3.57MHz) / 2 djnz LC[0], $ ; Decrement and jump if not zero to current ; instruction. djnz LC[1], middleC ; Decrement and jump, if not zero, to top of loop.通过改变循环计数器LC[0]装载的数值来改变输出频率(对应于产生的音符)。通过改变循环计数器LC[1]装载的数值来改变音符持续时间。把这些代码打包到一个简单宏中,定义几个常数,就很容易产生播放一小段音乐的代码。
#define NOTE_C 261 #define NOTE_C_SH 277 #define NOTE_D_FL 277 #define NOTE_D 294 #define NOTE_D_SH 311 #define NOTE_E_FL 311 #define NOTE_E 330 #define NOTE_F 349 #define NOTE_F_SH 370 #define NOTE_G_FL 370 #define NOTE_G 392 #define EIGHTH 1 ; 120 beats per minute, 4/4 time #define QUARTER 2 ; 120 beats per minute, 4/4 time #define QUARTERDOT 3 ; 120 beats per minute, 4/4 time #define HALF 4 ; 120 beats per minute, 4/4 time #define WHOLE 8 ; 120 beats per minute, 4/4 time play macro note, duration local L1, L2 move HRNC, #1 move LC[1], #(note * duration / 8) L1: move PO0.0, #1 ; Switch output high. move LC[0], #(1785000 / note) djnz LC[0], $ ; Decrement and jump, if not zero, to current ; instruction. move PO0.0, #0 ; Switch output low. move LC[0], #(1785000 / note) djnz LC[0], $ ; Decrement and jump, if not zero, to current ; instruction. djnz LC[1], L1 ; Decrement and jump, if not zero, to top of loop. move HRNC, #1 move LC[1], #50 ; 50ms of silence L2: move LC[0], #3570 ; 1ms (inner loop) djnz LC[0], $ djnz LC[1], L2 endm ;; First 8 bars of Beethoven's "Ode to Joy" play NOTE_E, QUARTER play NOTE_E, QUARTER play NOTE_F, QUARTER play NOTE_G, QUARTER play NOTE_G, QUARTER play NOTE_F, QUARTER play NOTE_E, QUARTER play NOTE_D, QUARTER play NOTE_C, QUARTER play NOTE_C, QUARTER play NOTE_D, QUARTER play NOTE_E, QUARTER play NOTE_E, QUARTERDOT play NOTE_D, EIGHTH play NOTE_D, HALF play NOTE_E, QUARTER play NOTE_E, QUARTER play NOTE_F, QUARTER play NOTE_G, QUARTER play NOTE_G, QUARTER play NOTE_F, QUARTER play NOTE_E, QUARTER play NOTE_D, QUARTER play NOTE_C, QUARTER play NOTE_C, QUARTER play NOTE_D, QUARTER play NOTE_E, QUARTER play NOTE_D, QUARTERDOT play NOTE_C, EIGHTH play NOTE_C, HALF可以缩小这一例子需要的代码空间。只使用子程序(而不是解开的代码宏)和查找表就可以产生音符值。其基本原理相同。
定时器驱动的音乐合成器
上面的代码虽然非常简单,但是要求微控制器牺牲其所有时间来产生音调。对于音乐贺卡等简单应用,这样简单地使用微控制器是可以的。然而,对于更复杂的应用,需要在后台播放音乐,而微控制器去完成其他工作。为完成这种双重角色,微控制器必须从周期性地开关端口引脚以产生某一音符这类工作中解放出来。MAXQ3210集成了计数器/定时器功能。在一种模式下,定时器可以在端口引脚上产生某一频率的输出波形。利用这种模式,将定时器输出引脚连接至反馈输入,微控制器在音符开始时启动定时器,在音符结束时关掉它。
定时器还可以用于控制音符本身的持续时间。MAXQ3210含有另一个长周期定时器,非常适合完成这一任务。通过在每一音符间隔开始产生一个中断,定时器查找预编码的音符查找表,以更少的空间来编码时间更长的音乐。
评论
查看更多