#include "COMM.H"
//闹钟部分代码
//正点原子@SCUT
//全局变量区域
//闹钟结构体
typedef struct
{
u8 Status; //状态寄存器 bit3,ON/OFF;bit2 RING/FM;bit 1,0 ONCE/EVERY DAY/SELF DEFINE
u8 WeekMark;//自定义标志
u8 Ring; //闹铃声编号
u8 hour;
u8 min;
u8 Ring_Name[9];
u32 Ring_Addr;
}AlarmStruct;
AlarmStruct Alarm[8]; //闹钟暂存
AlarmStruct Alarm_Temp; //零时寄存区
u8 AlarmInLine=0;//在闹钟寄存器中的闹铃编号 0~7
u8 *Alarm_F1[8];//时间数据缓存区 XX:XX +'\0' 用于数据显示
//存储铃声
//存储地址区间:300~411 总共112个字节
//type :铃声类型 0,MP3,1,FM
//Rnum :铃声编号 0~7
//RingN:铃声名字短文件名 对MP3
//RAddr:铃声地址/FM频率
void Save_Ring(u8 type,u8 RNum,u8 *RingN,u32 RAddr)
{
u8 i;
if(type)//FM收音机 保存 103.6 (1036)之类的数据,占两个字节
{
FM24C16_WriteOneByte(396+RNum*2+0,(RAddr>>8)&0xff);
FM24C16_WriteOneByte(396+RNum*2+1,RAddr&0xff);
}else
{
for(i=0;i<8;i++)FM24C16_WriteOneByte(300+RNum*12+i,RingN[i]);//把歌曲名字保存
FM24C16_WriteOneByte(300+RNum*12+8,(RAddr>>24)&0xff); //保存地址StartCluster
FM24C16_WriteOneByte(300+RNum*12+9,(RAddr>>16)&0xff);
FM24C16_WriteOneByte(300+RNum*12+10,(RAddr>>8)&0xff);
FM24C16_WriteOneByte(300+RNum*12+11,RAddr&0xff);
}
}
//读取铃声
//地址区间:300~411 总共112个字节
//type :铃声类型
//Rnum :铃声编号
//RingN:铃声名字短文件名 对MP3
//RAddr:铃声地址/FM频率
void Read_Ring(u8 type,u8 RNum,u8 *RingN,u32 *RAddr)
{
u8 i;
u8 temp[4];
if(type)//FM收音机 读取 103.6 (1036)之类的数据,占两个字节
{
temp[0]=FM24C16_ReadOneByte(396+RNum*2+0);
temp[1]=FM24C16_ReadOneByte(396+RNum*2+1);
*RAddr=(u32)temp[0]<<8;
*RAddr+=temp[1];
}else for(i=0;i<8;i++)
{
for(i=0;i<8;i++)*RingN++=FM24C16_ReadOneByte(300+RNum*12+i);
*RingN='\0';//添加结束符
temp[0]=FM24C16_ReadOneByte(300+RNum*12+8);
temp[1]=FM24C16_ReadOneByte(300+RNum*12+9);
temp[2]=FM24C16_ReadOneByte(300+RNum*12+10);
temp[3]=FM24C16_ReadOneByte(300+RNum*12+11);
*RAddr=(u32)temp[0]<<24;
*RAddr+=(u32)temp[1]<<16;
*RAddr+=(u32)temp[2]<<8;
*RAddr+=temp[3];
}
}
//存储闹钟数据
//存储地址区间:260~299 总共40个字节
//alx:要保存的编号 0~7,>=8,全部保存
void Save_Alarm(u8 alx)
{
u8 i;
if(alx<8)
{
FM24C16_WriteOneByte(260+alx*5,Alarm[alx].Status);
FM24C16_WriteOneByte(261+alx*5,Alarm[alx].WeekMark);
FM24C16_WriteOneByte(262+alx*5,Alarm[alx].Ring);
FM24C16_WriteOneByte(263+alx*5,Alarm[alx].hour);
FM24C16_WriteOneByte(264+alx*5,Alarm[alx].min);
Save_Ring(Alarm[alx].Status&0x04,Alarm[alx].Ring,Alarm[alx].Ring_Name,Alarm[alx].Ring_Addr); //保存MP3信息到相应的地址
}else for(i=0;i<8;i++)
{
FM24C16_WriteOneByte(260+i*5,Alarm[i].Status);
FM24C16_WriteOneByte(261+i*5,Alarm[i].WeekMark);
FM24C16_WriteOneByte(262+i*5,Alarm[i].Ring);
FM24C16_WriteOneByte(263+i*5,Alarm[i].hour);
FM24C16_WriteOneByte(264+i*5,Alarm[i].min);
Save_Ring(Alarm[alx].Status&0x04,Alarm[alx].Ring,Alarm[alx].Ring_Name,Alarm[alx].Ring_Addr); //保存MP3信息到相应的地址
}
}
//读取闹钟数据
//存储地址区间:260~299 总共40个字节
//alx:要读取的编号 0~7,>=8,全部读取
void Read_Alarm(u8 alx)
{
u8 i;
if(alx<8)
{
Alarm[alx].Status=FM24C16_ReadOneByte(260+alx*5);
Alarm[alx].WeekMark=FM24C16_ReadOneByte(261+alx*5);
Alarm[alx].Ring=FM24C16_ReadOneByte(262+alx*5);
Alarm[alx].hour=FM24C16_ReadOneByte(263+alx*5);
Alarm[alx].min=FM24C16_ReadOneByte(264+alx*5);
Read_Ring(Alarm[alx].Status&0x04,Alarm[alx].Ring,Alarm[alx].Ring_Name,&Alarm[alx].Ring_Addr);//读取闹钟铃声信息
}else for(i=0;i<8;i++)
{
Alarm[i].Status=FM24C16_ReadOneByte(260+i*5);
Alarm[i].WeekMark=FM24C16_ReadOneByte(261+i*5);
Alarm[i].Ring=FM24C16_ReadOneByte(262+i*5);
Alarm[i].hour=FM24C16_ReadOneByte(263+i*5);
Alarm[i].min=FM24C16_ReadOneByte(264+i*5);
Read_Ring(Alarm[i].Status&0x04,Alarm[i].Ring,Alarm[i].Ring_Name,&Alarm[i].Ring_Addr);//读取闹钟铃声信息
}
}
//初始化闹钟寄存器
//把闹钟0~7中的闹钟值取一个与当前时间最接近的放在闹钟寄存器里面
void Init_Alarm_Reg(void)
{
u8 i;
u8 temp;
u32 curtime=0;
u32 temptime=0;
u32 destime=0XFFFFFFFF;//设定到最大
u8 weekx;
u8 weektemp;
u8 t;
rtc_get();//得到时间
GetWeek(timer.w_year,timer.w_month,timer.w_date,&weekx);//得到星期 0~6 代表周末到周六
weekx=8-weekx;//与weekmark标志匹配
if(weekx==8)weekx=1;//周末处理
curtime=RTC->CNTH;//得到计数器中的值(秒钟数)
curtime<<=16;
curtime+=RTC->CNTL;
//取一个与当前时间最接近的值作为闹钟寄存器的内容
for(i=0;i<8;i++)
{
temptime=curtime/86400; //得到当前运行天数
temptime=temptime*86400;
temptime+=(u32)Alarm[i].hour*3600+(u32)Alarm[i].min*60;//得到秒钟数
temp=Alarm[i].Status;
if(temp&0x08)//闹钟开启了
{
temp&=0x03;
switch(temp)
{
case 0://闹铃一次
case 1:
if(temptime<=curtime)temptime+=86400;//执行时间已过,推迟到明天
if(temptime<destime)
{
destime=temptime;//更改闹钟寄存器
AlarmInLine=i;//记录保存在闹钟寄存器中的闹钟编号
}
break;
case 2://自定义闹钟
temp=Alarm[i].WeekMark;//周标记
if((temp&(1<<weekx))&&(temptime>curtime))//有标记当前的星期,且时间没有超过
{
if(temptime<destime)
{
destime=temptime;//更改闹钟寄存器
AlarmInLine=i;//记录保存在闹钟寄存器中的闹钟编号
}
}else
{
weektemp=weekx;
t=0;
while(1)
{
weektemp--;
if(weektemp<1)weektemp=7;
t++;
if(temp&(1<<weektemp))//有标记了
{
temptime+=(u32)t*86400;//更改闹钟寄存器,推后了t天
if(temptime<destime)
{
destime=temptime;
AlarmInLine=i;//记录保存在闹钟寄存器中的闹钟编号
}
break;
}
if(weektemp==weekx)break;//经过了一个循环
}
}
break;
}
}
}
//读取闹钟铃声信息
Read_Ring(Alarm[AlarmInLine].Status&0x04,Alarm[AlarmInLine].Ring,Alarm[AlarmInLine].Ring_Name,&Alarm[AlarmInLine].Ring_Addr);
printf("Alarm Num:%d\n",Alarm[AlarmInLine].Ring);//下一个闹钟的编号
printf("Alarm Addr:%d\n",Alarm[AlarmInLine].Ring_Addr);//下一个闹钟的编号
printf("Alarm Name:%s\n",Alarm[AlarmInLine].Ring_Name);//下一个闹钟的编号
printf("AlarmInLine:%d\n",AlarmInLine);//下一个闹钟的编号
//设置闹钟寄存器
RCC->APB1ENR|=1<<28;//使能电源时钟
RCC->APB1ENR|=1<<27;//使能备份时钟
PWR->CR|=1<<8; //取消备份区写保护
//上面三步是必须的!
RTC->CRL|=1<<4; //允许配置
RTC->ALRL=destime&0xffff;
RTC->ALRH=destime>>16;
RTC->CRL&=~(1<<4);//配置更新
while(!(RTC->CRL&(1<<5)));//等待RTC寄存器操作完成
}
//显示FM频道信息
u16 Ring_Fm_Show(u8 rch)
{
u16 freqdiv;
BACK_COLOR=WHITE;
POINT_COLOR=BLACK;
TFT_ShowNum(136,114,rch,16,0x00); //显示频道值
freqdiv=FM24C16_ReadOneByte(60+rch*2);//读取高位
freqdiv<<=8;//得到高位数据
freqdiv+=FM24C16_ReadOneByte(60+(rch*2)+1);//读取低位
if(freqdiv>=10000)TFT_ShowChar(104,146,freqdiv/10000+'0',16,0x00);//在指定位置显示一个字符
else TFT_ShowChar(104,146,' ',16,0x00);//在指定位置显示一个字符
TFT_ShowChar(104,146,(freqdiv/1000)%10+'0',16,0x00);//在指定位置显示一个字符
TFT_ShowChar(112,146,(freqdiv/100)%10+'0',16,0x00);//在指定位置显示一个字符
TFT_ShowChar(120,146,'.',16,0x00);//在指定位置显示一个字符
TFT_ShowChar(128,146,(freqdiv/10)%10+'0',16,0x00);//在指定位置显示一个字符
return freqdiv;//返回频率值
}
//设置闹铃/FM频率
void Set_Alarm_Ring(void)
{
FileInfoStruct RingInfo;
u16 index;
u32 curdir=0;
u8 key;
u8 Ch_Num;//频道总数
u8 CH_Val=0;
Load_Gui_Bro("完成");//显示GUI界面
if(Alarm_Temp.Status&0x04)//收音机作为铃声
{
Ch_Num=FM24C16_ReadOneByte(58);//保存USA频段最大电台数 sCh_Num
if(Ch_Num==0)//没有频率供