📄 pcf8563twi.c
字号:
//pcf8563TWI.c : source file for the pcf8563 Two-wire Serial Interface
//
#include "pcf8563.h"
#include "pcf8563TWI.h"
/////////////////////////////////////////////////////////////////////////////
//pcf8563TWI
void twi_init(void)
{
//{{WIZARD_MAP(TWI)
// SCL frequency: 92.160 kHz
TWBR = 0x48;
TWSR = 0x0;
TWCR = 0x4;
//}}WIZARD_MAP(TWI)
}
uchar SetHym8563(uchar suba,uchar *s,uchar no )
{
uchar twst,i,n=0x0,rv=0x1;
restart:
if(n++>=max)
goto error;
begin:
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);//发送开始信号
while((TWCR & _BV(TWINT))==0x0);//等待发送完毕
switch((twst = TW_STATUS))
{
case TW_REP_START://有可能出现
case TW_START:
break;
case TW_MT_ARB_LOST:
goto begin;
default:
goto error;
}
TWDR = slav | TW_WRITE;//发送SLAV+W
TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输
while((TWCR & _BV(TWINT))==0x0);//等待传输完毕
switch((twst = TW_STATUS))
{
case TW_MT_SLA_ACK:
break;
case TW_MT_SLA_NACK://器件忙,有可能处于内部写周期
goto restart;
case TW_MT_ARB_LOST:
goto begin;
default:
goto error;
}
TWDR = suba | TW_WRITE;//发送SUBA+W
TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输
while((TWCR & _BV(TWINT))==0x0);//等待传输完毕
switch((twst = TW_STATUS))
{
case TW_MT_DATA_ACK:
break;
case TW_MT_DATA_NACK://器件忙,有可能处于内部写周期
goto restart;
case TW_MT_ARB_LOST:
goto begin;
default:
goto error;
}
for(i=0;i<no;i++)
{
TWDR = *s | TW_WRITE;
TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输
while((TWCR & _BV(TWINT))==0x0);//等待传输完毕
switch((twst = TW_STATUS))
{
case TW_MT_DATA_ACK:
break;
case TW_MT_DATA_NACK://器件忙,有可能处于内部写周期
goto restart;
case TW_MT_ARB_LOST:
goto begin;
default:
goto error;
}
s++;
}
quit:
TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);//发送停止信号
return rv;
error:
rv=0x0;
goto quit;
}
uchar GetHym8563(uchar suba,uchar *s,uchar no)
{
uchar twst,i,n=0x0,rv=0x1;
restart:
if(n++>=max)
goto error;
begin:
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);//发送开始信号
while((TWCR & _BV(TWINT))==0x0);//等待发送完毕
switch((twst = TW_STATUS))
{
case TW_REP_START://有可能出现
case TW_START:
break;
case TW_MT_ARB_LOST:
goto begin;
default:
goto error;
}
TWDR = slav | TW_WRITE;//发送SLAV+W
TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输
while((TWCR & _BV(TWINT))==0x0);//等待传输完毕
switch((twst = TW_STATUS))
{
case TW_MT_SLA_ACK:
break;
case TW_MT_SLA_NACK://器件忙,有可能处于内部写周期
goto restart;
case TW_MT_ARB_LOST:
goto begin;
default:
goto error;
}
TWDR = suba | TW_WRITE;//发送SUBA+W
TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输
while((TWCR & _BV(TWINT))==0x0);//等待传输完毕
switch((twst = TW_STATUS))
{
case TW_MT_DATA_ACK:
break;
case TW_MT_DATA_NACK://器件忙,有可能处于内部写周期
goto restart;
case TW_MT_ARB_LOST:
goto begin;
default:
goto error;
}
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);//发送(重新)开始信号
while((TWCR & _BV(TWINT))==0x0);//等待发送完毕
switch((twst = TW_STATUS))
{
case TW_REP_START://正确的状态
break;
case TW_MT_ARB_LOST:
goto begin;
default:
goto error;
}
TWDR = slav | TW_READ;//发送SLAV+R
TWCR = _BV(TWINT) | _BV(TWEN);//清TWINT,开始传输
while((TWCR & _BV(TWINT))==0x0);//等待传输完毕
switch((twst = TW_STATUS))
{
case TW_MR_SLA_ACK:
break;
case TW_MR_SLA_NACK://器件忙,有可能处于内部写周期
goto restart;
case TW_MR_ARB_LOST:
goto begin;
default:
goto error;
}
for(i=0;i<no;i++)
{
if(i==(no-1))
{
TWCR = _BV(TWINT) | _BV(TWEN) ;//清TWINT,开始传输(无应答)
}
else
{
TWCR = _BV(TWINT) | _BV(TWEN) | _BV(TWEA) ;//清TWINT,开始传输(有应答)
}
while((TWCR & _BV(TWINT))==0x0);//等待传输完毕
switch((twst = TW_STATUS))
{
case TW_MR_DATA_NACK:
case TW_MR_DATA_ACK:
*s = TWDR;
s++;
break;
default:
goto error;
}
}
quit:
TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);//发送停止信号
return rv;
error:
rv=0x0;
goto quit;
}
/*----------------------------------------------------------------------
功 能:将读出的时间数据的无关位屏蔽掉
说 明:hym8563时钟寄存器的有些无关位的状态是不定的,所以应该将无效位屏蔽掉
----------------------------------------------------------------------*/
void Datajust(uchar *s)
{
s[0]=s[0]&0x7f;
s[1]=s[1]&0x7f;
s[2]=s[2]&0x3f;
s[3]=s[3]&0x3f;
s[4]=s[4]&0x07;
s[5]=s[5]&0x1f;
s[6]=s[6]&0xff;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -