📄 rtc.c
字号:
/****************************
*Copyright (c)2005,安安科技
*Product name:Intelligent life system
*DOCUMENT<<rtc.c>>
*auther:Charlie.Yi
*data :2006/12/12
****************************/
#include "USER_DEFINE.H"
//***************************************
//***时间日期数据还原处理****
struct time_asicc idata time_ram;
//RTC读取时间值/所有的时间寄存器
void Read_RTC_Time(void)
{
bit ack; //定义i2c的应答位。
uchar i_r_r=6,read_data,Previous_date,Previous_minute,Previous_second; //Previous_minute;
Previous_second=time_s3530[0]; //当前秒钟
Previous_minute=time_s3530[1]; //当前分钟
Previous_date=time_s3530[4]; //当前日期
I2C_Start();
ack=I2C_Send_Byte(S3530|0x05); //发送数据(控制位) 0x65 读模式 1
if(ack)while(1);
else
do
{
read_data=I2C_Receive_Byte();
read_data=Swap_Byte(read_data);//从RTC读出的数是高位与低位倒置的,故需要将其反过来。
time_s3530[i_r_r]=read_data;
I2C_ack(); //发送应答位,告知RTC MCU已经成功接收到一个数据
}while(i_r_r--);
I2C_Nack(); //发送应答位.在读取数据时,当数据为最后一个时)
I2C_Stop();
time_s3530[0]=time_s3530[0]&0x7f; //秒
time_s3530[1]=time_s3530[1]&0x7f; //分
time_s3530[2]=time_s3530[2]&0x3f; //时
time_s3530[3]=time_s3530[3]&0x07; //星期
time_s3530[4]=time_s3530[4]&0x3f; //日
time_s3530[5]=time_s3530[5]&0x1f; //月
//time_s3530[5]=time_s3530[6]&0xff; 年
if (Previous_date!=time_s3530[4]) b_REFRESH_DATE_flag=1; //Refurbish_Date_display
else if(Previous_minute!=time_s3530[1])b_REFRESH_SECOND_flag=b_REFRESH_MINUTE_flag=1;//Refurbish_Minute_Display
else if(Previous_second!=time_s3530[0])b_REFRESH_SECOND_flag=1; //Refurbish_Second_Display
return;
}
//********************************************
//**************RTC写入时间值*****************
void write_rtc_time(void)
{
uchar i_r_w=6;
bit ack;
uchar write_data;
time_s3530[0]=0;
I2C_Start();
ack=I2C_Send_Byte(S3530|0x04); //发送数据(控制位) 0x64 写模式" 0"
if(ack)while(1);
else
do
{
write_data=Swap_Byte(time_s3530[i_r_w]);
ack=I2C_Send_Byte(write_data);
if(ack)while(1);
Delay1ms(80);
}while(i_r_w--);
I2C_Nack(); //发送应答位 (在读取数据时,当数据为最后一个时)
I2C_Stop();
}
//******************************************
//**************RTC 初始化**************
void Initial_RTC(void)
{
bit ack;
uchar read_data;
I2C_Start();
ack=I2C_Send_Byte(0x61); //发送读控制位 0x61=读状态寄存器1
if(ack)while(1);
read_data=I2C_Receive_Byte(); //读状态寄存器值。
I2C_Nack(); //发送应答位(在读取数据时)no ack
I2C_Stop();
//**************写状态寄存器************
//地址与控制字节是从最高位先传,数据是低位先传。
//最高位与最低位依次对调。(因为s3530最先传送的是最低位)
//*****************************************************
if(read_data&0x01) //对S3530状态位POWER进行检测。如果POWER=“1”
{ //刚开启电源,对S3530进行初始化。
//******复位-写状态寄存器1*******
I2C_Start();
ack=I2C_Send_Byte(0x60); //发送写控制位 0x60=写状态寄存器1
if(ack)while(1);
ack=I2C_Send_Byte(0xc0); //写控制位(0xc0)复位操作并设定时间为24小时制
if(ack)while(1);
I2C_Stop();
Delay1ms(0xff);
//*************状态设置2*************
I2C_Start();
ack=I2C_Send_Byte(0x62); //发送写控制位 0x62=写状态寄存器2
if(ack)while(1);
ack=I2C_Send_Byte(0x80); //0x10=32khz; 0xc0=每分钟变化一次;0x80=固定频率输出.
if(ack)while(1);
I2C_Stop();
Delay1ms(0xff);
//**********写INT1寄存器1************
I2C_Start();
ack=I2C_Send_Byte(0x68); //发送写控制位,写INT1寄存器1
if(ack)while(1);
ack=I2C_Send_Byte(0x40); //设定输出频率 =每秒16次)
if(ack)while(1);
I2C_Stop();
//for(read_data=0;read_data<7;read_data++)time_s3530[read_data]=time_code[read_data];
write_rtc_time(); //写入新的系统时间。
Delay1ms(0xff);
}
else Delay1ms(0xff);
return;
}
//************************************************
//***********设定RTC的频率输出*********
void Set_Rtc_Status_Register(uchar a)
{
bit ack;
//*************状态设置*************
I2C_Start();
ack=I2C_Send_Byte(0x62); //发送写控制位 0x62=写状态寄存器2
if(ack)while(1);
ack=I2C_Send_Byte(0x80); //0x10=32khz; 0xc0=每分钟变化一次;0x80=固定频率输出.
if(ack)while(1);
I2C_Stop();
Delay1ms(0xff);
//**********写INT1寄存器1************
I2C_Start();
ack=I2C_Send_Byte(0x68); //发送写控制位,写INT1寄存器1
if(ack)while(1);
ack=I2C_Send_Byte(a); //设定输出频率(0x20=每秒4次,0x40=每秒2次,0x80=每秒1次)
if(ack)while(1);
I2C_Stop();
Delay1ms(0x04);
}
//**************************************
//***************日期显示*****************
void Date_display(void)
{
time_ram.year[1]=time_s3530[6]>>4;
time_ram.year[0]=time_s3530[6]&0x0f; //年
time_ram.month[1]=time_s3530[5]>>4;
time_ram.month[0]=time_s3530[5]&0x0f; //月
time_ram.day[1]=time_s3530[4]>>4;
time_ram.day[0]=time_s3530[4]&0x0f; //日
time_ram.week=time_s3530[3]&0x0f; //星期
//*******************************************
switch(KeyFuncIndex) //有分系统时间/日期显示模式和时间/日期设定模式
{
case 10: //系统时间的日期设定显示
case 80:
case 81:
case 82:
case 83:
case 84: //在KeyFuncIndex=10 or =83 or =84都运行相同的的函数。
{
LCD_ShowString(0x82,"20",2);
LCD_ShowData(0x84,time_ram.year[1],1,0); //年
LCD_ShowData(0x85,time_ram.year[0],1,0);
LCD_ShowString(0x86,"/",1);
LCD_ShowData(0x87,time_ram.month[1],1,0); //月
LCD_ShowData(0x88,time_ram.month[0],1,0);
LCD_ShowString(0x89,"/",1);
LCD_ShowData(0x8a,time_ram.day[1],1,0); //日
LCD_ShowData(0x8b,time_ram.day[0],1,0);
LCD_ShowString(0x8c," W",3);
LCD_ShowData(0x8f,time_ram.week,1,0); //星期
}
break;
case 93: case 94: case 95: case 96:case 97: //闹钟时间的日期设定显示
{
if(time_s3530[6]==0xbb)LCD_ShowString(0x82,"----",4);
else
{
LCD_ShowString(0x82,"20",2);
LCD_ShowData(0x84,time_ram.year[1],1,0); //年
LCD_ShowData(0x85,time_ram.year[0],1,0);
}
LCD_ShowString(0x86,"/",1);
if(time_s3530[5]==0xbb)LCD_ShowString(0x87,"--",2);
else
{
LCD_ShowData(0x87,time_ram.month[1],1,0); //月
LCD_ShowData(0x88,time_ram.month[0],1,0);
}
LCD_ShowString(0x89,"/",1);
if(time_s3530[4]==0xbb)LCD_ShowString(0x8a,"--",2);
else
{
LCD_ShowData(0x8a,time_ram.day[1],1,0); //日
LCD_ShowData(0x8b,time_ram.day[0],1,0);
}
LCD_ShowString(0x8c," ",2);
LCD_ShowString(0x8e,"W",4);
if(time_s3530[3]==0x8b)LCD_ShowString(0x8f,"-",1);
else LCD_ShowData(0x8f,time_ram.week,1,0); //星期
}
break;
default: //系统日期显示
{
LCD_ShowString(0xc2,"20",2);
LCD_ShowData(0xc4,time_ram.year[1],1,0); //年
LCD_ShowData(0xc5,time_ram.year[0],1,0);
LCD_ShowString(0xc6,"/",1);
LCD_ShowData(0xc7,time_ram.month[1],1,0); //月
LCD_ShowData(0xc8,time_ram.month[0],1,0);
LCD_ShowString(0xc9,"/",1);
LCD_ShowData(0xca,time_ram.day[1],1,0); //日
LCD_ShowData(0xcb,time_ram.day[0],1,0);
LCD_ShowString(0xcc," W",3);
LCD_ShowData(0xcf,time_ram.week,1,0); //星期
}
break;
}
b_REFRESH_DATE_flag=0;
}
//********************************************
//**************时间显示****************
void time_display(void)
{
time_ram.hour[1]=(time_s3530[2]>>4)&0x03;
time_ram.hour[0]=time_s3530[2]&0x0f; //时
time_ram.minute[1]=time_s3530[1]>>4;
time_ram.minute[0]=time_s3530[1]&0x0f; //分
time_ram.sencond[1]=(time_s3530[0]>>4)&0x0f;
time_ram.sencond[0]=time_s3530[0]&0x0f; //秒
LCD_ShowData(0x85,time_ram.hour[1],1,0); //时
LCD_ShowData(0x86,time_ram.hour[0],1,0);
LCD_ShowString(0x87,":",1); //秒指针
LCD_ShowData(0x88,time_ram.minute[1],1,0); //分
LCD_ShowData(0x89,time_ram.minute[0],1,0);
LCD_ShowString(0x8b,"|",1); //秒指针
LCD_ShowData(0x8c,time_ram.sencond[1],1,0); //秒
LCD_ShowData(0x8d,time_ram.sencond[0],1,0);
if(b_REFRESH_DATE_flag)Date_display();//如果需要显示日期,则可以知道目前是刚刚切换到时间显示菜单或者是日期更新显示.
}
//****************************************************
//**************时间日期设定**********************
//***********时间日期设定*************
void Hour_set_adding(void)
{
uchar i;
time_s3530[2]++;
if(time_s3530[2]>0x23)time_s3530[2]=0;
else {
i=time_s3530[2]&0x0f;;
if(i>9)time_s3530[2]=(time_s3530[2]&0xf0)+0x10;
}
time_ram.hour[1]=(time_s3530[2]>>4)&0x0f;
time_ram.hour[0]=time_s3530[2]&0x0f; //时
LCD_ShowData(0x85,time_ram.hour[1],1,0); //时
LCD_ShowData(0x86,time_ram.hour[0],1,0);
}
void Hour_set_decrease(void)
{
uchar i;
time_s3530[2]--;
if(time_s3530[2]<0)time_s3530[2]=0x23;
// else if(time_s3530[2]>0x23)time_s3530[2]=0;
else {
i=time_s3530[2]&0x0f;
if(i>9)time_s3530[2]=(time_s3530[2]&0xf0)+0x09;
}
time_ram.hour[1]=(time_s3530[2]>>4)&0x0f;;
time_ram.hour[0]=time_s3530[2]&0x0f;; //时
LCD_ShowData(0x85,time_ram.hour[1],1,0); //时
LCD_ShowData(0x86,time_ram.hour[0],1,0);
}
//********************************
void Minute_set_adding(void)
{
uchar i;
time_s3530[1]++;
if(time_s3530[1]>0x59)time_s3530[1]=0;
else {
i=time_s3530[1]&0x0f;
if(i>9)time_s3530[1]=(time_s3530[1]&0xf0)+0x10;
}
time_ram.minute[1]=(time_s3530[1]>>4)&0x0f;
time_ram.minute[0]=time_s3530[1]&0x0f; //分
LCD_ShowData(0x88,time_ram.minute[1],1,0); //分
LCD_ShowData(0x89,time_ram.minute[0],1,0);
}
void Minute_set_decrease(void)
{
uchar i;
time_s3530[1]--;
if(time_s3530[1]<0)time_s3530[1]=0x59;
// else if(time_s3530[1]>0x59)time_s3530[1]=0;
else {
i=time_s3530[1]&0x0f;
if(i>9)time_s3530[1]=(time_s3530[1]&0xf0)+0x09;
}
time_ram.minute[1]=(time_s3530[1]>>4)&0x0f;
time_ram.minute[0]=time_s3530[1]&0x0f; //分
LCD_ShowData(0x88,time_ram.minute[1],1,0); //分
LCD_ShowData(0x89,time_ram.minute[0],1,0);
}
//****************
void Sencond_set_adding(void)
{
uchar i;
time_s3530[0]++;
if(time_s3530[0]>0x59)time_s3530[0]=0;
else {
i=time_s3530[0]&0x0f;
if(i>9)time_s3530[0]=(time_s3530[0]&0xf0)+0x10;
}
time_ram.sencond[1]=(time_s3530[0]>>4)&0x0f;
time_ram.sencond[0]=time_s3530[0]&0x0f; //秒
LCD_ShowData(0x8c,time_ram.sencond[1],1,0); //秒
LCD_ShowData(0x8d,time_ram.sencond[0],1,0);
}
void Sencond_set_decrease(void)
{
uchar i;
time_s3530[0]--;
if(time_s3530[0]<0)time_s3530[0]=0x59;
// else if(time_s3530[0]>0x59)time_s3530[0]=0;
else {
i=time_s3530[0]&0x0f;
if(i>9)time_s3530[0]=(time_s3530[0]&0xf0)+0x09;
}
time_ram.sencond[1]=(time_s3530[0]>>4)&0x0f;
time_ram.sencond[0]=time_s3530[0]&0x0f; //秒
LCD_ShowData(0x8c,time_ram.sencond[1],1,0); //秒
LCD_ShowData(0x8d,time_ram.sencond[0],1,0);
}
//****************
/*************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -