找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3737|回复: 3
打印 上一主题 下一主题
收起左侧

求指导:51单片机怎么用PWM控制蜂鸣器放歌?

[复制链接]
跳转到指定楼层
楼主
ID:566584 发表于 2020-6-13 21:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
50黑币
对着自己的有源蜂鸣器拿程序研究半天,才知道有源音调改不了头都大了
PWM控制调节占空比可以设置音量大小,调节频率可以调节音调
用延时函数模拟PWM来做比较好?还是通过配置定时器中断,利用中断函数进行PWM输出波形的切换?
又怎么包装函数让波形自动变化放歌呢?

希望大佬们能给我讲讲(最好对着程序讲),谢谢


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:491577 发表于 2020-6-13 23:14 | 只看该作者
有源蜂鸣器只能够发出固定的声音,要播放音乐需要使用无源蜂鸣器。不需要用到PWM功能,用定时器就可以了。给你一个参考程序:
/************************************************************************  
[文件名]  C51音乐程序(八月桂花)  
[功能]    通过单片机演奏音乐  
  
/**********************************************************************/   
#include <REG52.H>   
#include <INTRINS.H>   
//本例采用89C52, 晶振为12MHZ   
//关于如何编制音乐代码, 其实十分简单,各位可以看以下代码.   
//频率常数即音乐术语中的音调,而节拍常数即音乐术语中的多少拍;   
//所以拿出谱子, 试探编吧!   

sbit Beep =  P1^5;
   
unsigned char n=0;  //n为节拍常数变量   
unsigned char code music_tab[] ={   
0x18, 0x30, 0x1C , 0x10, //格式为: 频率常数, 节拍常数, 频率常数, 节拍常数,   
0x20, 0x40, 0x1C , 0x10,   
0x18, 0x10, 0x20 , 0x10,   
0x1C, 0x10, 0x18 , 0x40,   
0x1C, 0x20, 0x20 , 0x20,   
0x1C, 0x20, 0x18 , 0x20,   
0x20, 0x80, 0xFF , 0x20,   
0x30, 0x1C, 0x10 , 0x18,   
0x20, 0x15, 0x20 , 0x1C,   
0x20, 0x20, 0x20 , 0x26,   
0x40, 0x20, 0x20 , 0x2B,   
0x20, 0x26, 0x20 , 0x20,   
0x20, 0x30, 0x80 , 0xFF,   
0x20, 0x20, 0x1C , 0x10,   
0x18, 0x10, 0x20 , 0x20,   
0x26, 0x20, 0x2B , 0x20,   
0x30, 0x20, 0x2B , 0x40,   
0x20, 0x20, 0x1C , 0x10,   
0x18, 0x10, 0x20 , 0x20,   
0x26, 0x20, 0x2B , 0x20,   
0x30, 0x20, 0x2B , 0x40,   
0x20, 0x30, 0x1C , 0x10,   
0x18, 0x20, 0x15 , 0x20,   
0x1C, 0x20, 0x20 , 0x20,   
0x26, 0x40, 0x20 , 0x20,   
0x2B, 0x20, 0x26 , 0x20,   
0x20, 0x20, 0x30 , 0x80,   
0x20, 0x30, 0x1C , 0x10,   
0x20, 0x10, 0x1C , 0x10,   
0x20, 0x20, 0x26 , 0x20,   
0x2B, 0x20, 0x30 , 0x20,   
0x2B, 0x40, 0x20 , 0x15,   
0x1F, 0x05, 0x20 , 0x10,   
0x1C, 0x10, 0x20 , 0x20,   
0x26, 0x20, 0x2B , 0x20,   
0x30, 0x20, 0x2B , 0x40,   
0x20, 0x30, 0x1C , 0x10,   
0x18, 0x20, 0x15 , 0x20,   
0x1C, 0x20, 0x20 , 0x20,   
0x26, 0x40, 0x20 , 0x20,   
0x2B, 0x20, 0x26 , 0x20,   
0x20, 0x20, 0x30 , 0x30,   
0x20, 0x30, 0x1C , 0x10,   
0x18, 0x40, 0x1C , 0x20,   
0x20, 0x20, 0x26 , 0x40,   
0x13, 0x60, 0x18 , 0x20,   
0x15, 0x40, 0x13 , 0x40,   
0x18, 0x80, 0x00   
};   
   
void int0()  interrupt 1   //采用中断0 控制节拍   
{  TH0=0xd8;   
   TL0=0xef;   
   n--;   
}   
   
void delay (unsigned char m)   //控制频率延时   
{   
unsigned i=3*m;   
while(--i);   
}   
   
void delayms(unsigned char a)  //豪秒延时子程序   
{   
  while(--a);                  //采用while(--a) 不要采用while(a--); 各位可编译一下看看汇编结果就知道了!   
}   
   
void main()   
{ unsigned char p,m;   //m为频率常数变量   
  unsigned char i=0;   
  TMOD&=0x0f;   
  TMOD|=0x01;   
  TH0=0xd8;TL0=0xef;   
  IE=0x82;   
play:   
   while(1)   
    {   
    a: p=music_tab[i];   
       if(p==0x00)       { i=0, delayms(1000); goto play;}     //如果碰到结束符,延时1秒,回到开始再来一遍   
       else if(p==0xff)  { i=i+1;delayms(100),TR0=0; goto a;}  //若碰到休止符,延时100ms,继续取下一音符   
            else         {m=music_tab[i++], n=music_tab[i++];}  //取频率常数 和 节拍常数   
             TR0=1;                                             //开定时器1   
           while(n!=0) Beep=~Beep,delay(m);                         //等待节拍完成, 通过P1口输出音频(可多声道哦!)   
       TR0=0;                                             //关定时器1   
    }   
}  
回复

使用道具 举报

板凳
ID:491577 发表于 2020-6-13 23:27 | 只看该作者
再发一个详细一点的:
SoundPlay.h文件:
/**************************************************************************
   
                                             SOUND PLAY FOR 51MCU
  
                               COPYRIGHT (c)   2005 BY JJJ.
                                       --  ALL RIGHTS RESERVED  --
  
   File Name:       SoundPlay.h
   Author:          Jiang Jian Jun
   Created:         2005/5/16
   Modified:                NO
   Revision:                 1.0
  
*******************************************************************************/

/*说明**************************************************************************
曲谱存贮格式 unsigned char code MusicName{音高,音长,音高,音长...., 0,0};        末尾:0,0 表示结束(Important)

音高由三位数字组成:
                个位是表示 1~7 这七个音符
                十位是表示音符所在的音区:1-低音,2-中音,3-高音;
                百位表示这个音符是否要升半音: 0-不升,1-升半音。

音长最多由三位数字组成:
                个位表示音符的时值,其对应关系是:
                        |数值(n):  |0 |1 |2 |3 | 4 | 5 | 6
                        |几分音符: |1 |2 |4 |8 |16 |32 |64                 音符=2^n
                十位表示音符的演奏效果(0-2):  0-普通,1-连音,2-顿音
                百位是符点位: 0-无符点,1-有符点

调用演奏子程序的格式
                Play(乐曲名,调号,升降八度,演奏速度);
        |乐曲名           : 要播放的乐曲指针,结尾以(0,0)结束;
        |调号(0-11)       :        是指乐曲升多少个半音演奏;
        |升降八度(1-3)          : 1:降八度, 2:不升不降, 3:升八度;
        |演奏速度(1-12000):        值越大速度越快;

***************************************************************************/
#ifndef __SOUNDPLAY_H_REVISION_FIRST__
#define __SOUNDPLAY_H_REVISION_FIRST__

//**************************************************************************
#include"music.h"

#define SYSTEM_OSC                 12000000        //定义晶振频率12000000HZ
#define SOUND_SPACE         4/5                 //定义普通音符演奏的长度分率,//每4分音符间隔
sbit    BeepIO    =           P1^5;                //定义输出管脚
unsigned char value=0;
unsigned int  code FreTab[12]  = { 262,277,294,311,330,349,369,392,415,440,466,494 }; //原始频率表
unsigned char code SignTab[7]  = { 0,2,4,5,7,9,11 };                                                                   //1~7在频率表中的位置
unsigned char code LengthTab[7]= { 1,2,4,8,16,32,64 };                                               
unsigned char Sound_Temp_TH0,Sound_Temp_TL0;        //音符定时器初值暂存
unsigned char Sound_Temp_TH1,Sound_Temp_TL1;        //音长定时器初值暂存
//**************************************************************************
void InitialSound(void)
{
        BeepIO = 0;
        Sound_Temp_TH1 = (65535-(1/1200)*SYSTEM_OSC)/256;        // 计算TL1应装入的初值         (10ms的初装值)
        Sound_Temp_TL1 = (65535-(1/1200)*SYSTEM_OSC)%256;        // 计算TH1应装入的初值
        TH1 = Sound_Temp_TH1;
        TL1 = Sound_Temp_TL1;
        TMOD  |= 0x11;
        ET0    = 1;
        ET1           = 0;
        TR0           = 0;
        TR1    = 0;
        EA     = 1;
}

void BeepTimer0(void) interrupt 1        //音符发生中断
{
        static unsigned char i;
        BeepIO = !BeepIO;
        TH0    = Sound_Temp_TH0;
        TL0    = Sound_Temp_TL0;
        i++;
        if(i==100)
        {
                i=0;
                value++;
                if(value==5)value=0;
        }

}
//**************************************************************************
void Play(unsigned char *Sound,unsigned char Signature,unsigned Octachord,unsigned int Speed)
{
        unsigned int NewFreTab[12];                //新的频率表
        unsigned char i,j;
        unsigned int Point,LDiv,LDiv0,LDiv1,LDiv2,LDiv4,CurrentFre,Temp_T,SoundLength;
        unsigned char Tone,Length,SL,SH,SM,SLen,XG,FD;
        for(i=0;i<12;i++)                                 // 根据调号及升降八度来生成新的频率表
        {
                j = i + Signature;
                if(j > 11)
                {
                        j = j-12;
                        NewFreTab[i] = FreTab[j]*2;
                }
                else
                        NewFreTab[i] = FreTab[j];

                if(Octachord == 1)
                        NewFreTab[i]>>=2;
                else if(Octachord == 3)
                        NewFreTab[i]<<=2;
        }                                                                       
       
        SoundLength = 0;
        while(Sound[SoundLength] != 0x00)        //计算歌曲长度
        {
                SoundLength+=2;
        }

        Point = 0;
        Tone   = Sound[Point];       
        Length = Sound[Point+1];                         // 读出第一个音符和它时时值
       
        LDiv0 = 12000/Speed;                                // 算出1分音符的长度(几个10ms)        
        LDiv4 = LDiv0/4;                                         // 算出4分音符的长度
        LDiv4 = LDiv4-LDiv4*SOUND_SPACE;         // 普通音最长间隔标准
        TR0          = 0;
        TR1   = 1;
        while(Point < SoundLength)
        {
                SL=Tone%10;                                                                 //计算出音符
                SM=Tone/10%10;                                                                 //计算出高低音
                SH=Tone/100;                                                                 //计算出是否升半
                CurrentFre = NewFreTab[SignTab[SL-1]+SH];         //查出对应音符的频率        
                if(SL!=0)
                {
                        if (SM==1) CurrentFre >>= 2;                 //低音
                        if (SM==3) CurrentFre <<= 2;                 //高音
                        Temp_T = 65536-(50000/CurrentFre)*10/(12000000/SYSTEM_OSC);//计算计数器初值
                        Sound_Temp_TH0 = Temp_T/256;
                        Sound_Temp_TL0 = Temp_T%256;
                        TH0 = Sound_Temp_TH0;  
                        TL0 = Sound_Temp_TL0 + 12; //加12是对中断延时的补偿
                }
                SLen=LengthTab[Length%10];         //算出是几分音符
                XG=Length/10%10;                         //算出音符类型(0普通1连音2顿音)
                FD=Length/100;
                LDiv=LDiv0/SLen;                         //算出连音音符演奏的长度(多少个10ms)
                if (FD==1)
                        LDiv=LDiv+LDiv/2;
                if(XG!=1)       
                        if(XG==0)                                 //算出普通音符的演奏长度
                                if (SLen<=4)       
                                        LDiv1=LDiv-LDiv4;
                                else
                                        LDiv1=LDiv*SOUND_SPACE;
                        else
                                LDiv1=LDiv/2;                 //算出顿音的演奏长度
                else
                        LDiv1=LDiv;
                if(SL==0) LDiv1=0;
                        LDiv2=LDiv-LDiv1;                 //算出不发音的长度
                  if (SL!=0)
                {
                        TR0=1;
                        for(i=LDiv1;i>0;i--)         //发规定长度的音
                        {
                                while(TF1==0);
                                TH1 = Sound_Temp_TH1;
                                TL1 = Sound_Temp_TL1;
                                TF1=0;
                        }
                }
                if(LDiv2!=0)
                {
                        TR0=0; BeepIO=0;
                        for(i=LDiv2;i>0;i--)         //音符间的间隔
                        {
                                while(TF1==0);
                                TH1 = Sound_Temp_TH1;
                                TL1 = Sound_Temp_TL1;
                                TF1=0;
                        }
                }
                Point+=2;
                Tone=Sound[Point];
                Length=Sound[Point+1];
        }
        BeepIO = 0;
}
//**************************************************************************
#endif

main.c文件:

#include "reg52.h"                         //此文件中定义了单片机的一些特殊功能寄存器
#include "SoundPlay.h"
#include"music.h"

typedef unsigned int u16;          //对数据类型进行声明定义
typedef unsigned char u8;



void Delay1ms(unsigned int count)
{
        unsigned int i,j;
        for(i=0;i<count;i++)
        for(j=0;j<120;j++);
}

void main()
{
        InitialSound();
        while(1)
        {
                Play(Music_Girl,0,3,360);
               
                Delay1ms(500);
                Play(Music_Same,0,3,360);
                Delay1ms(500);
                Play(Music_Two,0,3,360);
                Delay1ms(500);
        }
}

music.h文件:
#ifndef __MUSIC_H__
#define __MUSIC_H__
//*****************************Music******************************************************
//挥着翅膀的女孩
unsigned char code Music_Girl[]={ 0x17,0x02, 0x17,0x03, 0x18,0x03, 0x19,0x02, 0x15,0x03,
                                  0x16,0x03, 0x17,0x03, 0x17,0x03, 0x17,0x03, 0x18,0x03,
                                  0x19,0x02, 0x16,0x03, 0x17,0x03, 0x18,0x02, 0x18,0x03,
                                  0x17,0x03, 0x15,0x02, 0x18,0x03, 0x17,0x03, 0x18,0x02,
                                  0x10,0x03, 0x15,0x03, 0x16,0x02, 0x15,0x03, 0x16,0x03,
                                  0x17,0x02, 0x17,0x03, 0x18,0x03, 0x19,0x02, 0x1A,0x03,
                                  0x1B,0x03, 0x1F,0x03, 0x1F,0x03, 0x17,0x03, 0x18,0x03,
                                  0x19,0x02, 0x16,0x03, 0x17,0x03, 0x18,0x03, 0x17,0x03,
                                  0x18,0x03, 0x1F,0x03, 0x1F,0x02, 0x16,0x03, 0x17,0x03,
                                  0x18,0x03, 0x17,0x03, 0x18,0x03, 0x20,0x03, 0x20,0x02,
                                  0x1F,0x03, 0x1B,0x03, 0x1F,0x66, 0x20,0x03, 0x21,0x03,
                                  0x20,0x03, 0x1F,0x03, 0x1B,0x03, 0x1F,0x66, 0x1F,0x03,
                                  0x1B,0x03, 0x19,0x03, 0x19,0x03, 0x15,0x03, 0x1A,0x66,
                                  0x1A,0x03, 0x19,0x03, 0x15,0x03, 0x15,0x03, 0x17,0x03,
                                  0x16,0x66, 0x17,0x04, 0x18,0x04, 0x18,0x03, 0x19,0x03,
                                  0x1F,0x03, 0x1B,0x03, 0x1F,0x66, 0x20,0x03, 0x21,0x03,
                                  0x20,0x03, 0x1F,0x03, 0x1B,0x03, 0x1F,0x66, 0x1F,0x03,
                                  0x1B,0x03, 0x19,0x03, 0x19,0x03, 0x15,0x03, 0x1A,0x66,
                                  0x1A,0x03, 0x19,0x03, 0x19,0x03, 0x1F,0x03, 0x1B,0x03,
                                  0x1F,0x00, 0x1A,0x03, 0x1A,0x03, 0x1A,0x03, 0x1B,0x03,
                                  0x1B,0x03, 0x1A,0x03, 0x19,0x03, 0x19,0x02, 0x17,0x03,
                                  0x15,0x17, 0x15,0x03, 0x16,0x03, 0x17,0x03, 0x18,0x03,
                                  0x17,0x04, 0x18,0x0E, 0x18,0x03, 0x17,0x04, 0x18,0x0E,
                                  0x18,0x66, 0x17,0x03, 0x18,0x03, 0x17,0x03, 0x18,0x03,
                                  0x20,0x03, 0x20,0x02, 0x1F,0x03, 0x1B,0x03, 0x1F,0x66,
                                  0x20,0x03, 0x21,0x03, 0x20,0x03, 0x1F,0x03, 0x1B,0x03,
                                  0x1F,0x66, 0x1F,0x04, 0x1B,0x0E, 0x1B,0x03, 0x19,0x03,
                                  0x19,0x03, 0x15,0x03, 0x1A,0x66, 0x1A,0x03, 0x19,0x03,
                                  0x15,0x03, 0x15,0x03, 0x17,0x03, 0x16,0x66, 0x17,0x04,
                                  0x18,0x04, 0x18,0x03, 0x19,0x03, 0x1F,0x03, 0x1B,0x03,
                                  0x1F,0x66, 0x20,0x03, 0x21,0x03, 0x20,0x03, 0x1F,0x03,
                                  0x1B,0x03, 0x1F,0x66, 0x1F,0x03, 0x1B,0x03, 0x19,0x03,
                                  0x19,0x03, 0x15,0x03, 0x1A,0x66, 0x1A,0x03, 0x19,0x03,
                                  0x19,0x03, 0x1F,0x03, 0x1B,0x03, 0x1F,0x00, 0x18,0x02,
                                  0x18,0x03, 0x1A,0x03, 0x19,0x0D, 0x15,0x03, 0x15,0x02,
                                  0x18,0x66, 0x16,0x02, 0x17,0x02, 0x15,0x00, 0x00,0x00};
