课程设计名称多功能音乐闹钟Word格式文档下载.docx
《课程设计名称多功能音乐闹钟Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《课程设计名称多功能音乐闹钟Word格式文档下载.docx(17页珍藏版)》请在冰点文库上搜索。
![课程设计名称多功能音乐闹钟Word格式文档下载.docx](https://file1.bingdoc.com/fileroot1/2023-5/4/5498a275-9ca6-44f6-a45e-cd439a0959ca/5498a275-9ca6-44f6-a45e-cd439a0959ca1.gif)
产品所用程序:
/*******************************************************
Filename;
demo_11_4.c
Chiptype;
ATmega16
Programtype;
Application
Clockfrequency;
1.000000MHz
Memorymodel;
Small
ExternalSPAMsize;
0
Datastacksize;
256
********************************************************/
#include<
iom16v.h>
macros.h>
constunsignedcharled_7[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
constunsignedcharposition[6]={0xC1,0xC2,0xC4,0xC8,0xD0,0xE0};
constunsignedintt[16]={0,1912,1730,1518,1433,1276,1136,1012,956,865,759,716,638,568,506,470};
constunsignedchard[16]={0,52,58,66,70,78,88,99,105,116,132,140,157,176,198,209};
constunsignedcharMax_note[8]={84,86,64,88,90,100,78,102};
constunsignedcharmusic[8][102]={{5,2,4,2,5,2,10,6,10,2,11,2,10,2,9,2,7,2,8,10,8,2,7,2,8,2,12,6,12,2,11,2,10,2,9,2,10,2,10,10,5,2,4,2,5,2,10,6,10,2,11,2,10,2,9,2,7,2,8,2,9,2,10,2,14,2,13,6,10,2,12,2,11,2,10,2,11,2,10,6,9,2,8,14},
{12,2,12,2,10,2,9,2,10,2,6,4,9,2,10,2,12,2,10,2,9,10,12,2,12,2,10,2,9,2,10,2,5,4,9,2,10,2,12,2,9,2,8,10,8,2,9,2,10,2,12,2,13,2,12,2,10,2,12,2,10,2,10,2,9,2,9,10,8,2,9,2,8,2,9,4,8,2,9,4,10,4,12,2,10,10},
{2,4,2,4,3,4,3,6,2,2,3,4,5,2,6,4,5,6,1,4,2,4,3,4,6,4,5,4,3,2,5,14,5,2,6,2,8,8,6,4,5,4,3,4,5,2,3,6,1,2,2,2,3,6,1,2,1,4,3,4,2,2,2,4},
{3,4,5,4,8,12,8,4,7,8,6,4,5,4,6,4,8,4,3,4,2,4,1,8,1,4,1,4,1,4,8,8,6,4,5,4,3,4,2,4,1,4,2,24,3,4,5,4,8,12,8,4,7,8,6,4,5,4,6,4,8,4,3,4,2,4,1,8,1,4,1,4,1,4,8,8,6,4,5,4,3,4,2,4,1,4,1,24},
{8,4,7,4,8,12,9,4,10,4,9,4,8,4,7,4,8,12,8,4,8,4,5,4,5,4,1,4,6,12,6,4,5,4,1,4,1,4,3,4,2,12,4,4,4,4,5,4,8,4,7,4,8,12,9,4,10,4,9,4,8,4,7,4,8,12,8,4,8,4,5,4,5,4,1,4,6,12,6,4,5,4,5,4,8,4,7,4,8,24},
{5,4,12,4,11,4,10,8,10,4,11,2,10,10,10,4,11,4,10,4,11,4,10,4,9,2,8,6,8,4,10,4,12,4,13,8,13,4,13,2,12,6,9,4,9,4,11,2,10,22,8,4,10,4,12,4,13,8,13,4,13,2,12,2,12,4,9,4,9,4,11,4,10,4,11,4,10,4,9,2,8,10,9,4,10,4,6,8,6,4,8,4,8,4,7,4,7,8,8,24},
{12,4,12,4,11,4,10,4,9,12,9,4,9,4,10,4,11,4,10,12,8,4,8,8,9,8,10,8,9,8,8,8,7,4,6,4,5,12,12,4,12,4,11,4,10,4,9,8,9,4,9,4,10,4,11,4,10,12,8,4,8,8,9,4,10,4,11,8,10,8,9,8,8,4,7,4,8,24},
{5,2,8,2,8,2,8,3,9,1,10,2,8,4,6,2,8,2,8,2,8,3,8,1,6,2,5,4,5,2,8,2,8,2,8,3,9,1,10,2,8,4,8,2,9,2,9,2,9,1,8,1,9,1,10,1,9,6,5,2,8,2,8,2,8,3,9,1,10,2,8,4,8,2,6,2,8,2,8,2,9,2,8,6,5,2,8,2,8,2,8,4,12,2,11,2,10,2,8,2,8,8}};
unsignedcharnote_n;
unsignedintint_n;
intplay_on;
intclock_style=0,lazy_style=0,ci=0,cci;
unsignedcharweek_clock[8]={0,1,2,3,4,5,6,7},time[3],time_clock[8][3]={{10,0,7},{11,5,7},{12,10,7},{13,15,7},{14,20,7},{15,25,7},{16,30,7},{17,35,7}};
unsignedchardis_buff[6];
unsignedchartime_counter,key_stime_counter;
unsignedcharclock_state=6,return_time;
intpoint_on=0,set_on=0,time_1s_ok=0,key_stime_ok=0;
intweek;
voiddisplay(void)
{
staticunsignedcharposit=0;
PORTB=0xFF;
PORTA=led_7[dis_buff[posit]];
if(set_on&
&
(posit==clock_state))PORTA=0xFF;
if(point_on&
(posit==2||posit==4))PORTA&
=0x7F;
PORTB=position[posit];
if(++posit>
=6)posit=0;
}
//Timer0比较匹配中断服务,2ms定时
#pragmainterrupt_handlertimer0_comp_isr:
iv_TIMER0_COMP
voidtimer0_comp_isr(void)
display();
if(++key_stime_counter>
=5)
{
key_stime_counter=0;
key_stime_ok=1;
if(!
(++time_counter%25))set_on=!
set_on;
if(time_counter>
=100)
{
time_counter=0;
time_1s_ok=1;
}
}
//T/C1比较匹配A中断服务
#pragmainterrupt_handlertimer1_compa_isr:
iv_TIMER1_COMPA
voidtimer1_compa_isr(void)
if(!
play_on)
note_n=0;
int_n=1;
play_on=1;
else
if(--int_n==0)
TCCR1B=0x08;
if(note_n<
Max_note[cci])
{
OCR1A=t[music[cci][note_n]];
int_n=d[music[cci][note_n]];
note_n++;
int_n=int_n*music[cci][note_n];
TCCR1B=0x09;
}
else
play_on=0;
voidtime_to_disbuffer(unsignedchar*time)//时钟时间送显示缓冲区函数
unsignedchari,j=0;
for(i=0;
i<
=2;
i++)
dis_buff[j++]=time[i]%10;
dis_buff[j++]=time[i]/10;
voidctime_to_disbuffer(unsignedintci)//闹钟时间送显示缓冲区函数
dis_buff[j++]=time_clock[ci][i]%10;
dis_buff[j++]=time_clock[ci][i]/10;
voidwtime_to_disbuffer(unsignedintweek)//星期送显示缓冲区函数
unsignedcharj=0;
dis_buff[j++]=week%10;
dis_buff[j++]=week/10;
#definekey_inputPINB
#definekey_mask0b11000000
#definekey_no0
#definekey_k11
#definekey_k22
#definekey_state_00
#definekey_state_11
#definekey_state_22
unsignedcharread_key(void)
staticunsignedcharkey_state=0,key_old;
unsignedcharkey_press,key_return=key_no;
staticintpress_time=0;
key_press=key_input&
key_mask;
//读按键I/O电平
switch(key_state)
casekey_state_0:
//按键初始态
if(key_press!
=key_mask)
key_old=key_press;
//记录原电平
key_state=key_state_1;
//键被按下,状态转换到键确认态
break;
casekey_state_1:
//按键确认态
if(key_press==key_old)//和原电平比较(消抖处理)
if(key_press==0b01000000)key_return=key_k1;
elseif(key_press==0b10000000)key_return=key_k2;
key_state=key_state_2;
//状态转换到键释放态
TCCR1B=0x08;
//响铃关
note_n=0;
lazy_style=0;
//懒人响铃关
key_state=key_state_0;
//按键已抬起,转换到按键初始态
casekey_state_2:
if(key_press==key_mask)
press_time=0;
key_state=key_state_0;
//按键已释放,转换到按键初始态
else
if((key_press==0b10000000)&
(++press_time>
=100))
if(++clock_style>
1)clock_style=0;
returnkey_return;
voidmain(void)
unsignedcharkey_temp,i;
DDRA=0xFF;
//LED段码输出
PORTB=0x00;
DDRB=0x3F;
//LED位控输出
DDRD=0x20;
//PD5音乐播放输出
//T/C0初始化
OCR0=0xF9;
//OCR0=0xF9(249),(249+1)/(125kHz)=2ms
TCCR0=0x0A;
//内部时钟,8分频(1MHz/8=125kHz),CTC模式
//T/C1初始化
TCCR1A=0x40;
TCCR1B=0x08;
TIMSK=0x12;
//使能T/C1比较匹配A中断,使能T/C0比较匹配中断
time[2]=6;
time[1]=58;
time[0]=55;
week=0;
//设时间初始值为23:
58:
55星期天
SEI();
//使能全局中断
while
(1)
if(time_1s_ok)//1s到
{
time_1s_ok=0;
point_on=!
point_on;
//秒闪烁标志
if(++time[0]>
=60)//秒加1,以下为时间调整
{
time[0]=0;
if(lazy_style)TCCR1B=0x09;
//1min到懒人模式响铃
if(++time[1]>
=60)
{
time[1]=0;
if(++time[2]>
=24)
{
time[2]=0;
if(++week>
=7)week=0;
}
}
if((time[2]==time_clock[week][2])&
(time[1]==time_clock[week][1])&
(time_clock[week][0]!
=week))
if((time_clock[week][0])==(10+week))
ci=week_clock[week];
TCCR1B=0x09;
lazy_style=1;
if((time_clock[week][0]+=10)>
(30+week))
time_clock[week][0]=20+week;
cci=week_clock[week];
}//周闹钟时间到响铃同时懒人模式启动
if((time[2]==time_clock[7][2])&
(time[1]==time_clock[7][1])&
(time_clock[7][0]!
=7))
if((time_clock[7][0])==(17))
cci=week_clock[week];
if((time_clock[7][0]+=10)>
(37))
time_clock[7][0]=27;
cci=week_clock[7];
}//日闹钟时间到响铃同时懒人模式启动
if((++return_time>
=20)&
((clock_state!
=6)||(clock_style==1))){clock_state=6;
clock_style=0;
if(clock_style==1)ctime_to_disbuffer(ci);
{if(clock_state!
=0)time_to_disbuffer(time);
if(key_stime_ok)//10ms到,键处理
key_stime_ok=0;
key_temp=read_key();
//调用按键接口程序
if(clock_style)//判断是否处于闹钟设置状态
if(key_temp)//确认有键按下
return_time=0;
if(key_temp==key_k1)
if(++clock_state>
=7)clock_state=0;
if(clock_state==0)
ctime_to_disbuffer(ci);
if(clock_state==6)
if((clock_state==0)&
(key_temp==key_k2))
if(++ci>
=8)ci=0;
ctime_to_disbuffer(ci);
if((clock_state==1)&
if((time_clock[ci][0]+=10)>
(30+ci))time_clock[ci][0]=ci;
ctime_to_disbuffer(ci);
if((clock_state==6)&
if((++week_clock[ci])>
=8)week_clock[ci]=0;
cci=week_clock[ci];
if((clock_state<
6)&
(clock_state>
1)&
(key_temp==key_k2))//K2键按下
if(clock_state%2)time_clock[ci][clock_state/2]+=10;
else
if((time_clock[ci][clock_state/2]%10)==9)
time_clock[ci][clock_state/2]-=9;
else
time_clock[ci][cloc