闹钟设计"/>
基于STC89C52芯片完成音乐闹钟设计
找到不同音符对应的频率,定义音符,根据《孤勇者》简谱编写乐谱,运用按键k1来设置闹钟倒计时时间,设置完成后按下按键k2,倒计时开始,倒计时结束后,播放《孤勇者》铃声
设计开发环境:
keli4(51系列兼容单片机C语言软件开发系统)
#include <reg52.h>
typedef unsigned int uint;
typedef unsigned char uchar;
uint a,FreqSelect,MusicSelect,count,count2,count_ms=100;
uchar code table[]={0x3F, //"0"0x06, //"1"0x5B, //"2"0x4F, //"3"0x66, //"4"0x6D, //"5"0x7D, //"6"0x07, //"7"0x7F, //"8"0x6F, //"9"0x00 //熄灭};sbit P2_0 = P2^3;
sbit P2_1 = P2^2;
sbit P2_2 = P2^1;
sbit P2_3 = P2^0;
sbit P2_4 = P2^7;
sbit P2_5 = P2^6;
sbit P2_6 = P2^5;
sbit P2_7 = P2^4;
sbit k1=P1^6;
sbit k2=P1^7;
sbit Buzzer=P1^4;
//播放速度,将一个四分音符的时长设置为600(ms),并以四分音符的时长为基准
#define SPEED 600
//音符与索引对应表,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,
};
//乐谱
unsigned int code Music[]={//乐谱较长加上关键字code将其储存在ROM(flash)//音符,时值,//1L6,4+4,P,4,P,2,M6,1,M7,1,//2H1,1,H2,1,M7,1,H1,1,H1,2,H1,1,M7,1,H1,1,H1,2,H1,1,H2,1,//3H3,1,H2,1,H3,1,H2,1,H3,2,H3,1,H2,1,H3,2,H5,2,H3,2,M6,1,M7,1,//4H1,1,H2,1,M7,1,H1,1,H1,2,H1,1,M7,1,H1,1,H2,1,M7,1,H1,1,H1,2,H1,1,H2,1,//5H3,1,H2,1,H3,1,H2,1,H3,2,H3,1,H2,1,H3,2,H5,2,H3,2,H5,2,//6H3,2+1,H5,1,H3,2+1,H5,1,H3,1,H5,1,H6,1,H3,1,H5,2,H5,2,//7H3,2+1,H5,1,H3,2+1,H5,1,H3,1,H5,1,H6,1,H3,1,H5,1,H5,1,H5,1,//8H3,1,H2,1,H2,2,H2,2,H1,1,H3,1,H3,1,H2,1,H2,2,H2,2,H1,1,H1,1,//9M6,4+4,P,4,P,2,H5,1,H5,1,//10H3,1,H2,1,H2,2,H2,2,H1,1,H3,1,H3,1,H2,1,H2,2,H2,2,H1,1,H1,1,//11M6,4+4,P,4,P,4,0xFF //终止标志
};
/*
* 延时函数 毫秒级
*/
void delay1(uint z)
{uint x,y;for(x=z;z>0;z--)for(y=110;y>0;y--);
}
void Delay(unsigned int xms)
{unsigned char i, j;while(xms--){i = 2;j = 239;do{while (--j);} while (--i);}
}
/********************************************************************
* 名称 : Timer1Init()
* 功能 : 定时器1初始化
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Timer1Init(void) //10毫秒@11.0592MHz
{
// AUXR &= 0xBF; //定时器时钟12T模式TMOD &= 0x0F; //设置定时器模式TL1 = 0x00; //设置定时初值TH1 = 0xDC; //设置定时初值TF1 = 0; //清除TF1标志TR1 = 1; //定时器1开始计时ET1 = 1; //enable timer1 interruptEA = 1; //open global interrupt switch
}
void Timer0Init(void)
{TMOD &= 0xF0; //设置定时器模式TMOD |= 0x01; //设置定时器模式TL0 = 0x18; //设置定时初值TH0 = 0xFC; //设置定时初值TF0 = 0; //清除TF0标志TR0 = 1; //定时器0开始计时ET0=1;EA=1;PT0=0;
}
/********************************************************************
* 名称 : display()
* 功能 : 数码管显示函数
* 输入 : Dis_data1,Dis_data2,Dis_data3,Dis_data4
* 输出 : 无
***********************************************************************/
void display1(uint Dis_data1,uint Dis_data2,uint Dis_data3,uint Dis_data4)
{ P0=table[Dis_data1];P2_0 = 0;delay1(2);P2_0 = 1;P0=table[Dis_data2];P2_1 = 0;delay1(2);P2_1 = 1;P0=table[Dis_data3];P2_2 = 0;delay1(2);P2_2 = 1;P0=table[Dis_data4];P2_3 = 0;delay1(2);P2_3 = 1;}
void display2(uint Dis_data1,uint Dis_data2,uint Dis_data3,uint Dis_data4)
{ P0=table[Dis_data1];P2_4 = 0;delay1(2);P2_4 = 1;P0=table[Dis_data2];P2_5 = 0;delay1(2);P2_5 = 1;P0=table[Dis_data3];P2_6 = 0;delay1(2);P2_6 = 1;P0=table[Dis_data4];P2_7 = 0;delay1(2);P2_7 = 1;}/********************************************************************
* 名称 : main()
* 功能 : 主函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void main()
{while(1){if(k1==0){while(!k1);a++;}if(k2==0){break;}count=a;display2(count%10000/1000,count%1000/100,count%100/10,count%10);} Timer1Init();//count=100;//count=10000;count_ms=1000;while(1){display1(count%10000/1000,count%1000/100,count%100/10,count%10);if(count==0){Timer0Init();while(1){if(Music[MusicSelect]!=0xFF) //如果不是停止标志位{FreqSelect=Music[MusicSelect]; //选择音符对应的频率MusicSelect++;Delay(SPEED/2*Music[MusicSelect]); //选择音符对应的时长MusicSelect++;TR0=0;//不同音符间短暂停顿,利用延时开关定时器实现Delay(5); TR0=1;}else //如果是停止标志位{TR0=0; //关闭定时器while(1);}}}}
}/********************************************************************
* 名称 : void tm1_isr() interrupt 3 using 1
* 功能 : 定时器1中断服务函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void tm1_isr() interrupt 3 using 1
{TL1 = 0x00; //设置定时初值TH1 = 0xDC; //设置定时初值if (count_ms-- == 0) //1ms * 1000 -> 1s{count_ms=1000;if(count==0){count=a;}count --; //reset counter}
}void Timer0_Routine() interrupt 1
{if(FreqTable[FreqSelect]) //如果是休止符(0),那么不播放声音,只进行延时{//取对应频率值的重装载值到定时器(确认音高)FreqSelect=Music[MusicSelect]TL0 = FreqTable[FreqSelect]%256; //设置低位定时初值TH0 = FreqTable[FreqSelect]/256; //设置高位定时初值Buzzer=!Buzzer; //翻转蜂鸣器IO口(注意这里的重装值是周期的一半,故仅进行一次蜂鸣器的翻转)}
}
更多推荐
基于STC89C52芯片完成音乐闹钟设计
发布评论