蜂鸣器主要有电磁式和电压式两种, 而且都有无源蜂鸣器和有源蜂鸣器两类。开发板使用的是电磁式无源蜂鸣器, 而有源和无源的区别是有源蜂鸣器内部自带振荡器,给个电压就能发声, 但频率是固定的,只能发出一种声音,而无源蜂鸣器频率可控,给个方波才可以发声, 并且根据不同频率发出不同的声音效果
驱动设计:
这里接着介绍下安富莱的有源蜂鸣器,但无源和有源蜂鸣器的核心思想都是一样的。
大部分情况下可以配置鸣叫次数、 鸣叫的时间和停止的时间。 本驱动设计就是基于这种应用方式实现,基本可以满足大部分应用情况。
设计这个软件驱动的关键之处是如何避免采用阻塞式的实现方式, 比如要实现鸣叫 1 秒,停止 1 秒,循环 5 次,如果是阻塞方式等待 1 秒执行完毕,那就时间太长了。 鉴于这种情况,程序里面实现了一种非阻塞的方式,通过滴答定时器中断每 10ms 调用一次蜂鸣器处理函数来实现鸣叫次数、 鸣叫的时间和停止的时间的更新。
蜂鸣器驱动的实现
一,定义结构体:
typedef struct _BEEP_T
{
uint8_t ucEnalbe;
uint8_t ucState;
uint16_t usBeepTime;
uint16_t usStopTime;
uint16_t usCycle;
uint16_t usCount;
uint16_t usCycleCount;
uint8_t ucMute; /* 1表示静音 */
}BEEP_T;
BEEP_T g_tBeep; /* 定义蜂鸣器全局结构体变量 */
成员 ucEnalbe: 用于使能或者禁止蜂鸣器。
成员 ucState: 状态变量,用于蜂鸣器鸣叫和停止的区分。
成员 usBeepTime: 鸣叫时间,单位 10ms。
成员 usStopTime: 停止鸣叫时间,单位 10ms。
成员 usCycle:鸣叫和停止的循环次数。
成员 usCount: 用于鸣叫和停止时的计数。
成员 usCycleCount: 用于循环次数计数。
二,启动蜂鸣器:
void BEEP_Start(uint16_t _usBeepTime, uint16_t _usStopTime, uint16_t _usCycle)
{
if (_usBeepTime == 0 || g_tBeep.ucMute == 1)
{
return;
}
g_tBeep.usBeepTime = _usBeepTime;
g_tBeep.usStopTime = _usStopTime;
g_tBeep.usCycle = _usCycle;
g_tBeep.usCount = 0;
g_tBeep.usCycleCount = 0;
g_tBeep.ucState = 0;
g_tBeep.ucEnalbe = 1; /* 设置完全局参数后再使能发声标志 */
BEEP_ENABLE(); /* 开始发声 */
}
第 1 个参数_usBeepTime 用于设置蜂鸣时间,单位 10ms,配置为 0 表示不鸣叫。
第 2 个参数_usStopTime 用于设置蜂鸣时间,单位 10ms,配置为 0 表示不鸣叫。
第 3 个参数_ _usCycle 用于鸣叫次数, 配置为 0 表示持续鸣叫。
三,被检测蜂鸣器状态:
void BEEP_Pro(void) //(5,2,2)
{
if ((g_tBeep.ucEnalbe == 0) || (g_tBeep.usStopTime == 0) || (g_tBeep.ucMute == 1))
{
return;
}
if (g_tBeep.ucState == 0) //实际上并不是指蜂鸣器当前没有在发声,而是指蜂鸣器处于准备开始发声的状态。在这种情况下,蜂鸣器即将开始发声,而不是已经停止发声。
{
if (g_tBeep.usStopTime > 0) /* 间断发声 */
{
if (++g_tBeep.usCount >= g_tBeep.usBeepTime)
{
BEEP_DISABLE(); /* 停止发声 */
g_tBeep.usCount = 0;
g_tBeep.ucState = 1;
}
}
else
{
; /* 不做任何处理,连续发声 */
}
}
else if (g_tBeep.ucState == 1)// 准备要停止发声
{
if (++g_tBeep.usCount >= g_tBeep.usStopTime)
{
/* 连续发声时,直到调用stop停止为止 */
if (g_tBeep.usCycle > 0)
{
if (++g_tBeep.usCycleCount >= g_tBeep.usCycle)
{
/* 循环次数到,停止发声 */
g_tBeep.ucEnalbe = 0;
}
if (g_tBeep.ucEnalbe == 0)
{
g_tBeep.usStopTime = 0;
return;
}
}
g_tBeep.usCount = 0;
g_tBeep.ucState = 0;
BEEP_ENABLE(); /* 开始发声 */
}
}
}
此函数是蜂鸣器的主处理函数,用于实现鸣叫时间、 停止鸣叫时间和循环次数的处理。
使用举例:
调用此函数前,务必优先调用函数 BEEP_InitHard 进行初始化。另外, 此函数需要周期性调用,每 10ms 调用一次。
如果是裸机使用, 将此函数放在 bsp.c 文件的 bsp_RunPer10ms 函数里面即可, 这个函数是由滴答
定时器调用的,也就是说,大家要使用蜂鸣器,定时器的初始化函数 bsp_InitTimer 一定要调用。
如果是 RTOS 使用, 需要开启一个 10ms 为周期的任务调用函数 BEEP_Pro。
本来想具体给大家分析以下的,问了下GPT,这玩意写的真牛逼,贴在这了,清晰明了
声控制。
GPT-3.5
void BEEP_Pro(void) //(5,2,2)
{
if ((g_tBeep.ucEnalbe == 0) || (g_tBeep.usStopTime == 0) || (g_tBeep.ucMute == 1))
{
return;
}
if (g_tBeep.ucState == 0) //实际上并不是指蜂鸣器当前没有在发声,而是指蜂鸣器处于准备开始发声的状态。在这种情况下,蜂鸣器即将开始发声,而不是已经停止发声。
{
if (g_tBeep.usStopTime > 0) /* 间断发声 */
{
if (++g_tBeep.usCount >= g_tBeep.usBeepTime)
{
BEEP_DISABLE(); /* 停止发声 */
g_tBeep.usCount = 0;
g_tBeep.ucState = 1;
}
}
else
{
; /* 不做任何处理,连续发声 */
}
}
else if (g_tBeep.ucState == 1)// 准备要停止发声
{
if (++g_tBeep.usCount >= g_tBeep.usStopTime)
{
/* 连续发声时,直到调用stop停止为止 */
if (g_tBeep.usCycle > 0)
{
if (++g_tBeep.usCycleCount >= g_tBeep.usCycle)
{
/* 循环次数到,停止发声 */
g_tBeep.ucEnalbe = 0;
}
if (g_tBeep.ucEnalbe == 0)
{
g_tBeep.usStopTime = 0;
return;
}
}
g_tBeep.usCount = 0;
g_tBeep.ucState = 0;
BEEP_ENABLE(); /* 开始发声 */
}
}
} 解释一下这段代码
2024-03-07 00:39:55
GPT-3.5
这段代码是一个蜂鸣器控制函数。下面是对代码的解释:
函数名称是 BEEP_Pro,表示蜂鸣器处理函数。
该函数首先进行一系列条件判断,判断蜂鸣器是否允许发声。如果满足以下条件之一,则不进行后续操作,直接返回:
g_tBeep.ucEnable 等于 0,表示蜂鸣器被禁用;
g_tBeep.usStopTime 等于 0,表示停止时间为0,即不发声;
g_tBeep.ucMute 等于 1,表示蜂鸣器被静音。
接下来,根据蜂鸣器的当前状态进行处理:
如果 g_tBeep.ucState 等于 0,表示蜂鸣器当前处于准备开始发声的状态。在这种情况下,代码会根据以下逻辑进行处理:
如果蜂鸣器是间断发声模式(g_tBeep.usStopTime > 0),则判断发声计数器是否达到了设定的发声时间(g_tBeep.usBeepTime)。如果计数器达到了发声时间,则停止发声,设置状态为 1,重置计数器。
如果蜂鸣器是连续发声模式(g_tBeep.usStopTime 等于 0),则不进行任何处理。
如果 g_tBeep.ucState 等于 1,表示蜂鸣器准备要停止发声。在这种情况下,代码会根据以下逻辑进行处理:
判断停止发声计数器是否达到了设定的停止时间(g_tBeep.usStopTime)。如果计数器达到了停止时间,则执行以下操作:
如果蜂鸣器需要循环发声(g_tBeep.usCycle > 0),则判断循环计数器是否达到了设定的循环次数(g_tBeep.usCycle)。如果循环计数器达到了循环次数,则将 g_tBeep.ucEnable 设置为 0,即停止发声。
如果蜂鸣器已经停止发声,则将 g_tBeep.usStopTime 设置为 0,以便在下一次调用时清零,并直接返回。
重置计数器,将状态设置为 0,然后开始发声。
该段代码主要用于控制蜂鸣器的发声和停止发声过程,根据不同的模式(间断发声或连续发声),在合适的时间进行相应的操作。