(1)实验平台:
普中DSP28335开发板
https://item.taobao.com/item.htm?id=594649003982 (2)资料下载:普中科技-各型号产品资料下载链接
在前面章节中我们已经介绍了如何控制 F28335 的 IO 口输出高低电平, 本章我们通过另外一个实验来讲述 F28335 IO 口的输出。 通过 F28335 芯片的一个IO 口 控 制 板 载 无 源 蜂 鸣 器 , 实 现 蜂 鸣 器 控 制 。 学 习 本 章 可 以 参 考" tms320f28335(中文版).pdf" 的"4.13 GPIO MUX" 章节和" TMS320x2833x, 2823x System Control and Interrupts Reference Guide (Rev. D).pdf" 的"6 General-Purpose Input/Output (GPIO)" 章节, 特别是在涉及到寄存器功能部分, 或者参考前面 LED 实验章节。 若结合视频学习效果更佳。 本章分为如下几部分内容:
[9.1 蜂鸣器介绍](#9.1 蜂鸣器介绍)
[9.2 硬件设计](#9.2 硬件设计)
[9.3 软件设计](#9.3 软件设计)
[9.3.1 蜂鸣器初始化函数](#9.3.1 蜂鸣器初始化函数)
[9.3.2 主函数](#9.3.2 主函数)
[9.4 实验现象](#9.4 实验现象)
9.1 蜂鸣器介绍
蜂鸣器是一种一体化结构的电子讯响器, 采用直流电压供电, 广泛应用于计算机、 打印机、 复印机、 报警器、 电子玩具、 汽车电子设备、 电话机、 定时器等电子产品中作发声器件。 蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型。
压电式蜂鸣器主要由多谐振荡器、 压电蜂鸣片、 阻抗匹配器及共鸣箱、 外壳等组成。 多谐振荡器由晶体管或集成电路构成, 当接通电源后( 1.5~15V 直流工作电压) , 多谐振荡器起振,输出 1.5~5kHZ 的音频信号, 阻抗匹配器推动压电蜂鸣片发声。
电磁式蜂鸣器由振荡器、 电磁线圈、 磁铁、 振动膜片及外壳等组成。 接通电源后, 振荡器产生的音频信号电流通过电磁线圈, 使电磁线圈产生磁场, 振动膜片在电磁线圈和磁铁的相互作用下, 周期性地振动发声。
其实一句话就可概括它们之间的区别, 想要压电式蜂鸣器发声, 需提供一定频率的脉冲信号; 想要电磁式蜂鸣器发声, 只需提供电源即可。
我们 PZ-DSP28335-L 开发板上使用的蜂鸣器是无源蜂鸣器, 属于压电式蜂鸣器类型。 这里说的有源, 并不是指电源的意思, 而是指蜂鸣器内部是否含有振荡电路, 有源蜂鸣器内部自带振荡电路, 只需提供电源即可发声, 而无源蜂鸣器则需提供一定频率的脉冲信号才能发声, 频率大小通常在 1.5-5KHz 之间。 有源蜂鸣器实物图如下图所示:

如果给有源蜂鸣器加一个 1.5-5KHz 的脉冲信号, 同样也会发声, 而且改变这个频率, 就可以调节蜂鸣器音调, 产生各种不同音色、 音调的声音。 如果改变输出电平的高低电平占空比, 则可以改变蜂鸣器的声音大小。
9.2 硬件设计
在前面章节中我们已经对 F28335 的 GPIO 做了简单介绍, 并且还使用了其中 IO 口直接控制开发板上的 LED。 对于本章要实现蜂鸣器的控制, 我们能否直接使用 F28335 的 IO 口驱动呢? 根据 F28335 芯片数据手册可知, 单个 IO 口的最大输出电流是 25mA, 而蜂鸣器的驱动电流是 30mA 左右, 两者非常接近, 有的朋友就想直接用 IO 口来驱动, 但是有没有考虑到整个芯片的输出电流, 整个芯片的输出电流最大也就 150mA, 如果在驱动蜂鸣器上就耗掉了 30mA, 那么芯片其他的 IO 口及外设电流就非常拮据了。 所以我们不会直接使用 IO 口驱动蜂鸣器, 而是通过三极管把电流放大后再驱动蜂鸣器, 这样 F28335 的 IO 口只需要提供不到 1mA 的电流就可控制蜂鸣器。 所以我们也经常说到 F28335 芯片是用来做控制的, 而不是驱动。
我们 PZ-DSP28335-L 开发板上的蜂鸣器模块电路如下图所示:


从上图可以看到, 无源蜂鸣器的控制需要给其一定频率的脉冲才能发声, 仅给一个高电平或者低电平是不能发声的, 因此蜂鸣器模块电路直接将 F28335 引脚接在 ULN2003 驱动芯片的输入口上, 对应通道的输出连接蜂鸣器(ULN2003 芯片的功能我们先不介绍, 大家只要知道该芯片可用于驱动一些大功率器件, 并且输入信号与输出信号是反向的, 即输入为高, 输出为低) 。 无需考虑外界对 GPIO6脚产生的高低电平会对蜂鸣器发声干扰。 如果自己在设计电路时使用的是有源蜂鸣器, 它只要有电源就会发声, 因此就必须考虑外界对 GPIO6 引脚电平的干扰问题。 通常我们会在控制蜂鸣器管脚上接一个上拉电阻, 用来防止蜂鸣器误发声。可参考下图电路, 当 BUZ 引脚输出低电平时, PNP 三极管导通, 蜂鸣器发声; 当BUZ 引脚输出高电平时, PNP 三极管截止, 蜂鸣器停止发声。

9.3 软件设计
本章所要实现的功能是: 让蜂鸣器发出声音, 即让 F28335 的 GPIO6 管脚输出一定频率的脉冲信号。 即间隔一定时间翻转 GPIO6 输出电平状态。 程序框架如下:
(1) 初始化蜂鸣器控制 IO 口(使能对应 IO 外设时钟、 配置 IO 为普通 IO功能和输出模式、 上拉设置等)
(2) 蜂鸣器控制程序
和前面章节一样, 我们从上一章程序模板拷贝一份, 并将文件夹命名为"Example04_DSP2833x_BEEP" , 打开 CCS 软件, 将工程导入进来, 并将工程名修改成与文件夹一致, 在后面的章节中我们不在重复叙述该部分内容, 而直接进入程序的设计。 打开"E:\DSP8233x_ProjectExample\DSP2833x_Example\Example04_DSP2833x_BEEP " 工程, 在 APP 文件夹内可以看到又新建了一个 beep 文件夹, 这个在前面 LED实验的时候也说过为什么要这样操作。
这里我们分析几个重要函数, 其他部分程序大家可以打开工程查看。
9.3.1 蜂鸣器初始化函数
我们打开工程中 beep.c 文件, 里面代码如下:
cpp
#include "beep.h"
void BEEP_Init(void)
{
EALLOW;
//BEEP 端口配置
GpioCtrlRegs.GPAMUX1.bit.GPIO6=0;
GpioCtrlRegs.GPADIR.bit.GPIO6=1;
GpioCtrlRegs.GPAPUD.bit.GPIO6=0;
EDIS;
GpioDataRegs.GPACLEAR.bit.GPIO6=1;
}
BEEP_Init()函数用来初始化蜂鸣器的端口及时钟, 并使 GPIO6 口默认输出一个低电平。 打开 beep.h, 可以看到如下代码:
cpp
#ifndef BEEP_H_
#define BEEP_H_
#include "DSP2833x_Device.h" // DSP2833x 头文件
#include "DSP2833x_Examples.h" // DSP2833x 例子相关头文件
#define BEEP_ON (GpioDataRegs.GPASET.bit.GPIO6=1)
#define BEEP_OFF (GpioDataRegs.GPACLEAR.bit.GPIO6=1)
#define BEEP_TOGGLE (GpioDataRegs.GPATOGGLE.bit.GPIO6=1)
void BEEP_Init(void);
#endif /* BEEP_H_ */
里面就将蜂鸣器的 GPIO 管脚控制进行了宏定义, 这样做是方便大家阅读和移植程序。
9.3.2 主函数
编写好蜂鸣器初始化函数后, 接下来就可以编写主函数来进行控制了, main.c 内程序代码如下:
cpp
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
#include "leds.h"
#include "beep.h"
void main()
{
int i=0;
InitSysCtrl();
LED_Init();
BEEP_Init();
while(1)
{
i++;
BEEP_TOGGLE;
if(i%1000==0)
{
LED1_TOGGLE;
}
DELAY_US(100);
}
}
主函数实现的功能比较简单, 首先将使用到的外设硬件进行初始化, 然后进入 while 循环, 间隔 100us 对蜂鸣器管脚电平翻转, 这样就产生了一个频率为5KHz 的脉冲, 因此无源蜂鸣器就会发声, 当然有源蜂鸣器的控制可以更简单,只需要给它一个低电平即可。 同时间隔 100ms 对 led1 管脚电平翻转, 因为使用到了 DELAY_US 延时函数, 所以在工程中要添加"DSP2833x_usDelay.asm" 文件, 该函数的使用非常简单, 从函数名即可知道其功能是 us 级延时函数, 使用该函数的前提是 InitSysCtrl()函数内必须配置系统时钟为 150MHZ, 大家有兴趣也可以进入到 DELAY_US 函数看其实现过程。 所以在我们后面需要延时的程序都会使用该函数, 非常方便实用, 后面就不重复。
9.4 实验现象
使用仿真器将开发板和电脑连接成功后, 把编写好的程序编译后, 如果没有报错即可将点击仿真调试, 程序即会写入到芯片的 RAM 内, 运行结果是蜂鸣器发声, 同时 D1 指示灯闪烁。 当系统断电后, 程序不会继续执行, 因为我们现在使用的是仿真调试, 即程序写入到 RAM 内, 而非 FLASH。