定时器中断实现蜂鸣器唱歌(延时函数)(定时器)

嵌入式必备能力之蜂鸣器唱歌

本片文章主要参考“江科大自化协”B站内容

主程序 main 

//区别<>和"",<>为系统库,而""为程序员自定义库,需要令创.h文件
//本代码歌曲《天空之城》
#include <REGX52.H>
#include "delayms.h"
#include "timer0.h"

//蜂鸣器端口
sbit buzzer = P1^7;

//播放速度,值为四分音符时长
#define SPEED 500

//音符(若切换音乐,这里不用改)
/*P:休止符
  L:低音
  M:中音
  H:高音
  _:升半音符号
*/
#define P     0
#define L1    1
#define L1_   2
#define L2    3
#define L2_   4
#define L3    5
#define L4    6
#define L4_   7
#define L5    8
#define L5_   9
#define L6    10
#define L6_   11
#define L7    12
#define M1    13
#define M1_   14
#define M2    15
#define M2_   16
#define M3    17
#define M4    18
#define M4_   19
#define M5    20
#define M5_   21
#define M6    22
#define M6_   23
#define M7    24
#define H1    25
#define H1_   26
#define H2    27
#define H2_   28
#define H3    29
#define H4    30
#define H4_   31
#define H5    32
#define H5_   33
#define H6    34
#define H6_   35
#define H7    36

//频率
unsigned int FreqTable[]={
    0,
    63472,63584,63697,63797,63897,63987,64074,64156,64233,64307,64376,64441,
    64502,64560,64615,64667,64715,64761,64805,64846,64885,64921,64956,64989,
    65020,65048,65076,65102,65126,65149,65171,65191,65210,65229,65246,65262
};

//乐谱
unsigned char code Music[]={
    //1
    P,    4,    P,    4,    P,    4,    M6,    2,    M7,    2,
    H1,    4+2,M7,    2,    H1,    4,    H3,    4,
    M7,    4+4+4,        M3,    2,    M3,    2,
    //2
    M6,    4+2,M5,    2,    M6,    4,    H1,    4,
    M5,    4+4+4,        M3,    4,
    M4,    4+2,M3,    2,    M4,    4,     H1,    4,
    //3
    M3,    4+2,P,    2,    H1,    2,    H1,    2,    H1,    2,
    M7,    4+2,M4_,2,    M4_,4,    M7,    4,
    M7,    4+4,P,    4,    M6,    2,    M7,    2,
    //4
    H1, 4+2,M7,    2,    H1,    4,    H3,    4,
    M7,    4+4+4,    M3,    2,    M3,    2,
    M6,    4+2,    M5,    2,    M6,    4, H1,    4,
    //5
    M5,    4+4+4,    M2,    2,    M3,    2,
    M4,    4,    H1,    2,    M7,    2+2,    H1,    2+4,
    H2,    2,    H2,    2,    H3,    2,    H1,    2+4+4,
    //6
    H1,    2,    M7,    2,    M6,    2,    M6,    2,    M7,    4,    M5_,4,
    M6,    4+4+4,    H1,    2,    H2,    2,
    H3,    4+2,H2,    2,    H3,    4,    H5,    4,
    //7
    H2,    4+4+4,    M5,    2,    M5,    2,
    H1,    4+2,    M7,    2,    H1,    4,    H3,    4,
    H3,    4+4+4+4,
    //8
    M6,    2,    M7,    2, H1,    4,    M7,    4,    H2,    2,    H2,    2,
    H1,    4+2,M5,    2+4+4,
    H4,    4,    H3,    4,    H2,    4,    H1,    4,
    //9
    H3,    4+4+4,    H3,    4,
    H6,    4+4,    H5,    4,    H5,    4,
    H3,    2,    H2,    2,    H1,    4+4,    P,    2,    H1,    2,
    //10
    H2,    4,    H1,    2,    H2,    2,    H2,    4,    H5,    4,
    H3,    4+4+4,    H3,    4,
    H6,    4+4,    H5,    4+4,
    //11
    H3,    2,    H2,    2,    H1,    4+4,    P,    2,    H1,    2,
    H2,    4,    H1,    2,    H2,    2+4,    M7,    4,
    M6,    4+4+4,    M6,    2,    M7,    2,
    
    0xFF    //终止符号
};
//主函数
unsigned char FreqSelect,MusicSelect;

void main()
{
    timer0_init();
    while(1)
    {
        if(Music[MusicSelect]!=0xFF)    //如果(不是停止标志位)
        {
            FreqSelect = Music[MusicSelect];    //选择音符对应的频率
            MusicSelect++;
            delayms(SPEED/4*Music[MusicSelect]);    //选择音符对应的时长
            MusicSelect++;
            TR0 = 0;    
            delayms(5);        //音符间短暂停顿
            TR0 = 1;
        }
        else            //如果(是停止标志位)
        {
            TR0 = 0;    //停止播放
            while(1);
        }
    }
}

//中断函数
void timer0_routine() interrupt 1
{
    if(FreqTable[FreqSelect])    //如果(不是休止符)
    {
        /*取对应频率的重装值到定时器*/
        TL0 = FreqTable[FreqSelect]%256;        //设置定时初值
        TH0 = FreqTable[FreqSelect]/256;        //设置定时初值
        buzzer=!buzzer;    //反转蜂鸣器IO口
    }
}

定时器函数   timer0.h

//定时器函数
#ifndef _timer0_h_
#define _timer0_h_

    void timer0_init(void);
    
#endif


#include <REGX52.H>


void timer0_init(void)        //1毫秒@11.0592MHZ
{
    TMOD &= 0xF0;   //设置定时器模式,1111 0000,&,高四位保留,低四位清零
    TMOD |= 0x01;    //设置定时器模式,0000 0001,|,高四位保留,设置模式为T0
    TL0 = 0x66;       //设置定时初始值,1ms,11.0592MHZ
    TH0 = 0xFC;       //设置定时初始值,1ms,11.0592MHZ
    TF0 = 0;        //清楚TF0标志
    TR0 = 1;        //定时器0开始计时
    ET0=1;            //打开定时器T0中断开关
    EA=1;            //打开中断系统总开关
    PT0=0;            //设置T0中断优先级,低
}

延时函数  delayms.h

#include <intrins.h>

void delayms(unsigned int xms)        //@11.0592MHz
{
    unsigned char i, j;

    while(xms--)
    {
        _nop_();
        i = 2;
        j = 199;
        do
        {
            while (--j);
        } while (--i);    
    }
}

·这张图片记录A-I 各种内容,我们可以根据音符来敲出我们想要的音乐代码,并在原代码中稍作改动即可。 

 ·根据音符<——>索引来进行乐谱与代码的转换,此操作仅改变主程序 main中代码即可

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值