该框架主要工作4中模式
- 鸣叫1声
- 鸣叫2声
- 鸣叫3声
- 一直叫
核心代码
H头文件
#ifndef __BEEP_H__
#define __BEEP_H__
#include <stdint.h>
#define TIME 100
typedef enum
{
MD_NULL,
MD_CLOSE, //关闭蜂鸣器模式
MD_ONE, //响1声
MD_TWO, //响2声
MD_THREE, //响3声
MD_CONTINUE, //一直响
} mode_t;
typedef void (*control_beep)(uint8_t lvt);
typedef struct _beep
{
//蜂鸣器激活电平
uint8_t active_lev;
//最后一次蜂鸣器状态,程序内部使用
uint8_t last_sta;
//蜂鸣器打开时间
uint32_t start_time;
//蜂鸣器工作模式 见 mode_t
mode_t mode;
// 蜂鸣器控制回调函数
control_beep ctrl;
// 形成蜂鸣器链表内部使用
struct _beep *next;
} beep_t;
/*
打开蜂鸣器
pbeep 被打开的蜂鸣器
md 打开方式
tick 当前时间戳
*/
void beep_open(beep_t *pbeep, mode_t md, uint32_t tick);
/*
关闭蜂鸣器
pbeep 被关闭的蜂鸣器
*/
void beep_cloe(beep_t *pbeep);
/*
注册一个蜂鸣器
pbeep 代注册的蜂鸣器指针句柄
ctrl 蜂鸣器控制回调函数
acive 蜂鸣器的激活电平
*/
void beep_register(
beep_t *pbeep,
control_beep ctrl,
uint8_t acive);
/*
需要被循环调用的事件循环
tick 传入当前最新时间戳
*/
void beep_process(uint32_t tick);
#endif
C实现代码
#include "beep.h"
#include "main.h"
#include <stdio.h>
#include <stdint.h>
static beep_t *head = NULL;
/*
注册一个蜂鸣器
pbeep 代注册的蜂鸣器指针句柄
ctrl 蜂鸣器控制回调函数
acive 蜂鸣器的激活电平
*/
void beep_register(beep_t *pbeep, control_beep ctrl, uint8_t active)
{
if (pbeep == NULL)
{
printf("%s %d beep is nullptr\r\n", __FILE__, __LINE__);
}
pbeep->active_lev = active;
pbeep->ctrl = ctrl;
pbeep->next = head;
pbeep->mode = MD_CLOSE;
head = pbeep;
printf("%s %d register beep\r\n", __FILE__, __LINE__);
}
/*
打开蜂鸣器
pbeep 被打开的蜂鸣器
md 打开方式
tick 当前时间戳
*/
void beep_open(beep_t *pbeep, mode_t md, uint32_t tick)
{
beep_t *cur = head;
while (cur)
{
if (cur == pbeep)
{
break;
}
cur = cur->next;
}
if (cur)
{
cur->start_time = tick;
cur->last_sta = !cur->active_lev;
cur->mode = md;
}
printf("%s %d open mode %d\r\n", __FILE__, __LINE__, md);
}
/*
关闭蜂鸣器
pbeep 被关闭的蜂鸣器
*/
void beep_cloe(beep_t *pbeep)
{
beep_t *cur = head;
while (cur)
{
if (cur == pbeep)
{
break;
}
cur = cur->next;
}
if (cur)
{
cur->ctrl(!cur->active_lev);
}
}
/*
控制蜂鸣器鸣叫一次
cur 被控蜂鸣器指针
tick 当前时间戳
*/
static uint32_t exec_beep_once(beep_t *cur, uint32_t tick)
{
volatile uint32_t sub = 0;
uint8_t dest_sta;
uint8_t flag = 0;
sub = tick - cur->start_time;
if (sub < TIME)
{
dest_sta = cur->active_lev;
flag = 1;
}
else if (sub >= TIME)
{
dest_sta = !cur->active_lev;
flag = 1;
}
if (dest_sta != cur->last_sta && flag)
{
flag = 0;
cur->ctrl(dest_sta);
cur->last_sta = dest_sta;
}
if (sub > 2 * TIME)
{
return 1;
}
else
{
return 0;
}
}
/*
需要被循环调用的事件循环
tick 传入当前最新时间戳
*/
void beep_process(uint32_t tick)
{
beep_t *cur = head;
while (cur)
{
switch (cur->mode)
{
case MD_CLOSE:
cur->ctrl(!cur->active_lev);
cur->mode = MD_NULL;
break;
case MD_ONE:
if (exec_beep_once(cur, tick))
{
cur->mode = MD_CLOSE;
}
break;
case MD_TWO:
if (exec_beep_once(cur, tick))
{
cur->mode = MD_ONE;
cur->start_time = tick;
}
break;
case MD_THREE:
if (exec_beep_once(cur, tick))
{
cur->mode = MD_TWO;
cur->start_time = tick;
}
break;
case MD_CONTINUE:
cur->ctrl(cur->active_lev);
cur->mode = MD_NULL;
break;
default:
break;
}
cur = cur->next;
}
}
使用框架示例代码
H文件
#ifndef __HB_BEEP_H__
#define __HB_BEEP_H__
#include "beep.h"
#include "main.h"
#include "sys.h"
#define BEEP PCout(3)
/*
初始化蜂鸣器
*/
void init_beep(void);
/*
蜂鸣器循环调用的进程
*/
void process_beep(uint32_t tick);
/*
打开蜂鸣器 开发方式有 1,2,3 种方式
*/
void open_beep(uint32_t tick, mode_t mode);
/*
打开蜂鸣器 开发方式有 1,2,3 种方式
*/
void close_beep(void);
#endif
C文件
#include "hb_beep.h"
#include "stdio.h"
static beep_t s_beep;
static void control_beep_status(uint8_t lvt)
{
BEEP = lvt;
//HAL_GPIO_WritePin(BEEP_GPIO_Port, BEEP_Pin);
}
/*
初始化蜂鸣器
*/
void init_beep(void)
{
beep_register(&s_beep, control_beep_status, 1);
}
/*
蜂鸣器循环调用的进程
*/
void process_beep(uint32_t tick)
{
beep_process(tick);
}
/*
打开蜂鸣器 开发方式有 1,2,3 种方式
*/
void open_beep(uint32_t tick, mode_t mode)
{
beep_open(&s_beep, mode, tick);
}
/*
打开蜂鸣器 开发方式有 1,2,3 种方式
*/
void close_beep()
{
beep_cloe(&s_beep);
}
使用方法
- 主函数调用
init_beep();
- 定时器调用
process_beep(时间戳);
- 需要使用时打开定时器
open_beep(开启模式,时间戳)