新手51单片机入门实战-电子可调音乐闹钟项目
立即下载
资源介绍:
请用keil软件打开和编辑,用专门的51单片机烧录软件去烧录(stc-isp)
#include
#include "DELAY.H"
#include "Nixie.H"
#include "MatrixKey.H"
#include "DS1302.H"
#include "Timer1.H"
#include "Timer0.H"
#include "music.H"
sbit Buzzer=P2^5;
unsigned char MODE;//有三种模式,正常显示,时钟设置,闹钟设置
unsigned char KeyNum;//瞬间键码值
char Select;//数码管的位选(当前选择的数码管),Select>=0 && Select<=2
unsigned char Flag;//数码管闪烁标志
char ClockNum[3]={0,0,0};
unsigned char FreqSelect,MusicSelect;
//音乐播放函数
void Musicplay()
{
if(Music[MusicSelect]!=0xFF) //如果不是停止标志位
{
FreqSelect=Music[MusicSelect]; //选择音符对应的频率
MusicSelect++;
Delay(SPEED/4*Music[MusicSelect]); //选择音符对应的时值
MusicSelect++;
TR0=0;
Delay(5); //音符间短暂停顿
TR0=1;
}
else //如果是停止标志位
{
MusicSelect=0;
}
if(DS1302_Time[4]==ClockNum[1]+1)
{
TR0=0;Buzzer=0;
}
}
//时间显示函数(含音乐播放函数)
void TimeShow(void)
{
DS1302_ReadTime();
Nixie(1,DS1302_Time[3]/10);//显示时
Nixie(2,DS1302_Time[3]%10);
Nixie(3,17);
Nixie(4,DS1302_Time[4]/10);//显示分
Nixie(5,DS1302_Time[4]%10);
Nixie(6,17);
Nixie(7,DS1302_Time[5]/10);//显示秒
Nixie(8,DS1302_Time[5]%10);
if(DS1302_Time[3]==ClockNum[0] && DS1302_Time[4]==ClockNum[1] && DS1302_Time[5]==ClockNum[2])
{
TR0=1;
}
if(TR0==1)
{
Musicplay();
}
}
//时间设置函数
void TimeSet(void)
{
//选择设置1
if(KeyNum==1)
{
Select++;
if(Select>2){Select=0;}
}
//选择设置2
if(KeyNum==2)
{
Select--;
if(Select<0){Select=2;}
}
//按键时间加
if(KeyNum==3)
{
if(Select+3==3)
{
DS1302_Time[Select+3]++;
if(DS1302_Time[Select+3]>24)
{
DS1302_Time[Select+3]=0;
}
}
if(Select+3==4)
{
DS1302_Time[Select+3]++;
if(DS1302_Time[Select+3]>60)
{
DS1302_Time[Select+3]=0;
}
}
if(Select+3==5)
{
DS1302_Time[Select+3]++;
if(DS1302_Time[Select+3]>60)
{
DS1302_Time[Select+3]=0;
}
}
}
//按键时间减
if(KeyNum==4)
{
if(Select+3==3)
{
DS1302_Time[Select+3]--;
if(DS1302_Time[Select+3]<0)
{
DS1302_Time[Select+3]=24;
}
}
if(Select+3==4)
{
DS1302_Time[Select+3]--;
if(DS1302_Time[Select+3]<0)
{
DS1302_Time[Select+3]=60;
}
}
if(Select+3==5)
{
DS1302_Time[Select+3]--;
if(DS1302_Time[Select+3]<0)
{
DS1302_Time[Select+3]=60;
}
}
}
//闪烁判断
if(Select==0 && Flag==1){Nixie(1,16);Nixie(2,16);}
else {Nixie(1,DS1302_Time[3]/10);Nixie(2,DS1302_Time[3]%10);}
if(Select==1 && Flag==1){Nixie(4,16);Nixie(5,16);}
else {Nixie(4,DS1302_Time[4]/10);Nixie(5,DS1302_Time[4]%10);}
if(Select==2 && Flag==1){Nixie(7,16);Nixie(8,16);}
else {Nixie(7,DS1302_Time[5]/10);Nixie(8,DS1302_Time[5]%10);}
Nixie(3,17);
Nixie(6,17);
}
//闹钟设置函数
void ClockSet()
{
//选择设置1
if(KeyNum==1)
{
Select++;
if(Select>2){Select=0;}
}
//选择设置2
if(KeyNum==2)
{
Select--;
if(Select<0){Select=2;}
}
//按键时间加
if(KeyNum==3)
{
if(Select==0)
{
ClockNum[Select]++;
if(ClockNum[Select]>24)
{
ClockNum[Select]=0;
}
}
if(Select==1)
{
ClockNum[Select]++;
if(ClockNum[Select]>60)
{
ClockNum[Select]=0;
}
}
if(Select==2)
{
ClockNum[Select]++;
if(ClockNum[Select]>60)
{
ClockNum[Select]=0;
}
}
}
//按键时间减
if(KeyNum==4)
{
if(Select==0)
{
ClockNum[Select]--;
if(ClockNum[Select]<0)
{
ClockNum[Select]=24;
}
}
if(Select==1)
{
ClockNum[Select]--;
if(ClockNum[Select]<0)
{
ClockNum[Select]=60;
}
}
if(Select==2)
{
ClockNum[Select]--;
if(ClockNum[Select]<0)
{
ClockNum[Select]=60;
}
}
}
//闪烁判断
if(Select==0 && Flag==1){Nixie(1,16);Nixie(2,16);}
else {Nixie(1,ClockNum[0]/10);Nixie(2,ClockNum[0]%10);}
if(Select==1 && Flag==1){Nixie(4,16);Nixie(5,16);}
else {Nixie(4,ClockNum[1]/10);Nixie(5,ClockNum[1]%10);}
if(Select==2 && Flag==1){Nixie(7,16);Nixie(8,16);}
else {Nixie(7,ClockNum[2]/10);Nixie(8,ClockNum[2]%10);}
Nixie(3,17);
Nixie(6,17);
}
//主函数
void main()
{
DS1302_Init();
Timer1_Init();
Timer0_Init();
Buzzer=0;
DS1302_SetTime();
while(1)
{
KeyNum=MatrixKey();
if(KeyNum==5)
{
if(MODE==0){MODE=1;Select=0;}//显示模式
else if(MODE==1){MODE=2;DS1302_SetTime();}//时钟设置模式
else if(MODE==2){MODE=0;}//闹钟设置模式
}
switch(MODE)//根据不同的功能执行不同的函数
{
case 0:TimeShow();break;
case 1:TimeSet();break;
case 2:ClockSet();break;
}
}
}
//定时器0中断负责音乐的播放
void Timer0_Routine() interrupt 1
{
if(FreqTable[FreqSelect]) //如果不是休止符
{
/*取对应频率值的重装载值到定时器*/
TL0 = FreqTable[FreqSelect]%256; //设置定时初值
TH0 = FreqTable[FreqSelect]/256; //设置定时初值
Buzzer=!Buzzer; //翻转蜂鸣器IO口
}
}
//定时器1负责设置位的闪烁
void Timer1_Routine() interrupt 3
{
static unsigned int T1Count;
TL1 = 0x18; //设置定时初值
TH1 = 0xFC; //设置定时初值
T1Count++;
if(T1Count>=300)
{
T1Count=0;
Flag=!Flag;
}
}