📄 fm3104.c
字号:
#include "Clock.h"
void InitRtc(void)
{
ClearDog(); //Clear LB bit
SetCurrentAddress(0x00d0,0x000b); //Clear VBC bit
WriteAByte(0);
ReceiveI2CAck();
StopI2C();
SetCurrentAddress(0x00d0,0x0001); //Clear OSCEN bit
WriteAByte(0);
ReceiveI2CAck();
StopI2C();
EnableDog();
}
void StartRtc(UWORD cal)
{
SetCurrentAddress(0x00d0,0x0001); //CAL/CONTROL
WriteAByte(cal);
ReceiveI2CAck();
StopI2C();
}
void ReadRtc(void)
{
UWORD i,*ptr=&Clock.Second;
SetCurrentAddress(0x00d0,0);
WriteAByte(0);
ReceiveI2CAck();
StopI2C();
SetCurrentAddress(0x00d0,0);
WriteAByte(0x0001);
ReceiveI2CAck();
StopI2C();
SetCurrentAddress(0x00d0,0x0002);
ReadBytes(0x00d1,&Clock.Second,7);
for(i=0;i<7;i++)
{
*ptr=((*ptr)&0x000f)+((*ptr)>>4)*10;
ptr++;
}
if(Clock.Year>99)Clock.Year=0;
if((Clock.Month>12)||(Clock.Month==0))Clock.Month=1;
if((Clock.Day>31)||(Clock.Day==0))Clock.Day=1;
if(Clock.Hour>23)Clock.Hour=0;
if(Clock.Minute>59)Clock.Minute=0;
if(Clock.Second>59)Clock.Second=0;
}
void WriteRtc(void)
{
UWORD i,*ptr=&Clock.Second;
for(i=0;i<7;i++)
{
*ptr=(((*ptr)/10)<<4)+(*ptr)%10;
ptr++;
}
SetCurrentAddress(0x00d0,0);
WriteAByte(0x0002);
ReceiveI2CAck();
StopI2C();
SetCurrentAddress(0x00d0,0x0002);
WriteBytes(&Clock.Second,7);
SetCurrentAddress(0x00d0,0);
WriteAByte(0);
ReceiveI2CAck();
StopI2C();
}
void ReadEeprom(UWORD address,UWORD *buffer,UWORD n)
{
UWORD i;
ClearDog();
SetCurrentAddress(0x00a0,address);
StartI2C();
WriteAByte(0x00a1);
ReceiveI2CAck();
for(i=0;i<n;i++)
{
*buffer=ReadAByte();
SendI2CAck();
*buffer+=(ReadAByte())<<8;
if(i==(n-1))SendI2CNAck();
else SendI2CAck();
buffer++;
}
StopI2C();
}
void WriteEeprom(UWORD address,UWORD *buffer,UWORD n)
{
UWORD i;
ClearDog();
SetCurrentAddress(0x00a0,address);
for(i=0;i<n;i++)
{
WriteAByte(*buffer);
ReceiveI2CAck();
WriteAByte((*buffer)>>8);
ReceiveI2CAck();
buffer++;
}
StopI2C();
}
void EnableDog(void)
{
SetCurrentAddress(0x00d0,0x000a);
WriteAByte(0x0083); //300ms
ReceiveI2CAck();
StopI2C();
}
void DisableDog(void)
{
SetCurrentAddress(0x00d0,0x000a);
WriteAByte(0);
ReceiveI2CAck();
StopI2C();
}
void ClearDog(void)
{
SetCurrentAddress(0x00d0,0x0009);
WriteAByte(0x000a);
ReceiveI2CAck();
StopI2C();
}
/* ///////////////////////////// */
void StartI2C(void)
{
DIR_OUT;
SCL_0;
SDA_1;
Delay(1);
SCL_1;
Delay(1);
SDA_0;
Delay(1);
SCL_0;
Delay(1);
}
void StopI2C(void)
{
DIR_OUT;
SDA_0;
Delay(1);
SCL_1;
Delay(1);
SDA_1;
Delay(1);
SCL_0;
Delay(1);
}
//Write low 8 bit
void WriteAByte(UWORD data)
{
UWORD i;
DIR_OUT;
for(i=0;i<8;i++)
{
SCL_0;
Delay(1);
if((data>>7)&0x0001)SDA_1;
else SDA_0;
Delay(1);
SCL_1;
data<<=1;
Delay(1);
}
SCL_0;
Delay(1);
}
UWORD ReadAByte(void)
{
UWORD i,bit=0,data=0;
DIR_IN;
SCL_0;
Delay(1);
for(i=0;i<8;i++)
{
SCL_1;
Delay(1);
if(SDA_IN)bit=1;
else bit=0;
data=(data<<1)|bit;
SCL_0;
Delay(1);
}
return(data);
}
/*Return: TRUE -Right ACK
FLASE -no ACK*/
UWORD ReceiveI2CAck(void)
{
UWORD i=1000;
SDA_1;
DIR_IN;
SCL_1;
Delay(1);
while(SDA_IN)
{
if(!(--i))
{
SCL_0;
return(FALSE);
}
}
SCL_0;
Delay(1);
return(TRUE);
}
void SendI2CAck(void)
{
SCL_0;
Delay(1);
DIR_OUT;
SDA_0;
SCL_1;
Delay(1);
SCL_0;
Delay(1);
}
void SendI2CNAck(void)
{
SCL_0;
Delay(1);
DIR_OUT;
SDA_1;
SCL_1;
Delay(1);
SCL_0;
Delay(1);
}
/* RTC: slave=0x00d0
EEPROM: slave=0x00a0*/
void SetCurrentAddress(UWORD slave,UWORD address)
{
StartI2C();
WriteAByte(slave);
ReceiveI2CAck();
if(slave==0x00a0)
{
WriteAByte(address>>8);
ReceiveI2CAck();
}
WriteAByte(address);
ReceiveI2CAck();
}
/* RTC: slave=0x00d1
EEPROM: slave=0x00a1*/
void ReadBytes(UWORD slave,UWORD *buffer,UWORD n)
{
UWORD i;
StartI2C();
WriteAByte(slave);
ReceiveI2CAck();
for(i=0;i<n;i++)
{
*buffer++=ReadAByte();
if(i==(n-1))SendI2CNAck();
else SendI2CAck();
}
StopI2C();
}
/* RTC: slave=0x00d0
EEPROM: slave=0x00a0*/
void WriteBytes(UWORD *buffer,UWORD n)
{
UWORD i;
for(i=0;i<n;i++)
{
WriteAByte(*buffer++);
ReceiveI2CAck();
}
StopI2C();
}
//1-380ns
void Delay(UWORD xms)
{
while(xms--)Factor++;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -