⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 alarm.c

📁 基于stm32的MP3播放器
💻 C
📖 第 1 页 / 共 2 页
字号:

//处理闹钟中断后的进程
//执行中断里面闹钟的处理
//重新把下一个最近的闹钟值写入闹钟寄存器
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 + -