?? 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 + -