📄 alarm.c
字号:
//处理闹钟中断后的进程
//执行中断里面闹钟的处理
//重新把下一个最近的闹钟值写入闹钟寄存器
void Alarm_Process(void)
{
u16 cbcolor;
u16 cpcolor;
cbcolor=BACK_COLOR; //保存先前的画笔状态
cpcolor=POINT_COLOR;
//对于只要闹铃一次的闹钟,在执行之后关闭闹钟
if((Alarm[AlarmInLine].Status&0x03)==0)
{
Alarm[AlarmInLine].Status&=0xF7; //取消闹铃
Save_Alarm(AlarmInLine);//将数据保存,下次不再启用
}
READ_GRAM(111,151);
BACK_COLOR=GRAY;
POINT_COLOR=BLACK;
TFT_ShowNum(112,152,Alarm[AlarmInLine].hour,16,0x00);
TFT_ShowChar(128,152,':',16,0x00);
TFT_ShowNum(136,152,Alarm[AlarmInLine].min,16,0x00);
POINT_COLOR=GRED;
TFT_DrawRectangle(111,151,152,168);
Play_Alarm_Ring();//响闹铃
RECOVER_GRAM(111,151);
Init_Alarm_Reg();//取得下一个闹钟的时间
POINT_COLOR=cpcolor;//恢复先前的画笔状态
BACK_COLOR=cbcolor;
}
//闹钟初始化
void Alarm_Init(void)
{
u8 t,i;
while(!(RTC->CRL&(1<<3)));//等待RTC寄存器同步
RTC->CRH|=0X02; //允许闹钟中断
while(!(RTC->CRL&(1<<5)));//等待RTC寄存器操作完成
rtc_get();//得到时间
t=FM24C16_ReadOneByte(263);//读取第一个闹钟的小时
if(t>23) //未被初始化
{
for(i=0;i<8;i++)//初始化
{
Alarm[i].Status=0;
Alarm[i].WeekMark=0;
Alarm[i].Ring=0;
Alarm[i].hour=0;
Alarm[i].min=0;
Alarm[i].Ring_Addr=0;
}
Save_Alarm(8);//全部保存
}else Read_Alarm(8);//全部读取闹钟数据,包括闹钟铃声
Init_Alarm_Reg(); //更新闹钟寄存器
}
//加载星期自定义的设置
void Self_Define(u8 sfd)
{
u8 t;
BACK_COLOR=LGRAY;
//加载条目信息
for(t=0;t<7;t++)
{
if(sfd&0x80)POINT_COLOR=RED;
else POINT_COLOR=LGRAY;
TFT_DrawRectangle(20+29*t,146,46+29*t,162);//26*16方框
sfd<<=1;
}
}
//显示铃声的名字
void Show_Ring_Name(void)
{
u8 str[8];
if(Alarm_Temp.Status&0x04)//收音机作为铃声
{
if(Alarm_Temp.Ring_Addr>=8750&&Alarm_Temp.Ring_Addr<=10800)//存在合法频段
{
str[0]='F';
str[1]='M';
if(Alarm_Temp.Ring_Addr>=10000)str[2]='1';//
else str[2]=' ';//
str[3]=(Alarm_Temp.Ring_Addr/1000)%10+'0';//
str[4]=(Alarm_Temp.Ring_Addr/100)%10+'0';//
str[5]='.';//
str[6]=(Alarm_Temp.Ring_Addr/10)%10+'0';//小数点后一位
str[7]='\0';//加入结束符
Show_Str_Mid(0,210,str,0x00,240); //叠加模式,非自动换
}else Show_Str_Mid(0,210,"空白",0x00,240); //不存在FM,跳出
}
else //MP3作为铃声
{
if(Alarm_Temp.Ring_Addr>2)Show_Str_Mid(0,210,Alarm_Temp.Ring_Name,0x00,240); //叠加模式,非自动换
else Show_Str_Mid(0,210,"空白",0x00,240); //叠加模式,非自动换
}
}
u8 AlarmTPos=0;//闹铃时钟所在位置 XX:XX 共四位
//选项选中/取消
//num:目录项 0,1,2,4,5
//sel:1选中/0取消
void Item_Sel(u8 num,u8 sel)
{
u8 temp;
Self_Define(0);//默认去除星期框
if(num==1||num==4)BACK_COLOR=WHITE;//假定没有选中,原背景
else BACK_COLOR=LGRAY;
if(sel)BACK_COLOR=BROWN;//棕色背景,选中了
POINT_COLOR=BLACK; //笔是黑色的
temp=Alarm_Temp.Status; //得到状态值
switch(num)
{
case 0: //闹铃开关
if(temp&0x08)Show_Str(144,50,"打开",0x00); //非叠加模式,非自动换行
else Show_Str(144,50,"关闭",0x00); //非叠加模式,非自动换行
break;
case 1://闹铃时间
temp=Alarm_Temp.hour;//获得小时
TFT_ShowChar(140,82,temp/10+'0',16,0x00);
TFT_ShowChar(148,82,temp%10+'0',16,0x00);
TFT_ShowChar(156,82,':',16,0x00);
temp=Alarm_Temp.min;//获得分钟
TFT_ShowChar(164,82,temp/10+'0',16,0x00);
TFT_ShowChar(172,82,temp%10+'0',16,0x00);
if(sel)
{
BACK_COLOR=BLUE;//
POINT_COLOR=WHITE;
switch(AlarmTPos)
{
case 0:
TFT_ShowChar(140,82,Alarm_Temp.hour/10+'0',16,0x00);
break;
case 1:
TFT_ShowChar(148,82,Alarm_Temp.hour%10+'0',16,0x00);
break;
case 2:
TFT_ShowChar(164,82,Alarm_Temp.min/10+'0',16,0x00);
break;
case 3:
TFT_ShowChar(172,82,Alarm_Temp.min%10+'0',16,0x00);
break;
}
Load_KeyBoard(1);//加载键盘
}else Load_KeyBoard(0);
break;
case 2://响铃方式
temp=temp&0x03;
switch(temp)
{
case 0://一次
Show_Str(136,114," 一次 ",0x00); //叠加模式,非自动换行
break;
case 1://每天
Show_Str(136,114," 每天 ",0x00); //叠加模式,非自动换行
break;
case 2://自定义
Show_Str(136,114,"自定义",0x00); //叠加模式,非自动换行
Self_Define(Alarm_Temp.WeekMark);//加载星期框
break;
}
break;
case 4:
if(temp&0x04)//FM作为铃声
{
Read_Ring(1,Alarm_Temp.Ring,Alarm_Temp.Ring_Name,&Alarm_Temp.Ring_Addr);
Show_Str(136,178,"FM广播",0x00); //叠加模式,非自动换行
}
else //MP3作为铃声
{
Read_Ring(0,Alarm_Temp.Ring,Alarm_Temp.Ring_Name,&Alarm_Temp.Ring_Addr);
Show_Str(136,178," 铃声 ",0x00); //叠加模式,非自动换行
}
TFT_Fill(0,202,239,234,LGRAY);//清空上次显示
BACK_COLOR=LGRAY;
Show_Ring_Name();
break;
case 5:
TFT_Fill(0,202,239,234,LGRAY);//清空上次显示
Show_Ring_Name(); break;
}
}
//处理键值
//selx:键值条目编号
void Pro_Key_Alarm(u8 selx)
{
u8 temp;
switch(selx)
{
case 0://开关按键
if(Is_In_Area(85,46,109,70)||Is_In_Area(210,46,234,70))
{
if(Alarm_Temp.Status&0x08)Alarm_Temp.Status&=0xF7;//取消操作
else Alarm_Temp.Status|=0x08;//选择操作
Item_Sel(0,1);
}
break;
case 1://时间设置
if(Is_In_Area(140,82,148,98))AlarmTPos=0;//选中小时十位
else if(Is_In_Area(148,82,156,98))AlarmTPos=1;//选中小时个位
else if(Is_In_Area(164,82,172,98))AlarmTPos=2;//选中分钟十位
else if(Is_In_Area(172,82,180,98))AlarmTPos=3;//选中分钟个位
Item_Sel(1,1);
break;
case 2://响铃方式
temp=Alarm_Temp.Status&0x03;
if(Is_In_Area(85,110,109,134))//左键
{
if(temp)temp--;
else temp=2;
}else if(Is_In_Area(210,110,234,134))//右键
{
temp++;
if(temp>2)temp=0;
}
Alarm_Temp.Status&=0XFC;
Alarm_Temp.Status|=temp;
Item_Sel(2,1);
break;
case 4: //铃声设置
if(Is_In_Area(85,174,109,198)||Is_In_Area(210,174,234,198))
{
if(Alarm_Temp.Status&0x04)Alarm_Temp.Status&=0xFB;//取消操作 0,MP3铃声
else Alarm_Temp.Status|=0x04;//选择操作 1,FM铃声
Item_Sel(4,1);
}
break;
case 5:
Set_Alarm_Ring(); //闹钟铃声
Load_Gui_Set_Alarm(); //装载ALARM编辑主界面
for(temp=0;temp<6;temp++)
{
if(temp==5)Item_Sel(temp,1);//选中闹铃开关
else if(temp!=3)Item_Sel(temp,0);
}
break;
}
}
//得到星期几按键返回值
//返回:1~8
//返回8:按键无效
u8 Get_WeekBit_Val(void)
{
u8 t;
for(t=0;t<7;t++)if(Is_In_Area(20+29*t,146,46+29*t,162))return t+1;//返回星期几的编号
return 8;
}
//设置闹钟
//index:闹钟编号
void Set_Alarm(u8 index)
{
u8 key,sel;
Alarm_Temp=Alarm[index];
Alarm_Temp.Ring=index;//保存闹钟编号
Read_Ring(Alarm_Temp.Status&0x04,Alarm_Temp.Ring,Alarm_Temp.Ring_Name,&Alarm_Temp.Ring_Addr);//读取闹钟铃声信息
Load_Gui_Set_Alarm(); //装载ALARM编辑主界面
for(sel=0;sel<6;sel++)
{
if(sel==0)Item_Sel(sel,1);//选中闹铃开关
else if(sel!=3)Item_Sel(sel,0);
}
key=0;
sel=0;//默认选择0
Pen_Point.Key_Sta=Key_Up;//释放显示期间的触发
while(1)//等待按键
{
if((Pen_Point.Key_Sta==Key_Down||NPEN)&&Pen_Point.Key_LSta)key=Touch_To_Num(4);//得到按键值
if(PEN)//按键松开了,状态改变(状态机)
{
Pen_Point.Key_LSta=1;
Pen_Point.Key_Sta=Key_Up;
}
if(key)//有按键按下
{
Pen_Point.Key_LSta=0;
switch(key)
{
case 1:
case 2:
case 3:
case 5:
case 6:
key-=1;
if(sel!=key&&key<8)//选中一个
{
AlarmTPos=0;//复位到第一位
Item_Sel(sel,0);
sel=key;//选择这次选择的
Item_Sel(sel,1);
}else if(sel==key)//选择按钮,或者双击
{
Pro_Key_Alarm(sel);//操作
}
break;
case 9://确认按钮按下了
Alarm[index]=Alarm_Temp;
Save_Alarm(index);//保存特定编号的闹钟数据
Init_Alarm_Reg(); //更新闹钟寄存器
return; //保存并返回
case 10:return;//选择了"返回"按钮,返回一个不可能值
default:
if(sel==1)//时间输入
{
key=Get_KeyBoard_Val();
if(key==10&&AlarmTPos)AlarmTPos--;//退格操作
if(key<10)
{
switch(AlarmTPos)
{
case 0://修改小时的十位
Alarm_Temp.hour%=10;
Alarm_Temp.hour+=key*10;
if(Alarm_Temp.hour>23)Alarm_Temp.hour=23;
break;
case 1:
Alarm_Temp.hour/=10;
Alarm_Temp.hour*=10;
Alarm_Temp.hour+=key;
if(Alarm_Temp.hour>23)Alarm_Temp.hour=23;
break;
case 2://修改分钟的十位
if(key>5)key=5;
Alarm_Temp.min%=10;
Alarm_Temp.min+=key*10;
break;
case 3:
Alarm_Temp.min/=10;
Alarm_Temp.min*=10;
Alarm_Temp.min+=key;
break;
}
if(AlarmTPos<3)AlarmTPos++;//自动切换到下一个
}
Item_Sel(1,1);//更新显示数据
}else if(sel==2&&(((Alarm_Temp.Status)&0x03)==2))//自定义星期
{
key=Get_WeekBit_Val();
if(key<8)
{
key=8-key;
if(Alarm_Temp.WeekMark&(1<<key))
{
Alarm_Temp.WeekMark&=~(1<<key);
}else
{
Alarm_Temp.WeekMark|=(1<<key);
}
}
Item_Sel(2,1);
}
break;
}
key=0;//取消按键值
}
delay_ms(1);
}
}
//闹钟浏览
//相关闹钟的设置全部在这个函数里面了
void Alarm_Viewer(void)
{
u8 selx=0;
u8 t;
u8 *p=(u8 *)iclip;
ARST:
Read_Alarm(8);//获取闹钟数据
for(t=0;t<8;t++)Alarm_F1[t]=p+t*30;//地址映射到 Alarm_F1里面
for(t=0;t<8;t++)
{
Alarm_F1[t][0]=Alarm[t].hour/10+'0';
Alarm_F1[t][1]=Alarm[t].hour%10+'0';
Alarm_F1[t][2]=':';
Alarm_F1[t][3]=Alarm[t].min/10+'0';
Alarm_F1[t][4]=Alarm[t].min%10+'0';
Alarm_F1[t][5]='\0'; //添加结束符
}
while(1)
{
selx=Load_Fun_Sel((const u8 * *)Alarm_F1,"闹钟设置","编辑",8,selx);
if(selx==8)return;//返回
else
{
Set_Alarm(selx);//设置闹钟 goto ARST;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -