[蜂鸣器不简单]单片机中蜂鸣器的多种运用(长响,短响,多次响)
2015-07-15 14:02
477 查看
在一般的单片机教材中,对蜂鸣器的使用都有简单的说明。这里就详细展开不同蜂鸣器,不同芯片的蜂鸣器写法了。
不过,在开发项目的时候发现,教材中的蜂鸣器使用存在很大的局限。
在教材中,对于蜂鸣器的长短都是用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;
二,蜂鸣器开
/************************************************************************/
/* 功能:蜂鸣器响
* 描述:
* 形参:开启的持续时间,关闭的持续时间(响一次随意),响次数(>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--; //蜂鸣器周期
不过,在开发项目的时候发现,教材中的蜂鸣器使用存在很大的局限。
在教材中,对于蜂鸣器的长短都是用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--; //蜂鸣器周期
相关文章推荐
- Lua和C语言的交互详解
- 关于C语言中参数的传值问题
- 深入C++中API的问题详解
- 基于C语言string函数的详解
- C语言内存对齐实例详解
- c语言实现的带通配符匹配算法
- C语言实现顺序表基本操作汇总
- 探讨C语言的那些小秘密之断言
- 深入探讨C语言中局部变量与全局变量在内存中的存放位置
- C语言泛型编程实例教程
- C语言中使用lex统计文本文件字符数
- C语言进制转换代码分享
- 基于C语言fflush()函数的使用详解
- C语言单链队列的表示与实现实例详解
- 关于C语言除0引发的思考
- 深入分析C中不安全的sprintf与strcpy
- Lua教程(四):在Lua中调用C语言、C++的函数
- C语言求幂计算的高效解法
- C语言实现输入一颗二元查找树并将该树转换为它的镜像
- 12个关于C语言的有趣问答