//同一首歌
const unsigned char code Music_Same[]={ 0x0F,0x01, 0x15,0x02, 0x16,0x02, 0x17,0x66, 0x18,0x03,
                                  0x17,0x02, 0x15,0x02, 0x16,0x01, 0x15,0x02, 0x10,0x02,
                                  0x15,0x00, 0x0F,0x01, 0x15,0x02, 0x16,0x02, 0x17,0x02,
                                  0x17,0x03, 0x18,0x03, 0x19,0x02, 0x15,0x02, 0x18,0x66,
                                  0x17,0x03, 0x19,0x02, 0x16,0x03, 0x17,0x03, 0x16,0x00,
                                  0x17,0x01, 0x19,0x02, 0x1B,0x02, 0x1B,0x70, 0x1A,0x03,
                                  0x1A,0x01, 0x19,0x02, 0x19,0x03, 0x1A,0x03, 0x1B,0x02,
                                  0x1A,0x0D, 0x19,0x03, 0x17,0x00, 0x18,0x66, 0x18,0x03,
                                  0x19,0x02, 0x1A,0x02, 0x19,0x0C, 0x18,0x0D, 0x17,0x03,
                                  0x16,0x01, 0x11,0x02, 0x11,0x03, 0x10,0x03, 0x0F,0x0C,
                                  0x10,0x02, 0x15,0x00, 0x1F,0x01, 0x1A,0x01, 0x18,0x66,
                                  0x19,0x03, 0x1A,0x01, 0x1B,0x02, 0x1B,0x03, 0x1B,0x03,
                                  0x1B,0x0C, 0x1A,0x0D, 0x19,0x03, 0x17,0x00, 0x1F,0x01,
                                  0x1A,0x01, 0x18,0x66, 0x19,0x03, 0x1A,0x01, 0x10,0x02,
                                  0x10,0x03, 0x10,0x03, 0x1A,0x0C, 0x18,0x0D, 0x17,0x03,
                                  0x16,0x00, 0x0F,0x01, 0x15,0x02, 0x16,0x02, 0x17,0x70,
                                  0x18,0x03, 0x17,0x02, 0x15,0x03, 0x15,0x03, 0x16,0x66,
                                  0x16,0x03, 0x16,0x02, 0x16,0x03, 0x15,0x03, 0x10,0x02,
                                  0x10,0x01, 0x11,0x01, 0x11,0x66, 0x10,0x03, 0x0F,0x0C,
                                  0x1A,0x02, 0x19,0x02, 0x16,0x03, 0x16,0x03, 0x18,0x66,
                                  0x18,0x03, 0x18,0x02, 0x17,0x03, 0x16,0x03, 0x19,0x00,
                                  0x00,0x00 };
//两只蝴蝶                                 
const unsigned char code Music_Two[] ={ 0x17,0x03, 0x16,0x03, 0x17,0x01, 0x16,0x03, 0x17,0x03,
                                  0x16,0x03, 0x15,0x01, 0x10,0x03, 0x15,0x03, 0x16,0x02,
                                  0x16,0x0D, 0x17,0x03, 0x16,0x03, 0x15,0x03, 0x10,0x03,
                                  0x10,0x0E, 0x15,0x04, 0x0F,0x01, 0x17,0x03, 0x16,0x03,
                                  0x17,0x01, 0x16,0x03, 0x17,0x03, 0x16,0x03, 0x15,0x01,
                                  0x10,0x03, 0x15,0x03, 0x16,0x02, 0x16,0x0D, 0x17,0x03,
                                  0x16,0x03, 0x15,0x03, 0x10,0x03, 0x15,0x03, 0x16,0x01,
                                  0x17,0x03, 0x16,0x03, 0x17,0x01, 0x16,0x03, 0x17,0x03,
                                  0x16,0x03, 0x15,0x01, 0x10,0x03, 0x15,0x03, 0x16,0x02,
                                  0x16,0x0D, 0x17,0x03, 0x16,0x03, 0x15,0x03, 0x10,0x03,
                                  0x10,0x0E, 0x15,0x04, 0x0F,0x01, 0x17,0x03, 0x19,0x03,
                                  0x19,0x01, 0x19,0x03, 0x1A,0x03, 0x19,0x03, 0x17,0x01,
                                  0x16,0x03, 0x16,0x03, 0x16,0x02, 0x16,0x0D, 0x17,0x03,
                                  0x16,0x03, 0x15,0x03, 0x10,0x03, 0x10,0x0D, 0x15,0x00,
                                  0x19,0x03, 0x19,0x03, 0x1A,0x03, 0x1F,0x03, 0x1B,0x03,
                                  0x1B,0x03, 0x1A,0x03, 0x17,0x0D, 0x16,0x03, 0x16,0x03,
                                  0x16,0x0D, 0x17,0x01, 0x17,0x03, 0x17,0x03, 0x19,0x03,
                                  0x1A,0x02, 0x1A,0x02, 0x10,0x03, 0x17,0x0D, 0x16,0x03,
                                  0x16,0x01, 0x17,0x03, 0x19,0x03, 0x19,0x03, 0x17,0x03,
                                  0x19,0x02, 0x1F,0x02, 0x1B,0x03, 0x1A,0x03, 0x1A,0x0E,
                                  0x1B,0x04, 0x17,0x02, 0x1A,0x03, 0x1A,0x03, 0x1A,0x0E,
                                  0x1B,0x04, 0x1A,0x03, 0x19,0x03, 0x17,0x03, 0x16,0x03,
                                  0x17,0x0D, 0x16,0x03, 0x17,0x03, 0x19,0x01, 0x19,0x03,
                                  0x19,0x03, 0x1A,0x03, 0x1F,0x03, 0x1B,0x03, 0x1B,0x03,
                                  0x1A,0x03, 0x17,0x0D, 0x16,0x03, 0x16,0x03, 0x16,0x03,
                                  0x17,0x01, 0x17,0x03, 0x17,0x03, 0x19,0x03, 0x1A,0x02,
                                  0x1A,0x02, 0x10,0x03, 0x17,0x0D, 0x16,0x03, 0x16,0x01,
                                  0x17,0x03, 0x19,0x03, 0x19,0x03, 0x17,0x03, 0x19,0x03,
                                  0x1F,0x02, 0x1B,0x03, 0x1A,0x03, 0x1A,0x0E, 0x1B,0x04,
                                  0x17,0x02, 0x1A,0x03, 0x1A,0x03, 0x1A,0x0E, 0x1B,0x04,
                                  0x17,0x16, 0x1A,0x03, 0x1A,0x03, 0x1A,0x0E, 0x1B,0x04,
                                  0x1A,0x03, 0x19,0x03, 0x17,0x03, 0x16,0x03, 0x0F,0x02,
                                  0x10,0x03, 0x15,0x00, 0x00,0x00 };
