找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5018|回复: 14
收起左侧

无源蜂鸣器阻塞程序,怎样让无源蜂鸣器正常发声且不会影响主程序。

[复制链接]
ID:735365 发表于 2020-5-18 10:32 | 显示全部楼层 |阅读模式
我想用无源蜂鸣器报警,但是无源蜂鸣器太占用时值,导致中断异常。能否有一种方法,让无源蜂鸣器正常发声的同时程序也能正常工作?望大佬指点,先行谢过!

回复

使用道具 举报

ID:548551 发表于 2020-5-18 14:35 | 显示全部楼层
开中断定时器啊.比如,你用T0做主定时, 那么T1做蜂鸣器定时中断啊. 只要有需要蜂鸣器的的时候它自己会去处理.就是这么个道理.
回复

使用道具 举报

ID:735365 发表于 2020-5-18 21:54 | 显示全部楼层
xqleft 发表于 2020-5-18 14:35
开中断定时器啊.比如,你用T0做主定时, 那么T1做蜂鸣器定时中断啊. 只要有需要蜂鸣器的的时候它自己会去处理 ...

你好,我已经开了外部中断和定时器T0,T0是小延时且嵌套按键扫描,我把蜂鸣器写到T0里面,但是无源蜂鸣器太占用时值,影响主程序出错了。现在可以把T0延时拉长一些再试试,但我主要想让无源蜂鸣器一直响且不影响主程序。我再试试,谢谢你的想法。
回复

使用道具 举报

ID:440553 发表于 2020-5-18 22:37 | 显示全部楼层
定时器
回复

使用道具 举报

ID:712493 发表于 2020-5-18 22:47 来自手机 | 显示全部楼层
xqleft 发表于 2020-5-18 14:35
开中断定时器啊.比如,你用T0做主定时, 那么T1做蜂鸣器定时中断啊. 只要有需要蜂鸣器的的时候它自己会去处理 ...

中断会不会太频繁,找有pwm的芯片
回复

使用道具 举报

ID:213173 发表于 2020-5-19 06:46 | 显示全部楼层
BMK达人 发表于 2020-5-18 21:54
你好,我已经开了外部中断和定时器T0,T0是小延时且嵌套按键扫描,我把蜂鸣器写到T0里面,但是无源蜂鸣器 ...

一个定时器可以做N项工作。操作蜂鸣器只占几us,根本不会影响其他程序运行。
void InitTimer0(void)
{
    TMOD = 0x02;//8位自动重装
    TH0 = 0x06; //250us
    TL0 = 0x06;
    EA = 1;
    ET0 = 1;
    TR0 = 1;
}

void Timer0Interrupt(void) interrupt 1
{
        if(sign)//sign控制位
                buzzer=~buzzer;//取反
        else buzzer=0;//复位
        //其它中断任务
}
回复

使用道具 举报

ID:401564 发表于 2020-5-19 09:10 | 显示全部楼层
中断,是单片机的一个重要功能,目的就是要让单片机“同时”去做几个事情,T0或者T1都是一样的,蜂鸣器一般是1KHZ的,如果用中断的话,就是0.5mS进入一次中断,几uS的中断时间,这完全是没有占用多少时间的
如果实在不行,那就用PWM,但打开和关闭PWM也是一样的要时间的呀,不知道你到底是什么程序,对时间要求那么严格
回复

使用道具 举报

ID:548551 发表于 2020-5-19 09:46 | 显示全部楼层
fj51hei 发表于 2020-5-18 22:47
中断会不会太频繁,找有pwm的芯片

不会,中断就是用来干这个的.
回复

使用道具 举报

ID:735365 发表于 2020-5-19 10:36 | 显示全部楼层
xqleft 发表于 2020-5-19 09:46
不会,中断就是用来干这个的.

各位辛苦了,我今天把T1定时器开个小延时,功能正常了。
回复

使用道具 举报

ID:548551 发表于 2020-5-19 10:49 | 显示全部楼层
BMK达人 发表于 2020-5-18 21:54
你好,我已经开了外部中断和定时器T0,T0是小延时且嵌套按键扫描,我把蜂鸣器写到T0里面,但是无源蜂鸣器 ...

玩的51系列对吧? 你现在估计才刚开始接触单片机.记住一个重点,重中之重:不要用delay_延时.不要用delay_延时.不要用delay_延时.
现在给你一个思路,你可以做下参考.
void main (void)
{
        POWER_INITIAL();                                //单片机初始化:IO口输出输入定义;上下拉设置;IO口初始电平;单片机晶振频率选择,晶振频率根据需要选
                                                                //合适的频率.选好之后后面需要用到的都是在选的频率之上计算
        TIME0_INITIAL();                                //定时器初始化设置.这个开中断,设置4MS一次定时中断.后面所有的计数都是在4MS以上进行计算的
                                                                //比如你要延时1秒,直接用变量累加,累加到250次的时候执行你延时1秒之后的程序,没有累加到1S的时候
                                                                //可以执行其它程序,因为delay延时程序是在哪里空跑,其它的程序跑不了,用变量延时,可以跑其它的程序,
                                                                //比如我按键还没有到的时候我可以执行灯里面的程序.
        TIME1_INITIAL();                                //模拟蜂鸣器的定时4K的频率,125US进一次中断,进一次翻转一直蜂鸣器电平,组成一个250US,4K频率的蜂
                                                                //鸣器方波                       
        WTD_INITAL();                                        //看门狗初始化 ,这个我不知道C51系列用到没有但是前面的肯定是用到了
        //开T0 定时器中断                                //这个我没有玩过C51不知道那一段代码
        //开T1 定时器中断                                //
        //开总中断.
        while(1)
        {
                if(F_4MS)
                {
                        F_4MS=0;
                        //清看门狗程序                    //这一段代码是清看门狗的,防止看门狗复位
                        ////////////////////////                //下面是所有程序的子函数,你把子函数模块写好嵌套进去就可以了
                        KEY_SCAN();                        //按键扫描
                        LED_DISPLAY();                        //指示灯
                        PWM_OUT();                        //马达输出
                }
        }
}
因为我不是写C51的.但是我写的都是51内核的.和它差距不大.所以整体上是一个思路.这是出来工作后的思路, 你的那个思路学习可以.但是想要学习好,学习精,你那个思路要把不好的去掉.  因为我没有玩过51,我只看了它的教程,所以不知道定时器怎么配,下面是中断函数处理:
void interrupt(void)
{
        //T0中断处理  
        //这个T0主程序定时的到了之后把4_4MS这个标志位置1;下面while(1)哪里就是靠这个标志位来进入主程序里面的子程序模块
        F_4MS=1;



        //T2处理   模拟蜂鸣器的
        //51的我不知道到了之后有没有标志位什么的,你只需要把下面这个放到T2中断里面去就可以了
        if(F_BELL_WORK)
        {
                P_BELL=!P_BELL;
        }
}
void TIME0_INITIAL(void)
{
        //操作T0定时器中断的寄存器,让它定时为4MS进一次中断
}
void TIME2_INITIAL(void);
{
        //操作T2定时器中断的寄存器,让它定时为125US进一次中断
}

可能写的有点乱. 但是我想这个你应该能看懂
回复

使用道具 举报

ID:695961 发表于 2020-5-19 11:31 | 显示全部楼层
最好找PWM的芯片。

当然,把定时器分开使用也是没有问题的,关键是程序要组织好。
回复

使用道具 举报

ID:695961 发表于 2020-5-19 11:32 | 显示全部楼层
另外,中断优先级要提高一些,这样音乐就不会跑调了。
回复

使用道具 举报

ID:735365 发表于 2020-5-19 12:24 | 显示全部楼层
xqleft 发表于 2020-5-19 10:49
玩的51系列对吧? 你现在估计才刚开始接触单片机.记住一个重点,重中之重:不要用delay_延时.不要用delay_延 ...

是的,注释这么详细,要是看不懂也太不给面子了(接触过32,那些配置有了解)。一个定时器服务其他函数,另一个短延时控制无源蜂鸣器IO反转。收获重点:尽量不用delay这种延时。大哥讲的很好!
回复

使用道具 举报

ID:235954 发表于 2020-5-19 21:57 | 显示全部楼层
定时中断,设置下时间,服务函数里面置下标志位,这样也不占太多程序的时间
回复

使用道具 举报

ID:420836 发表于 2020-5-20 08:08 | 显示全部楼层
如果使用了过多的延迟,则最终会占太多控制时间,应对某些功能使用中断。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表