[蜂鸣器不简单]单片机中蜂鸣器的多种运用(长响,短响,多次响)

传统的单片机蜂鸣器控制常使用delay导致CPU资源浪费和时间错乱。本文深入探讨如何通过独立的开/关函数实现蜂鸣器的长响、短响及间隔响功能,利用局部和全局变量控制次数和时间,并结合定时器进行优化,提高系统效率。

在一般的单片机教材中,对蜂鸣器的使用都有简单的说明。这里就详细展开不同蜂鸣器,不同芯片的蜂鸣器写法了。

不过,在开发项目的时候发现,教材中的蜂鸣器使用存在很大的局限。


在教材中,对于蜂鸣器的长短都是用delay这种忙循环来控制的,但实际中,这种函数不仅对CPU资源有极大浪费,而且会延后其他函数的运行,如果有些时间相关的函数,会造成时间错乱。

此外在蜂鸣器响的过程中,不能进行除了中断之外的任何操作。严格来说,除了主函数是无限循环外,其他的任何对CPU空转的忙循环必须小心使用,而且时间不能过长。一般来说,毫秒级别的忙循环已经是不能容忍了。

另外,这种写法不能灵活的配置长响短响,每隔一定时间响几下等高级功能。


不过经过查阅发现,蜂鸣器的开和关是两个不同的过程。

因此我的实现了蜂鸣器开/关两个函数和配套的其他相关函数。

蜂鸣器开函数的作用是开蜂鸣器,设置时间(长响,短响,中响),设置次数。

蜂鸣器关函数的作用是查询开函数的设置量,决定什么时候关蜂鸣器,什么时候再次开蜂鸣器,什么时候不再开蜂鸣器。

局部全局变量控制次数,定时器全局变量控制时间。

看上面的描述可以确定开函数是随意使用的,而关函数却必须在主函数中不断的循环查询设置量。


下面是函数示例。

一,必要的初始化

//////////////////蜂鸣器时长变量声明/////////////////////
typedef enum 			//开启时间
{
  	BEEP_SHORT  = SEC_01,			//100ms
  	BEEP_MIDDLE = SEC_03,			//300ms
  	BEEP_LONG   = SEC_04  			//400ms
} BEEP_LAST;
typedef enum 		//关闭间隔
{
	BEEP_FAST = SEC_03,
	BEEP_SLOW = SEC_05
} BEEP_SHUT;

static uint8_t		tmp_beep_cnt;				//蜂鸣器计数临时存储
static BEEP_LAST	tmp_beep_on;				//蜂鸣器开启临时存储
static BEEP_SHUT	tmp_beep_period;			//蜂鸣器周期临时存储

二,蜂鸣器开

/************************************************************************/
/* 功能:蜂鸣器响
 * 描述:
 * 形参:开启的持续时间,关闭的持续时间(响一次随意),响次数(>0)
 * 返回:
 * 注意:次数不能写0                             */
/************************************************************************/
void beep_on(BEEP_LAST last, BEEP_SHUT off, uint8_t times)
{
	BEEP_CSR |=1<<5;					//开启蜂鸣器
	freq.beep_on  	 = last;			//响持续
	freq.beep_period = last + off;		//一次开和关的周期

	tmp_beep_on 	= last;
	tmp_beep_period = last + off;
	if(times > 0)
		tmp_beep_cnt = times - 1;
	else
		tmp_beep_cnt = 0;
}

三,蜂鸣器关

/************************************************************************/
/* 功能:蜂鸣器关闭
 * 描述:检测时间flag,为0时关闭,同时将次数减1
 * 形参:
 * 返回:
 * 注意:这是主循环里面的                             */
/************************************************************************/
void beep_off(void)
{
	if (freq.beep_on == 0)				//如果持续时间到了,关闭
	{
		BEEP_CSR &=~(1<<5);				//关闭
		if (tmp_beep_cnt)				//蜂鸣器关闭,但是次数还有,等待条件满足重新打开
		{
			if (freq.beep_period == 0)		//蜂鸣器周期已到
			{
				BEEP_CSR |=1<<5;						//打开蜂鸣器
				freq.beep_on  = tmp_beep_on;			//赋值上一次持续时间
				freq.beep_off = tmp_beep_period;		//蜂鸣器周期重新计数				
				s_beep_cnt--;							//次数减1
			}
		}
	}

}

四,定时器处理,10ms中断一次。

	/*蜂鸣器相关定时*/
	if (freq.beep_on)
		freq.beep_on--;			//蜂鸣器开的持续时间
	if(freq.beep_period)
		freq.beep_period--;		//蜂鸣器周期


评论 10
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值