OpenEdv-开源电子网

标题: 请问用定时器控制蜂鸣器发出“滴滴“声应该怎么做最好 [打印本页]

作者: ryanwong    时间: 2018-1-23 16:12
标题: 请问用定时器控制蜂鸣器发出“滴滴“声应该怎么做最好


作者: a496298685    时间: 2018-1-23 16:12
本帖最后由 a496298685 于 2018-1-23 16:19 编辑

如果是传统51单片机,自然只能按最常规的思路来。定时器中断,中断服务程序,给蜂鸣器引脚取反。完毕。
当然,如果是STM32这样的东西,可以直接把IO口与定时器绑定,用定时器产生响、不响、响、不响的方波。

以上针对有源蜂鸣器而言。

无源蜂鸣器可以用timer0产生鸣响的方波,用timer1控制响、不响、响、不响。

作者: ryanwong    时间: 2018-1-23 17:58
a496298685 发表于 2018-1-23 16:16
如果是传统51单片机,自然只能按最常规的思路来。定时器中断,中断服务程序,给蜂鸣器引脚取反。完毕。
当 ...

那如果同一个项目中,我要让蜂鸣器可以嘀一声长音,嘀嘀两声,嘀嘀嘀三声,大概框架要怎么写?
作者: a496298685    时间: 2018-1-23 18:17
ryanwong 发表于 2018-1-23 17:58
那如果同一个项目中,我要让蜂鸣器可以嘀一声长音,嘀嘀两声,嘀嘀嘀三声,大概框架要怎么写?

你还没说你用的是什么单片机呢。我现在不知道你的系统资源是什么样的。
作者: ryanwong    时间: 2018-1-23 19:13
a496298685 发表于 2018-1-23 18:17
你还没说你用的是什么单片机呢。我现在不知道你的系统资源是什么样的。

新唐,N76E003,谢谢
作者: a496298685    时间: 2018-1-23 20:17
(, 下载次数: 5)
它是具备16位计数的timer0和timer1的。
我就按你是有源蜂鸣器来说,那么只需要timer0开一个10ms左右的定时器中断。下方是顺手写的一个思路。可以在这个的基础上完善一下。
[mw_shl_code=c,true]uint8_t Beep_times=1;//鸣响次数
#define TermValue 150 //总共鸣响时间恒定为1.5s(10ms*150=1.5s)
void Timer0_ISR(void) interrupt 1 //10ms定时器中断
{
        static uint8_t Current_Beep_times=0;//用于检测鸣响设定是否更新
        static uint8_t Steps=0;//每进入Steps次中断,蜂鸣器电平更改一次
        static uint8_t CountBack_0=0;
        static uint8_t CountBack_1=0;
        if(Current_Beep_times!=Beep_times)//鸣响设定更新
        {
                Buzzer_Pin=Buzzer_OFF;//确保蜂鸣器不会意外常响
               
                Current_Beep_times=Current_Beep_times;//更新鸣响次数
                Steps=TermValue/(2*Current_Beep_times);
                CountBack_0=Steps;//定时中断计数
                CountBack_1=2*Current_Beep_times;//切换次数计数
                if(Current_Beep_times==1)
                {
                        Steps=TermValue;
                        CountBack_1=Current_Beep_times;
                }
        }
        if(CountBack_1)
        {
                if(!CountBack_0--)
                {
                        Buzzer_Pin=~Buzzer_Pin;//蜂鸣器电平取反
                        CountBack_1--;//切换次数计数自减
                        CountBack_0=Steps;//定时中断计数复位
                }
                if(!CountBack_1)
                {
                        Buzzer_Pin=Buzzer_OFF;//确保蜂鸣器不会意外常响
                        Timer0_SwitchOFF();//这是一个用于关掉定时器的函数
        }[/mw_shl_code]

这是示意图。
(, 下载次数: 5)

作者: 神之终结    时间: 2018-1-24 08:33
所有的蜂鸣器都可以直接用单片机的定时器的pwm输出功能控制,有些单片机还自带buzz就是蜂鸣器驱动,只要设置频率就行了。

有源内置震荡电路,你加个电压就会响,无源的没有震荡电路,需要给指定频率的方波,现在基本都用无源的,2根IO口能让蜂鸣器发出动听的和旋音,网上随便搜就有电路和程序
作者: DongInker    时间: 2018-1-24 08:36
本帖最后由 DongInker 于 2018-1-24 08:41 编辑

分享我的蜂鸣器设计代码长叫:SetBeep(1,0,1)
单次:SetBeep(1,5,0) --可以用于按键交互
多次:SetBeep(5,20,30)
连续:SetBeep(0xff,20,30)
根据自己的感觉设置声音的开关时间,去表示相应的事件声音。

作者: ryanwong    时间: 2018-1-24 09:52
a496298685 发表于 2018-1-23 20:17
它是具备16位计数的timer0和timer1的。
我就按你是有源蜂鸣器来说,那么只需要timer0开一个10ms左右的定 ...

谢谢你的解答,不好意思我忘了说,我用的是无源的。你之前提到的思路,我觉得可以,但是好像处理起来不方便啊
作者: a496298685    时间: 2018-1-24 13:52
ryanwong 发表于 2018-1-24 09:52
谢谢你的解答,不好意思我忘了说,我用的是无源的。你之前提到的思路,我觉得可以,但是好像处理起来不方 ...

无源的话也可以很简单地稍作改动。
用Timer1产生方波,用Timer0控制Timer1工作与否。具体操作是完全相同的。

我的实现可能麻烦了一些,但是可以确保音效,每一次响声总用时都是相同的。
作者: HXYDJ    时间: 2018-2-7 16:28
如果偶尔调用一次蜂鸣器可以用延时做,蜂鸣器响,延时,蜂鸣器关。 封装成一个函数,需要的时候调用一下就行了。




欢迎光临 OpenEdv-开源电子网 (http://www.openedv.com/) Powered by Discuz! X3.4