#include <stc15w401as.h>
#define EOS 0xFFFF // end of sound
unsigned int notetime= EOS; // 每个音符持续时间
unsigned int *noteptr;
bit noteend;
sbit bell=P2^3;
//==============================================================================
// 音符数组: {频率hz,持续时间ms}
unsigned int code NoteTurnon[]= {2000,1000,0,EOS};
unsigned int code NoteWorkStop[]={2500,250,0,250,2200,250,0,250,1900,250,0,EOS};
unsigned int code NoteTurnoff[]={2794,125,2637,125,2349,125,2093,125,1976,125,1760,125,1568,125,1397,125,0,EOS};
//-------------------------------------------------------------------------
/*定时器0中断,声音处理及定时 */
void timer0_isr() interrupt 1
{
bell = ~bell;
}
void ConfigTimer() // 不需要赋初值, 因为一直处于变化之中
{
//T0,T2中断设置
TMOD=0; // T0:模式0,16位自动重装,GATE=0,C/T=0定时模式
ET0=1; // 允许T0中断,
TR0=0; // ----> T0关闭
//
AUXR=0;
}
void BellDataProcess() //用于放在主函数
{
unsigned int temp;
unsigned int reload;
static bit note_f=0;
if(notetime == EOS) // =EOS时退出,音乐结束
{
if(note_f)
{
note_f=0; // 一组音乐结束后,确保只执行一次
noteend=1; // 音乐结束标志位
TR0=0;
bell=0;
}
}
else
{
if(notetime) notetime--; // 对1ms计数
else
{
note_f=1;
noteend=0; // =0读数据没结束
temp = *noteptr; // 读取频率,读取第1个数据
if(!temp)
{
TR0=0; // temp=0, 无声但需计时
bell=0; // bell=1会有大电流,但发声时没事
}
else
{
reload = 65536-500000/temp; // 此时temp为频率
TL0 = reload;
TH0 = reload >>8; // 计数值
TR0 = 1; // 启动T0
}
//--------------------------------
noteptr++;
temp = *noteptr; // 读取时间ms,读取第2个数据
notetime = temp;
//--------------------------------
noteptr++; // 读取下1组准备
}
}
}
//--------------------------------------------------------------------------------
// 读数组首地址
void PlaySongTurnon() {notetime = 0; noteptr = NoteTurnon;}
void PlaySongWorkStop(){notetime = 0; noteptr = NoteWorkStop;}
void PlaySongTurnoff() {notetime = 0; noteptr = NoteTurnoff;}