51单片机 蜂鸣器播放音乐

本文详细介绍了如何在嵌入式系统中使用C语言,如main.c中的代码,通过定时器和中断处理来控制蜂鸣器播放预定义的音乐,涉及到头文件、中断函数和延时函数的使用。

main.c中

#include <REGX52.H>
#include "Delay.h"
#include "Timer0.h"

//蜂鸣器端口定义
sbit Buzzer=P1^5;

//播放速度,值为四分音符的时长(ms)
#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,
    63628,63731,63835,63928,64021,64103,64185,64260,64331,64400,64463,64528,
    64580,64633,64684,64732,64777,64820,64860,64898,64934,64968,65000,65030,
    65058,65085,65110,65134,65157,65178,65198,65217,65235,65252,65268,65283,
};

//乐谱 code,rom可存8k数据,只读不能在主函数修改
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+4,
    P,    2,
    H1,    2,
    H1,    2,
    H1,    2,
    
    M7,    4+2,
    M4_,2,
    M4_,4,
    M7,    4,
    
    M7,    8,
    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,
    H3,    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,
    P,    4,
    
    0xFF    //终止标志
};

unsigned char FreqSelect,MusicSelect;

void main()
{
    Timer0_Init();
    while(1)
    {
        if(Music[MusicSelect]!=0xFF)    //如果不是停止标志位
        {
            FreqSelect=Music[MusicSelect];    //选择音符对应的频率
            MusicSelect++;
            Delay(SPEED/4*Music[MusicSelect]);    //选择音符对应的时值
            MusicSelect++;
            TR0=0;
            Delay(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口
    }
}
delay.c中

void Delay(unsigned int xms)
{
    unsigned char i, j;
    while(xms--)
    {
        i = 2;
        j = 239;
        do
        {
            while (--j);
        } while (--i);
    }
}

delay.h中

#ifndef __DELAY_H__
#define __DELAY_H__

void Delay(unsigned int xms);

#endif

Timer0.c

#include <REGX52.H>

void Timer0_Init()
{
    TMOD &= 0xF0;        //设置定时器模式
    TMOD |= 0x01;        //设置定时器模式
    TL0 = 0x18;        //设置定时初始值
    TH0 = 0xFC;        //设置定时初始值
    TF0 = 0;        //清除TF0标志
    TR0 = 1;        //定时器0开始计时
    ET0=1;
    EA=1;
    PT0=0;
}

/*
定时器中断函数模板,使用时复制到main.c中
void Timer0_Routine() interrupt  1

   static unsigned int T0Count;
   TL0 = 0x18;        //设置定时初始值
   TH0 = 0xFC;
   T0Count++;
   if(T0Count>=1000)
   {
     T0Count=0;
    
   }
  
  
}
*/

Timer0.h中

#ifndef __TIMER0_H__
#define    __TIMER0_H__

void Timer0_Init(void);


#endif

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值