//***********************************************************************************
#endif

音乐播放器.zip

25.44 KB, 下载次数: 14

评分

参与人数 1黑币 +5 收起 理由
浮一音 + 5 谢谢你,但我是想要用PWM实现、、

查看全部评分

回复

使用道具 举报

地板
ID:67199 发表于 2020-6-14 22:48 | 只看该作者
几年前玩翻页钟时,用STC60S2的PCA弄过,无源蜂鸣器当音乐闹铃

if(music_star)       //音乐启动
      {jiepai=1;           //赋初值
       music_a=*music_p;   //节拍速度
       music_b=1;          //
       music_star=0;
      
       music_f=1;          //音乐播放启动
      }
         
   if(music_f)    //音乐标志为1,放音乐
     {music_b--;          //节拍计时
   if(music_b==0)        //四分之一音节到,计时后一个四分之一音节   
    {music_b=music_a;
     jiepai--;        //节拍减一
     if(jiepai)       //判断音节演奏完否
      {return;}          //未完成返回继续演奏
     else            // 完成后取下一个音乐频率
  {                      //计时复位
    CR=0;
    jiepai=*(++music_p)&0x0F ; //提取节拍, 以48MHZ为基准,
    if(jiepai==0)    //节拍为零,表示整首音乐演奏完毕,进行初值回位
    { CR=0;
            music_f=0;
   
     }
   else
   {yindiao=*music_p>>4;      //提取音调后,指针指向下一音节
   if(yindiao)              //音调不为零,由发声,音调地址=(n-1)*2=2n-2
  { yindiao=yindiao<<1;      //音调代码乘2
      CCAP0L =TABLE[yindiao+1]; //                        
      CCAP0H =TABLE[yindiao]; ; //装载比较初值                     
    CR=1;
   }

原程序太大,如感兴趣私发给你,自行参考。好久没玩了,自己都整不太明白了...........

评分

参与人数 1黑币 +5 收起 理由
浮一音 + 5 谢谢你,不过我是个小白看不太懂QAQ

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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