📄 rtc.c
字号:
//***************************************************************************************************
//Chinese Academy of Sciences, Institute of Automation
//File Name: RTC.c
//Description: RTC Test.
//Author: Lee JuGuang
//Date: 2004-2-10
//***************************************************************************************************
#include "s3c4510b_add.h"
#include "uart.h"
//#include "public.h"
#define PAGE_SIZE 8
#define IIC_DEV_0 0xa2 // RTC device's slave address
#define S_WRITE 0x00 // Write IIC data for slave
#define S_READ 0x01 // Read IIC data for slave
#define BF 0x01 // Buffer flag
#define IEN 0x02 // Interrupt enable
#define LRB 0x04 // Last bit received/ACK not received
#define ACK 0x08 // Ack enable/Generate an ACK signal at 9th SCL
#define NOACK 0x00
#define START 0x10
#define STOP 0x20
#define RESTART 0x30
#define BUSY 0x40
#define IICRESET 0x80
void Test_RTC(void);
static int DrvIicInit(void);
static int DrvIicRead(int addr, int size, int *pdata);
static int DrvIicWrite(int address, int size, int *pdata);
static void Delay(int);
static void Display_Current_Time(void);
static void Set_Current_Time(void);
static int DrvIicInit()
{
int error = 0;
// reset the ICC
IICCON = IICRESET;
// clock setup, ICC CLK = SysClk/(16 x (prescaker + 1) + 3), 100KHz at 50MHz
IICPS = 0x0000001E;
return error;
}
static int DrvIicRead(int addr, int size, int *pdata)
{
int error = 0, i;
// reset the ICC
DrvIicInit();
// wait for not busy
while(IICCON & BUSY);
// Send Start: START | ACK
IICCON = START | ACK;
// send control byte (write cmd): read block 0
IICBUF = IIC_DEV_0 | S_WRITE ;
while(!(IICCON & BF));
// send msb address
// IICBUF = (int)((addr>>8) & 0xFF);
// while(!(IICCON & 0x01));
// send lsb address
IICBUF = (int)(addr & 0xFF);
while(!(IICCON & BF));
// send re-start and control byte (read cmd)
IICCON = RESTART;
IICCON = START | ACK;
IICBUF = IIC_DEV_0 | S_READ ;
while(!(IICCON & BF));
// Generate ACK for multi read
IICCON = ACK;
while(!(IICCON & BF));
// Rx Data
for(i=0; i<size; i++)
{
*pdata++ = IICBUF;
while(!(IICCON & BF));
}
// Send NO ACK
IICCON = NOACK;
while(!(IICCON & BF));
// Send Stop
IICCON = STOP;
return error;
}
static int DrvIicWrite(int address, int size, int *pdata)
{
int i;
//int block;
// reset the ICC
DrvIicInit();
// wait for not busy
while(IICCON & BUSY);
// Send Start: START | ACK
IICCON = START | ACK;
// send control byte (write cmd): read block 0
IICBUF = IIC_DEV_0 | S_WRITE;
while(!(IICCON & BF));
// send msb address
// IICBUF = (tU8)((address>>8) & 0xFF);
// while(!(IICCON & 0x01));
// send lsb address
IICBUF = (int)(address & 0xFF);
while(!(IICCON & BF));
// Write data
for(i=0; i<size; i++)
{
IICBUF = *pdata++;
while(!(IICCON & BF));
}
// STOP IIC Controller
IICCON = STOP;
// 5 ms write cycle
Delay(5000);
return 0;
}
void Test_RTC(void)
{
unsigned char ch;
Loop1:
i_printf("\n\r\n\r\n\r");
i_printf("*************************************************************\n\r");
i_printf("* Please Input the Item: *\n\r");
i_printf("* [1] Display Current Time *\n\r");
i_printf("* [2] Set Current Time *\n\r");
i_printf("* [3] Exit *\n\r");
i_printf("*************************************************************\n\r");
while(1)
{
put_char(0, 0x0d);
ch=get_char(0);
switch(ch)
{
case '1':Display_Current_Time();
goto Loop1;
case '2':Set_Current_Time();
goto Loop1;
case '3':i_printf("\r\n\r\n");
return;
default:
{i_printf("\r\n");
goto Loop1;}
}
}
return;
}
static void Set_Current_Time(void)
{
char size[10];
int tmp[6]={0,0,0,0,0,0};
int i,k,Byte,t;
int a[7];
a[0]=0x0; //命令与状态寄存器
a[1]=0x0; //百分之一秒
a[2]=0x0; //秒
a[3]=0x0; //分
a[4]=0x0; //小时
a[5]=0x0; //年/日
a[6]=0x0; //周/月
//*********************************************************
//**** Here,We input the new time
//*********************************************************
i_printf("\r\n>>>Please Input New Time Value:");
for(Byte=0;Byte<6;Byte++)
{
if(Byte==0)
{i_printf("\r\n>>>Year(2004~2007) :");}
if(Byte==1)
{i_printf("\r\n>>>Month(1~12) :");}
if(Byte==2)
{i_printf("\r\n>>>Day(1~31) :");}
if(Byte==3)
{i_printf("\r\n>>>Hour(0~23) :");}
if(Byte==4)
{i_printf("\r\n>>>Minute(0~59) :");}
if(Byte==5)
{i_printf("\r\n>>>Second(0~59) :");}
i=0;
size[0]=get_char(0);
//等待用户的输入;
do
{
i_printf("%c",size[i]);
if(size[i]>'9'||size[i]<'0')
{
i_printf("\r\n\r\nSorry,Input Error!\r\n\r\n");
return;
}
i++;
size[i]=get_char(0);
}while(size[i]!=0x0d);
for(k=0;k<i;k++)
{
tmp[Byte]=tmp[Byte]*10+size[k]-'0';
}
}
//用户输入数据结束;
//在此检测输入数据的范围:年、月、日、时、分、秒;
if((tmp[0]>2007)||(tmp[0]<2004)) //Year
{
i_printf("\r\n\r\nSorry,Year Out of Range!\r\n\r\n");
return;
}
else if((tmp[1]>12)||(tmp[1]<1)) //Month
{
i_printf("\r\n\r\nSorry,Month Out of Range!\r\n\r\n");
return;
}
else if((tmp[2]>31)||(tmp[1]<1)) //Day
{
i_printf("\r\n\r\nSorry,Day Out of Range!\r\n\r\n");
return;
}
else if(tmp[3]>23) //Hour
{
i_printf("\r\n\r\nSorry,Hour Out of Range!\r\n\r\n");
return;
}
else if(tmp[4]>59) //minute
{
i_printf("\r\n\r\nSorry,Minute Out of Range!\r\n\r\n");
return;
}
else if(tmp[5]>59) //Second
{
i_printf("\r\n\r\nSorry,Second Out of Range!\r\n\r\n");
return;
}
//计算“年”的设定值:
a[5]=a[5]|((tmp[0]-2004)<<6);
//计算“月”的设定值:
t=tmp[1];
a[6]=a[6]|((t/10)<<4);
if(tmp[1]<10)
a[6]=a[6]|tmp[1];
else
a[6]=a[6]|(tmp[1]-10);
//计算“日”的设定值:
t=tmp[2];
a[5]=a[5]|((t/10)<<4);
t=tmp[2]-(tmp[2]/10)*10;
a[5]=a[5]|t;
//计算“时”的设定值:
t=tmp[3];
a[4]=a[4]|((t/10)<<4);
t=tmp[3]-(tmp[3]/10)*10;
a[4]=a[4]|t;
//计算“分”的设定值:
t=tmp[4];
a[3]=a[3]|((t/10)<<4);
t=tmp[4]-(tmp[4]/10)*10;
a[3]=a[3]|t;
//计算“秒”的设定值:
t=tmp[5];
a[2]=a[2]|((t/10)<<4);
t=tmp[5]-(tmp[5]/10)*10;
a[2]=a[2]|t;
// 将时间值写入RTC;
DrvIicInit();
i=DrvIicWrite(0x0,7,a);
Delay(10000);
i_printf("\r\n\r\n\r\n>>>Time Set OK!\r\n\r\n");
return;
}
//*******************************************************************
//功能描述: 显示当前时间。
//*******************************************************************
static void Display_Current_Time(void)
{
unsigned char tmp;
int i,j;
int a[7];
a[0]=0x0; //命令与状态寄存器
a[1]=0x0; //百分之一秒
a[2]=0x0; //秒
a[3]=0x0; //分
a[4]=0x0; //小时
a[5]=0x0; //年/日
a[6]=0x0; //周/月
i_printf("\r\n>>>Current Time: ");
DrvIicInit();
//对RTC的寄存器0(命令与状态寄存器)进行初始化,0x0
i=DrvIicWrite(0x0,1,a);
//读取当前时间(时、分、秒),循环显示
while(1){
i=DrvIicRead(0x0,7,a);
//Year
put_char(0,0x32); //'2'
put_char(0,0x30); //'0'
put_char(0,0x30); //'0'
tmp=a[5]; //0~3,最多计4年
tmp=(tmp>>6)&0x03;
put_char(0,tmp+0x34);
put_char(0,'/');
tmp=a[6]; //月的十位;
if(tmp&0x10)
put_char(0,'1');
else
put_char(0,'0');
tmp=a[6]; //月的个位;
tmp=tmp&0xf;
put_char(0,tmp+0x30);
put_char(0,'/');
tmp=a[5]; //日的十位;
tmp=(tmp>>4)&0x03;
put_char(0,tmp+0x30);
tmp=a[5]; //日的个位;
tmp=tmp&0x0f;
put_char(0,tmp+0x30);
put_char(0,' ');
put_char(0,' ');
tmp=a[4]; //时的十位;
tmp=(tmp>>4)&0x03;
put_char(0,tmp+0x30);
tmp=a[4]; //时的个位;
tmp=tmp&0x0f;
put_char(0,tmp+0x30);
put_char(0,':');
tmp=a[3]; //分的十位;
tmp=(tmp>>4)&0x0f;
put_char(0,tmp+0x30);
tmp=a[3]; //分的个位;
tmp=tmp&0x0f;
put_char(0,tmp+0x30);
put_char(0,':');
tmp=a[2]; //秒的十位;
tmp=(tmp>>4)&0x0f;
put_char(0,tmp+0x30);
tmp=a[2]; //秒的个位;
tmp=tmp&0x0f;
put_char(0,tmp+0x30);
//调整显示位置
for(i=0;i<20;i++)
{
put_char(0,'\b');
}
for(j=0;j<255;j++)
{
Delay(10000);
}
if(kbd_hit())
{
i_printf("\r\n\r\n\r\n");
return;
}
}
}
static void Delay(int x)
{
int i;
for(i=x;i>=0;i--)
;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -