请问怎么把闹钟蜂鸣器的短响换成下面的音乐,我弄的老是会有中断冲突,求救啊

2019-07-15 07:37发布

Desktop.zip (118.13 KB, 下载次数: 6)

#include<reg51.h>
#include"DS18B20.h"
#include"DS1302.h"
#include"LCD1602.h"
#include"BUTTON.h"


//定时器0初始化程序
void init() //定时器、计数器设置函数
{
        TMOD=0x11; //指定定时/计数器的工作方式为1
        TH0=0;  //定时器T0的高四位=0
        TL0=0;  //定时器T0的低四位=0
        EA=1;  //系统允许有开放的中断
        ET0=1; //允许T0中断
        TR0=1; //开启中断,启动定时器
}
//*******************主函数**************************
//***************************************************
void main()
{        
        lcd_init();      //调用液晶屏初始化子函数
        ds1302_init();   //调用DS1302时钟的初始化子函数
        init();          //调用定时计数器的设置子函数
        led=0;           //打开LCD的背光电源
    buzzer=0;//蜂鸣器长响一次
    delay(80);
    buzzer=1;
        while(1)  //无限循环下面的语句:
        {               
            keyscan();      //调用键盘扫描子函数
    }
}
/*************通过定时中断实现定时读出并显示数据******************/
void t0() interrupt 1  //取得并显示日历和时间
{        
           //Init_DS18B20();//温度传感器DS18b20初始化子函数,在头文件中
           flag=ReadTemperature();//将18b2头文件运行返回的函数结果送到变量FLAG中,用于显示
          //读取秒时分周日月年七个数据(DS1302的读寄存器与写寄存器不一样):
        miao=BCD_Decimal(read_1302(0x81));
        fen=BCD_Decimal(read_1302(0x83));
        shi=BCD_Decimal(read_1302(0x85));
        ri=BCD_Decimal(read_1302(0x87));
        yue=BCD_Decimal(read_1302(0x89));
        nian=BCD_Decimal(read_1302(0x8d));
        week=BCD_Decimal(read_1302(0x8b));
        //显示温度、秒、时、分数据:
        write_temp(12,flag);//显示温度,从第二行第12个字符后开始显示
        write_sfm(8,miao);//秒,从第二行第8个字后开始显示(调用时分秒显示子函数)
        write_sfm(5,fen);//分,从第二行第5个字符后开始显示
        write_sfm(2,shi);//小时,从第二行第2个字符后开始显示
        //显示日、月、年数据:
        write_nyr(9,ri);//日期,从第二行第9个字符后开始显示
        write_nyr(6,yue);//月份,从第二行第6个字符后开始显示
        write_nyr(3,nian);//年,从第二行第3个字符后开始显示
        write_week(week-1);
        /***********整点报时程序************/
        if(fen==0&&miao==0)
                if(shi<22&&shi>6 )
                {
                        buzzer=0;//蜂鸣器短响一次
                        delay(20);
                        buzzer=1;
                }
                /**************闹钟程序: 将暂停键按下停止蜂鸣********************/
                if(shi1==shi&&fen1==fen&&miao==0)
                {               
                        clock=1;
                }        
                if(clock==1)
                {
                        buzzer=0;//蜂鸣器短响一次
                        delay(20);
                        buzzer=1;
                }
                if(CLO==0)        /*按下p1.4停止蜂鸣*/
                        clock=0;        
}





<p>#include <reg52.h>

sbit buzzer= P1^3;  //蜂鸣器控制引脚

unsigned int code NoteFrequ[] = {  //中音1-7和高音1-7对应频率列表
    523,  587,  659,  698,  784,  880,  988,  //中音1-7
    1047, 1175, 1319, 1397, 1568, 1760, 1976  //高音1-7
};
unsigned int code NoteReload[] = { //中音1-7和高音1-7对应的定时器重载值
    65536 - (11059200/12) / (523*2),  //中音1
    65536 - (11059200/12) / (587*2),  //2
    65536 - (11059200/12) / (659*2),  //3
    65536 - (11059200/12) / (698*2),  //4
    65536 - (11059200/12) / (784*2),  //5
    65536 - (11059200/12) / (880*2),  //6
    65536 - (11059200/12) / (988*2),  //7
    65536 - (11059200/12) / (1047*2), //高音1
    65536 - (11059200/12) / (1175*2), //2
    65536 - (11059200/12) / (1319*2), //3
    65536 - (11059200/12) / (1397*2), //4
    65536 - (11059200/12) / (1568*2), //5
    65536 - (11059200/12) / (1760*2), //6
    65536 - (11059200/12) / (1976*2), //7
};
bit enable = 1;   //蜂鸣器发声使能标志
bit tmrflag = 0;  //定时器中断完成标志
unsigned char T0RH = 0xFF;  //T0重载值的高字节
unsigned char T0RL = 0x00;  //T0重载值的低字节

void PlayTwotiger();

void main()
{
    unsigned int i;

    EA = 1;       //使能全局中断
    TMOD = 0x01;  //配置T0工作在模式1
    TH0 = T0RH;
    TL0 = T0RL;
    ET0 = 1;      //使能T0中断
    TR0 = 1;      //启动T0

    while (1)
    {
        PlayTwoTiger();  //播放乐曲--两支老虎
        for (i=0; i<40000; i++);  //停止一段时间
    }
}
/* 两支老虎乐曲播放函数 */
void PlayTwoTiger()
{
    unsigned char beat;   //当前节拍索引
    unsigned char note;   //当前节拍对应的音符
    unsigned int time = 0;      //当前节拍计时
    unsigned int beatTime = 0;  //当前节拍总时间
    unsigned int soundTime = 0; //当前节拍需发声时间
    //两只老虎音符表
    unsigned char code TwoTigerNote[] = {
        1,   2,   3, 1,    1,   2,   3, 1,   3, 4, 5,   3, 4, 5,
        5,6, 5,4, 3, 1,    5,6, 5,4, 3, 1,   1, 5, 1,   1, 5, 1,
    };
    //两只老虎节拍表,4表示一拍,1就是1/4拍,8就是2拍
    unsigned char code TwoTigerBeat[] = {
        4,   4,   4, 4,    4,   4,   4, 4,   4, 4, 8,   4, 4, 8,
        3,1, 3,1, 4, 4,    3,1, 3,1, 4, 4,   4, 4, 8,   4, 4, 8,
    };

    for (beat=0; beat<sizeof(TwoTigerNote); )  //用节拍索引作为循环变量
    {
        while (!tmrflag);  //每次定时器中断完成后,检测并处理节拍
        tmrflag = 0;
        if (time == 0)  //当前节拍播完则启动一个新节拍
        {
            note = TwoTigerNote[beat] - 1;
            T0RH = NoteReload[note] >> 8;
            T0RL = NoteReload[note];
            //计算节拍总时间,右移2位相当于除4,移位代替除法可以加快执行速度
            beatTime = (TwoTigerBeat[beat] * NoteFrequ[note]) >> 2;
            //计算发声时间,为总时间的0.75,移位原理同上
            soundTime = beatTime - (beatTime >> 2);
            enable = 1;  //指示蜂鸣器开始发声
            time++;
        }
        else  //当前节拍未播完则处理当前节拍
        {
            if (time >= beatTime)  //当前持续时间到达节拍总时间时归零,
            {                      //并递增节拍索引,以准备启动新节拍
                time = 0;
                beat++;
            }
            else  //当前持续时间未达到总时间时,
            {
                time++;   //累加时间计数
                if (time == soundTime)  //到达发声时间后,指示关闭蜂鸣器,
                {                       //插入0.25*总时间的静音间隔,
                    enable = 0;         //用以区分连续的两个节拍
                }
            }
        }
    }
}
/* T0中断服务函数,用于控制蜂鸣器发声 */
void InterruptTimer0() interrupt 1
{
    TH0 = T0RH;   //重新加载重载值
    TL0 = T0RL;
    tmrflag = 1;
    if (enable)   //使能时反转蜂鸣器控制电平
        buzzer= ~buzzer;
    else          //未使能时关闭蜂鸣器
        buzzer= 1;
}



0条回答

一周热门 更多>