📄 fpc8583.c
字号:
CLOCK_SDA=0;
CLOCK_SCL=0;
}
else
{
asm(" nop ");
asm(" nop ");
asm(" nop ");/*添加应答错误处理程序*/
}
EALLOW;
CLOCK_SDADIR = 1; //SDA Input
EDIS;
}
void master_ack()
{
//PFDATDIR = PFDATDIR & DATAL; /*SDA=0*/
CLOCK_SDA=0;
no_ack();
}
void no_ack()
{
//PFDATDIR = PFDATDIR | CLOCKH; /*SCL=1*/
CLOCK_SCL=1;
iic_dly();
//PFDATDIR = PFDATDIR & CLOCKL; /*SCL=0*/
CLOCK_SCL=0;
}
void iic_dly()
{
//asm(" rpt #1h ");
delay(360);
asm(" nop ");
asm(" nop ");
}
void init_8583()
{
//DEVSELWR=0xA0; /*I2C器件写操作命*/
//DEVSELRD=0xA1; /*I2C器件读操作命令*/
DATAH=0x0004; /*数据线SDA=1 (IOPf2)*/
DATAL=0xFFFB; /*SDA=0*/
CLOCKH=0x0002; /*时钟线SCL=1 (IOPF1)*/
CLOCKL=0xFFFD; /*SCL=0*/
DATACLOCKH=0x0006; /*SDA=SCL=1*/
DATACLOCKL=0xFFF9; /*SDA=SCL=0*/
DATAINPUT=0xFBFF; /*PFDATDIR.11=0,即IOPF2引脚作为输入*/
DATAOUTPUT=0x0400; /*PFDATDIR.11=1,即IOPF2引脚作为输出*/
r_data=0xff;
byte_addr=0x00;
t_data=0x00;
byte_wr();
byte_rd();
ms_data=0X02;
sec_data=0X03;
min_data=0X04;
hour_data=0X05;
yd_data=0x01;
mon_data=0x06;
ms_data1=0Xff;
sec_data1=0Xff;
min_data1=0Xff;
hour_data1=0Xff;
yd_data1=0xff;
mon_data1=0xff;
delay(360);
write_iic();
// loop:
delay(3600);
read_iic();
asm ( " nop " );
asm ( " nop " );
asm ( " nop " );
// goto loop;
}
void GetTimeFromPCF8583()
{
int temp=0;
GetPCF8583(00,32,Time);
millisecond_gewei=(unsigned int)(millisecond_js*(5.0/8.0)+0.5); //yxy0417gai
millisecond_get=(Time[1]&0x0F)*10+((Time[1]&0xF0)>>4)*100+millisecond_gewei;
second_get=(Time[2]&0x0F)+((Time[2]&0xF0)>>4)*10;
minute_get=(Time[3]&0x0F)+((Time[3]&0xF0)>>4)*10;
hour_get=(Time[4]&0x0F)+((Time[4]&0x30)>>4)*10;
day_get=(Time[5]&0x0F)+((Time[5]&0x30)>>4)*10;
week_get=(Time[6]&0xE0)>>5;
month_get=(Time[6]&0x0F)+((Time[6]&0x10)>>4)*10;
if ((day_get==31)&&(month_get==12))
{
yearflag=1;
}
if ((day_get==1)&&(month_get==1)&&(yearflag==1))
{
yearflag=0;
year_get++;
SetPCF8583(0x10,year_get%100);
delay(70);
SetPCF8583(0x11,year_get/100);
delay(70);
}
temp=Time[16]&0xFF;
temp=temp+(Time[17]&0xFF)*100;
year_get=temp;
// FuncTab[7].status=0x5555;
}
/**--------------------------------------------------------------------------------
2006-3-30
调用方式:void GetPCF8563(uchar firsttype,uchar count,uchar *buff)
函数说明:读取时钟芯片PCF8583的时间,设置要读的第一个时间类型firsttype,并设置读取
的字节数,则会一次把时间读取到buff中。顺序是:
0x02:秒/0x03:分/0x04:小时/0x05:日/0x06:星期/0x07:月(世纪)/0x08:年
---------------------------------------------------------------------------------*/
void GetPCF8583(unsigned int firsttype,unsigned int count,unsigned int *buff)
{
unsigned int i_temp;
start(); /*启动子程序*/
//tmp_data = DEVSELWR; /*I2C器件写操作命令*/
clock_transmit(DEVSELWR); /*字节发送写控制字*/
slave_ack(); /*读从机应答*/
//byte_addr = 0x01; /*各时间单元8583内开始地址*/
//tmp_data = byte_addr;
clock_transmit(firsttype);
slave_ack();
start();
//tmp_data = DEVSELRD; /*I2C器件读操作命令*/
clock_transmit(DEVSELRD);
slave_ack();
for (i_temp=0;i_temp<32;i_temp++)
{
receive();
buff[i_temp] = tmp_data; /*接收的字节送年单元*/
master_ack();
}
no_ack();
tingzhi();
}
/**--------------------------------------------------------------------------------
2006-3-30
调用方式:void SetPCF8583(uchar timetype,uchar value)
函数说明:字节调整时钟。timetype是要改的时间类型,value是新设置的时间值(BCD格式)。
0x02:秒/0x03:分/0x04:小时/0x05:日/0x06:星期/0x07:月(世纪)/0x08:年
---------------------------------------------------------------------------------*/
void SetPCF8583(unsigned int timetype,unsigned int value)
{
I2CStart();
I2CSendByte(0xA0);
WaitAck();
I2CSendByte(timetype);
WaitAck();
I2CSendByte(value);
WaitAck();
tingzhi();
}
/**--------------------------------------------------------------------------------
调用方式:bit I2CAck(void)
函数说明:私有函数,I2C专用,等待从器件接收方的应答
---------------------------------------------------------------------------------*/
int WaitAck(void)
{
int i;
//int SDA_BIT=0x0008;
CLOCK_SDA=1;
iic_dly();
//PADATDIR = PADATDIR&0xF7FF; // SDA为输入
EALLOW;
CLOCK_SDADIR = 0; //SDA 设为输入
EDIS;
//CLOCK_SDA=0;
// CLOCK_SCL=0;
CLOCK_SCL=1;
iic_dly();
for (i=0;i<1000;i++) //因故障接收方无ACK,超时值为255。
{
//SDA_BIT=(PADATDIR&0x0008);
if((GpioDataRegs.GPADAT.bit.GPIOA4)==0)
{
CLOCK_SCL=0;
return 1;
}
}
tingzhi();
EALLOW;
CLOCK_SDADIR = 1; //SDA 设为输
EDIS;
return 0;
}
/**--------------------------------------------------------------------------------
调用方式:void SendAck(void)
函数说明:私有函数,I2C专用,主器件为接收方,从器件为发送方时,应答信号。
---------------------------------------------------------------------------------*/
void SendAck(void)
{
//SDA_0();
CLOCK_SDA=0;
iic_dly();
//SCL_1();
CLOCK_SCL=1;
iic_dly();
//SCL_0();
CLOCK_SCL=0;
}
/**--------------------------------------------------------------------------------
调用方式:void SendAck(void)
函数说明:私有函数,I2C专用,主器件为接收方,从器件为发送方时,非应答信号。
--------------------------------------------------------------------------------*/
void SendNotAck(void)
{
//SDA_1();
CLOCK_SDA=1;
iic_dly();
//SCL_1();
CLOCK_SCL=1;
//iic_dly();
iic_dly();
//SCL_0();
CLOCK_SCL=0;
}
/**--------------------------------------------------------------------------------
调用方式:void I2CSend(uchar ch)
函数说明:私有函数,I2C专用
---------------------------------------------------------------------------------*/
void I2CSendByte(int ch)
{
int i=8;
int sz;
EALLOW;
CLOCK_SDADIR = 1; //SDA 设为输入
EDIS;
while (i--)
{
iic_dly();
//SCL_0();
CLOCK_SCL=0;
iic_dly();
asm(" NOP");
sz=(ch&0x0080)>>7;
if (sz==0)
{
//SDA_0(); // SDA_0( )
CLOCK_SDA=0;
iic_dly();
}
else
{
//SDA_1(); // SDA_1( )
CLOCK_SDA=1;
iic_dly();
}
ch<<=1;
iic_dly();
//SCL_1();
CLOCK_SCL=1;
iic_dly();
}
iic_dly();
//SCL_0();
CLOCK_SCL=0;
iic_dly();
}
void clock_transmit(int ch)
{
int i;
CLOCK_SCL=0; /*SCL=0*/
iic_dly();
for( i=0; i<8; i++ )
{
if( (ch & 0x0080) == 0 )
{
CLOCK_SDA=0; /*SDA=0*/
}
else
{
CLOCK_SDA=1; /*SDA=1*/
}
iic_dly();
CLOCK_SCL=1; /*SCL=1*/
iic_dly();
CLOCK_SCL=0; /*SCL=0*/
ch = ch << 1;
}
}
void PCF8583Init_time()
{
//int i;
// samptest1++;
// if (samptest1>60)
// {
// samptest1=0;
// }
millisecond_set=111;
second_set=10;
minute_set=8;
hour_set=1;
day_set=4;
week_set=2;
month_set=4;
year_set=2006;
// KickDog;
SetTimeToPCF8583();
//初始化时间2005/1/3/星期1/12时/48分/1秒/111毫秒
}
/*--------------------------------------------------------------------------------
设置系统时间及PCF8583时间,时间范围如下:
毫秒范围:00~990ms;(00~99)/100s
秒范围:0~59s;
分范围:0~59m;
时范围:0~23h;
日范围:
1~31day 1、3、5、7、8、10、12月
1~30day 4、6、9、11月
1~29day 2月且0年
1~28day 2月且1、2、3年
周范围:0~6;
月范围:1~12month;
年范围:0~3年;(中间变量yearC)
caosmart in BeiJing 2005-01-08
----------------------------------------------------------------------------------*/
void SetTimeToPCF8583( )
{ /*1、设置系统时间(全局变量),整型格式;
2、设置PCF8583时间(转换成BCD码格式)。*/
int Time_temp=0,year_temp;
/*设置系统时间(全局变量),整型格式*/
/*初始化PCF8583*/
SetPCF8583(0x00,0x04);
iic_dly();
iic_dly();
SetPCF8583(0x08,0x05);
iic_dly();
iic_dly();
/*设置PCF8583时间(转换成BCD码格式)*/
/*millisecond*/
Time_temp=millisecond_set%100;/*毫秒个位与十位*/
Time_temp=(Time_temp/10)|((millisecond_set/100)<<4);
/*毫秒十位与百位送入PCF8583,地址01H*/
SetPCF8583(0x01,Time_temp); //Time_temp
iic_dly();
iic_dly();
/*second*/
Time_temp=(second_set%10)|((second_set/10)<<4);
SetPCF8583(0x02,Time_temp);
iic_dly();
iic_dly();
/*minute*/
Time_temp=(minute_set%10)|((minute_set/10)<<4);
SetPCF8583(0x03,Time_temp);
iic_dly();
iic_dly();
/*hour*/
Time_temp=(hour_set%10)|((hour_set/10)<<4);
Time_temp=Time_temp&0x7F;
SetPCF8583(0x04,Time_temp);
iic_dly();
iic_dly();
/*day&year*/
Time_temp=(day_set%10)|((day_set/10)<<4);
Time_temp=Time_temp&0x3F; /*年中间变量清零*/
year_temp=(year_set%4)<<6;/*用于判断闰年*/
Time_temp=Time_temp|year_temp;
SetPCF8583(0x05,Time_temp);
iic_dly();
iic_dly();
SetPCF8583(0x10,year_set%100);
iic_dly();
iic_dly();
SetPCF8583(0x11,year_set/100);
iic_dly();
iic_dly();
/*week&month*/
Time_temp=(month_set%10)|((month_set/10)<<4);
Time_temp=Time_temp|(week_set<<5);
SetPCF8583(0x06,Time_temp);
iic_dly();
iic_dly();
// FuncTab[0].status=0x5555;
}
void delay(int v)
{
unsigned int j;
for(j=v;j>0;j--)
{
asm( " nop " );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -