【DSP28335 入门教程】让你的开发板“发声”—— 蜂鸣器控制 (GPIO脉冲篇)

大家好,欢迎回到我们的 DSP28335 探索之旅!在上一篇教程中,我们成功点亮了 LED,完成了与这个强大芯片的第一次“视觉”交流。这一次,我们将更进一步,进行一次“听觉”互动——学习如何驱动蜂鸣器,让我们的开发板发出声音。

本篇将首先分析我们开发板上无源蜂鸣器的硬件驱动电路,然后通过配置 GPIO 并使用软件延时产生方波脉冲来驱动它。这不仅是一个有趣的实验,更是理解 DSP 信号生成和未来学习 PWM (脉冲宽度调制) 控制的绝佳前奏。

硬件分析:声音是如何产生的?

在动手编码之前,我们必须先弄清楚硬件是如何连接的,以及它需要什么样的信号才能工作。

1. 确认硬件:开发板使用的是无源蜂鸣器

在开始前,最重要的一点是明确我们面对的硬件类型。我们开发板上所使用的,是一个无源蜂鸣器 (Passive Buzzer)。

什么是无源蜂鸣器呢?你可以把它想象成一个微型的小喇叭。它内部没有振荡电路,你必须给它提供一定频率的脉冲信号(方波),它才会根据这个频率发出对应音调的声音。频率高,音调就高;频率低,音调就低。

我们之所以分析这种蜂鸣器,正是因为它给了我们用软件自由控制音调和节奏的可能,更能体现 DSP 的强大控制能力。

作为对比,我们简单提一下有源蜂鸣器 (Active Buzzer)。有源蜂鸣器内部自带了振荡源,这是另一种非常经典的开关电路。当 BUZ 信号为高电平时,电流通过 R06 流入三极管的基极(B),三极管导通,集电极(C)和发射极(E)之间近似短路,将蜂-鸣器 BZ1 的负极拉到地,蜂鸣器发声。BUZ 为低电平时,三极管截止,蜂鸣器不响。请记住,我们后续所有的实验对象,都是板载的这个无源蜂鸣器。

2. 驱动电路分析

由于 DSP 的 IO 口驱动电流有限(通常是几毫安),不足以直接驱动需要较大电流的蜂鸣器。因此,我们需要一个驱动电路来放大电流。

为了解决这些问题,DSP 提供了一个强大的外设——ePWM (增强型脉宽调制模块)。它可以在硬件层面产生精确、稳定、可调的方波,而完全不占用 CPU 时间。

在下一篇教程中,我们将把 GpioCtrlRegs.GPAMUX1.bit.GPIO6 的配置从 0 改为 1,把控制权从 GPIO 交给 ePWM 模块,实现对无源蜂鸣器音调的更高级控制。

总结

今天,我们通过分析硬件电路,将软件与硬件紧密结合,使用最基本的 GPIO 功能和软件延时,成功驱动了无源蜂鸣器。你已经掌握了:

请动手尝试修改 DELAY_US() 中的数值,比如改成 DELAY_US(500) 或 DELAY_US(1000),听听看音调会有什么变化?这个简单的实验将加深你对频率和音高关系的理解。

期待在下一篇 PWM 教程中与你再次相遇!

  • 核心器件: ULN2003D 是一款达林顿晶体管阵列芯片,可以看作一个包含了多个“开关”的集合,专门用来驱动继电器、电机、LED灯带等稍大功率的负载。

  • 信号流向: DSP 的 EPWM4A 引脚发出的控制信号,进入 ULN2003D 的 IN7 输入端。芯片的 OUT7 输出端连接到无源蜂鸣器 BZ1 的一端,蜂鸣器的另一端接 D5V (5V电源)。

  • 工作原理: ULN2003D 是一个反相器。当 IN7 为高电平(比如3.3V)时,内部开关导通,OUT7 被拉到接近地(GND)的低电平。此时电流从 D5V -> 蜂鸣器 -> OUT7 -> GND,形成回路,蜂鸣器两端产生压差。反之,IN7 为低电平时,OUT7 悬空,回路断开。

  • 控制逻辑: 要让无源蜂鸣器发声,我们需要让 IN7 高低电平快速切换,从而让蜂鸣器两端的压差不断通、断,使其振动发声。

  • 3. DSP 引脚映射

  • 从图中可以确定,原理图上的 EPWM4A 信号,在 DSP 上复用的是 GPIO6 引脚。它属于 GPIOA 端口组。

    软件设计:谱写发声的代码

    现在,我们可以开始编写软件了。今天的目标是通过快速地切换 GPIO6 的高低电平,来产生一个固定频率的方波。

    1. 头文件 (beep.h)

    定义蜂鸣器控制的宏,并声明初始化函数。

  • #ifndef BEEP_H_
    #define BEEP_H_
    
    #include "DSP2833x_Device.h"     // DSP2833x 头文件
    #include "DSP2833x_Examples.h"   // DSP2833x 例子相关头文件
    
    // 宏定义只是为了方便操作IO口,BEEP_ON不代表持续响,而是输出高电平
    #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_ */

    2. 初始化函数 (beep.c)

    这个函数负责将 GPIO6 配置为通用推挽输出模式。

  • #include "beep.h"
    
    /*******************************************************************************
    * 函 数 名         : BEEP_Init
    * 函数功能		   : 蜂鸣器初始化
    * 输    入         : 无
    * 输    出         : 无*******************************************************************************/
    void BEEP_Init(void)
    {
    	EALLOW; // 关闭写保护
    
    	SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1; // 开启GPIO时钟,必备!
    
    	// 蜂鸣器引脚 (GPIO6) 配置
    	// 将引脚功能选为通用 GPIO 功能 (EPWM4A 是复用功能1)
    	GpioCtrlRegs.GPAMUX1.bit.GPIO6 = 0;
    	// 设置方向为输出
    	GpioCtrlRegs.GPADIR.bit.GPIO6 = 1;
    	// 使能内部上拉 (好习惯)
    	GpioCtrlRegs.GPAPUD.bit.GPIO6 = 0;
    
    	EDIS; // 开启写保护
    
    	// 初始化时,默认关闭蜂鸣器 (输出低电平)
    	GpioDataRegs.GPACLEAR.bit.GPIO6 = 1;
    }

  • GpioCtrlRegs.GPAMUX1.bit.GPIO6 = 0; 这一步至关重要。它明确告诉 DSP,我们现在要用 GPIO6 作为普通的 IO 口,而不是用它的复用功能 EPWM4A。在我们后续升级到 PWM 控制时,就需要修改这个值。

  • 3. 主函数 (main.c)

    在主循环中,我们不断地翻转 GPIO6 的电平,以产生方波。

  • #include "DSP2833x_Device.h"     // DSP2833x Headerfile Include File
    #include "DSP2833x_Examples.h"   // DSP2833x Examples Include File
    #include "leds.h" // 假设你保留了之前的 LED 代码
    #include "beep.h"
    
    void main()
    {
    	int i=0;
    
    	InitSysCtrl();  // 初始化系统控制
    	DINT;           // 关总中断
    
    	// 初始化外设
    	InitPieCtrl();
    	IER = 0x0000;
    	IFR = 0x0000;
    	InitPieVectTable();
    
    	LED_Init();     // 初始化 LED
    	BEEP_Init();    // 初始化蜂鸣器
    
    	while(1)
    	{
    		i++;
    
    		BEEP_TOGGLE;      // 翻转蜂鸣器IO口电平
    		DELAY_US(100);    // 延时 100 微秒
    
    		// 让 LED 闪烁得慢一些,以证明主程序在运行
    		if(i % 1000 == 0)
    		{
    			LED1_TOGGLE;
    		}
    	}
    }

    在这段代码里,BEEP_TOGGLE; DELAY_US(100); 是核心。BEEP_TOGGLE 使 GPIO6 电平翻转一次(高变低或低变高),DELAY_US(100) 保持这个状态 100 微秒。因此,一个完整的高低电平周期是 100us (高) + 100us (低) = 200us。

    这个方波的频率就是:f = 1 / T = 1 / 200us = 1 / 0.0002s = 5000 Hz = 5 kHz。

    这个 5kHz 的信号驱动板载的无源蜂鸣器,我们就能听到清脆的“嘀”声了!

    展望:更优雅的 PWM 控制

    虽然我们成功地让蜂鸣器发声了,但使用 DELAY_US 的方法有几个缺点:

  • 阻塞式 (Blocking): DELAY_US 是通过执行空循环来消耗时间的,在延时期间,CPU 不能做任何其他事情,浪费了宝贵的计算资源。

  • 不精确: 如果系统中有中断发生,延时的时间会变得不准确,导致音调不稳定。

  • 不灵活: 改变音调需要修改代码中的延时值,并且难以产生复杂的音乐旋律。

  • 无源蜂鸣器驱动电路的基本原理。

  • 如何将 GPIO 引脚配置为通用输出。

  • 利用软件循环产生脉冲信号来制造声音。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值