《DN8P1开发指南_V1.0》第九章 蜂鸣器实验

第九章 蜂鸣器实验

上一章,我们介绍了 RA8P1的 IO 口作为输出的使用。本章,我们将通过另外一个例子继续讲述 RA8P1的 IO 口作为输出的使用,不同的是本章讲的不是用 IO 口直接驱动器件,而是通过三极管间接驱动。我们将利用一个 IO 口来控制板载的有源蜂鸣器。
本章分为如下几个小节:
9.1 蜂鸣器简介
9.2 硬件设计
9.3 程序设计
9.4 下载验证

9.1 蜂鸣器简介
蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于计算机、打印机、复印机、报警器、电子玩具、汽车电子设备、电话机、定时器等电子产品中作发声器件。蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型。
RA8P1板载的蜂鸣器是电磁式的有源蜂鸣器,如图 9.1.1 所示:

image001

图9.1.1 有源蜂鸣器

这里的有源不是指电源的“源”,而是指有没有自带震荡电路,有源蜂鸣器自带了震荡电路,一通电就会发声;无源蜂鸣器则没有自带震荡电路,必须外部提供 2~5Khz 左右的方波驱动,才能发声。

上一章,我们利用 RA8P1的 IO 口直接驱动 LED 灯,本章的蜂鸣器,我们能否直接用 RA8P1的 IO 口驱动呢?让我们来分析一下:RA8P1的单个 IO 最大可以提供 20mA 电流(来自数据手册),而蜂鸣器的驱动电流是 30mA 左右,两者差距不小,且出于全盘考虑,RA8P1整个芯片的电流也不是很高,如果用 IO 口直接驱动蜂鸣器,其他地方用电就得省着点了,所以我们不用 RA8P1的 IO 直接驱动蜂鸣器,而是通过三极管扩流后再驱动蜂鸣器,这样 RA8P1的 IO 只需要提供不到 1mA 的电流就足够了。

IO 口使用虽然简单,但是和外部电路的匹配设计,还是要十分讲究的,考虑越多,设计就越可靠,可能出现的问题也就越少。

9.2 硬件设计
1. 例程功能
LED周期翻转,且伴随着LED灯闪烁的同时,蜂鸣器声响。

2. 硬件资源
1)LED 灯
LED0 – P108
LED1 – PD06
2)蜂鸣器
BEEP – 0P001

3. 原理图
蜂鸣器在硬件上是直接连接好了的,不需要经过任何设置,直接编写代码就可以了。蜂鸣器的驱动信号连接在RA8P1的P001上。如图9.2.1所示:

image003

图 9.2.1 蜂鸣器与 RA8P1连接原理图

我们用一个NPN三极管(S8050)来驱动蜂鸣器,驱动信号通过R56和R57间的电获得,芯片上电时默认电平为低电平,故上电时蜂鸣器不会直接响起。当P001输出高电平的时候,蜂鸣器将发声,当P001输出低电平的时候,蜂鸣器停止发声。

**9.3 程序设计 **
9.3.1 FSP配置流程
注意:LED的FSP配置流程,我们已经在第八章节讲解过,这里我们不再赘述。
在FSP配置PinsPorts路径下配置P001管脚初始化为低电平,如下图所示。

image005

9.3.2 程序解析
1. 蜂鸣器驱动代码
这里我们只讲解核心代码,详细的源码请大家参考光盘本实验对应源码。蜂鸣器(BEEP)驱动源码包括两个文件:buzzer.c 和 buzzer.h。
下面我们先解析 buzzer.h 程序中的引脚定义与操作函数定义。

/* 蜂鸣器管脚定义 (P001) */
#define BUZZER_GPIO_PIN   BSP_IO_PORT_00_PIN_01

/* 蜂鸣器状态设置:1-响,0-停 */
#define BUZZER(x)    
do { x ?                                      \
       R_IOPORT_PinWrite(&g_ioport_ctrl, BUZZER_GPIO_PIN, BSP_IO_LEVEL_HIGH) :\
       R_IOPORT_PinWrite(&g_ioport_ctrl, BUZZER_GPIO_PIN, BSP_IO_LEVEL_LOW); \
    } while(0)

/* 蜂鸣器状态翻转 */
#define BUZZER_TOGGLE()    
do { bsp_io_level_t level; \
          R_IOPORT_PinRead(&g_ioport_ctrl, BUZZER_GPIO_PIN, &level); \
          R_IOPORT_PinWrite(&g_ioport_ctrl, BUZZER_GPIO_PIN, \
          (level == BSP_IO_LEVEL_HIGH) ? BSP_IO_LEVEL_LOW:BSP_IO_LEVEL_HIGH);\
        } while(0)

BUZZER(x) 这个宏定义就是控制蜂鸣器的打开和关闭的。例如:如果要打开蜂鸣器,那么调用宏定义 BUZZER(1) 即可,如果要关闭蜂鸣器,调用宏定义 BUZZER(0) 即可。
BUZZER_TOGGLE() 是控制蜂鸣器进行翻转的。这里通过先读取引脚当前电平、再写入相反电平的方式,实现 IO 口输出电平取反操作。
下面我们再解析 buzzer.c 的程序,这里只有一个函数 buzzer_init,这是蜂鸣器的初始化函数,其定义如下:

/**
 * @brief 蜂鸣器初始化
 * @note  P001引脚配置为输出模式,默认关闭蜂鸣器
 * @param 无
 * @retval 无
 */
void buzzer_init(void)
{
    /* 系统已在hal_warmstart.c中初始化IOPORT,此处仅初始化默认状态 */
    BUZZER(0);  /* 默认关闭蜂鸣器 */
}

引脚的输出模式、电气属性已通过 FSP 配置工具完成配置,并在系统启动时统一初始化。buzzer_init 函数仅负责设置蜂鸣器的默认状态:上电后默认关闭蜂鸣器,防止没有操作就发声。

2. hal_entry.c 代码
在 hal_entry.c 里面编写如下代码:

void hal_entry(void)
{
    delay_init(1000000);    	/* 初始化delay */
    led_init();              	/* 初始化LED */
    buzzer_init();          	/* 初始化蜂鸣器 */
    while(1)
    {
        /* LED0 和 LED1周期翻转 */
        LED0_TOGGLE();
        LED1_TOGGLE();
        /* 蜂鸣器响 */
        BUZZER(1);
        delay_s(1);         /* 延时1秒 */
        /* LED翻转 */
        LED0_TOGGLE();
        LED1_TOGGLE();
        /* 蜂鸣器停 */
        BUZZER(0);
        delay_s(1);         /* 延时1秒 */
    }
}

hal_entry 是 FSP 工程的系统启动入口点。程序首先初始化延时函数、LED 和蜂鸣器外设,最后在无限循环中实现 LED0、LED1 周期翻转,同时蜂鸣器以 1 秒为间隔开关,与 LED 闪烁状态同步。

9.4 下载验证
下载完之后,可以看到开发板上的 LED0、LED1 周期翻转闪烁,蜂鸣器伴随 LED 的状态同步发出声响,亮灭与发声间隔均为 1 秒,符合预期设计。
至此,本章的学习就结束了。通过本章,我们进一步学习 IO 作为输出的使用方法,同时巩固了前面知识的学习。希望大家在开发板上实际验证一下,从而加深印象。

posted @ 2026-11-04 16:41  正点原子  阅读(9)  评论(0)    收藏  举报