电子说
PCF8563是PHILIPS公司推出的一款工业级内含I2C总线接口功能的具有极低功耗的多功能时钟/日历芯片。PCF8563的多种报警功能、定时器功能、时钟输出功能以及中断输出功能能完成各种复杂的定时服务,甚至可为单片机提供看门狗功能。内部时钟电路、内部振荡电路、内部低电压检测电路(1.0V)以及两线制I2C总线通讯方式,不但使外围电路及其简洁,而且也增加了芯片的可靠性。同时每次读写数据后,内嵌的字地址寄存器会自动产生增量。当然作为时钟芯片,PCF8563亦解决了2000年问题。因而,PCF8563是一款性价比极高的时钟芯片,它已被广泛用于电表、水表、气表、电话、传真机、便携式仪器以及电池供电的仪器仪表等产品领域。
1)大工作电压范围:1.0~5.5V
2)400KHz 的 I2C 总线接口(VDD=1.8~5.5V 时)。
时钟频率最大400KH
3)i2C 总线从地址:读,0A3H;写,0A2H 。
//******************************************************
//define
//*****************************************************
#define PCF8563_ADDR 0xa2 // PCF8563设备地址
#define PCF8563_ENABLE 0x00 // 设置
#define PCF8563_SUBADDR 0x02 // 时间地址
#define PCF8563_NUMB 0x07 // 时间个数
#define PCF8563_LOOPTIME 0x02 // 循环次数
#define PCF8563_SECMASK 0x7f // second
#define PCF8563_MINMASK 0x7f // minute
#define PCF8563_HRMASK 0x3f // hour
#define PCF8563_DAYMASK 0x3f // day
#define PCF8563_WKMASK 0x07 // week
#define PCF8563_MOMASK 0x1f // month
#define PCF8563_YRMASK 0xff // year
*
void DELAY_US(Uint16 i)
{ Uint16 m,n;
for(m=0;m《i;m++)
{
for(n=0;n《5;n++)
{
_nop_();
}
}
} */
/********************************************************
** 函数名称: void DELAY_MS(Uint16 i)
** 功能描述: 延时函数
** 输 入:延时毫秒数
** 输 出:无
********************************************************/
//延时函数单位ms
void DELAY_MS(Uint16 i)
{ Uint16 m,n; for(m=0;m《i;m++)
{
for(n=0;n《1000;n++)
{
_nop_();
}
}
}
********************************************************
** 函数名称: InitCrt()
** 功能描述: SD2405的初始化
** 输 入:无 ** 输 出:无
********************************************************/
void InitCrt() { //设备地址
I2cDeviceAdd = PCF8563_ADDR; }
/********************************************************
** 函数名称: CrtGetDateTime(struct SYSTEM_TIME *Time)
** 功能描述: 读取时间
** 说 明:将从PCF8563中读取的时间放入Time指向的结构中
** 输 入:无
** 输 出:无
********************************************************/
void CrtGetDateTime(struct SYSTEM_TIME *Time) {
Uint8 buf[8]; //设备地址
I2cDeviceAdd = PCF8563_ADDR;
SM_Receive (PCF8563_SUBADDR , buf, PCF8563_NUMB);
Time-》time.ucSecond = buf[0]; //秒
Time-》time.ucMinute = buf[1]; //分
Time-》time.ucHour = buf[2]; //时
屏蔽最高位 Time-》date.ucDay = buf[3]; //日
Time-》Week = buf[4]; //星期 Time-》date.ucMonth = buf[5]; //月
Time-》date.ucYear = buf[6]; //年
}
/******************************************************** ** 函数名称: CrtSetDateTime(struct SYSTEM_TIME *Time) ** 功能描述: 设置时间
** 说 明:将Time指向的结构中日期时间参数设置到sd24.5中
** 输 入:无 ** 输 出:无
********************************************************/
void CrtSetDateTime(struct SYSTEM_TIME *Time)
{
Uint8 buf[8]; //设备地址
I2cDeviceAdd = PCF8563_ADDR;
//写入设置(时钟工作、关闭复位、关闭测试模式)
buf[0] = PCF8563_ENABLE;
SM_Send (0, buf, 0);
//写入日期时间 buf[0] = Time-》time.ucSecond; //秒
buf[1] = Time-》time.ucMinute; //分
buf[2] = Time-》time.ucHour|0x80; //时 置为24小时格式
buf[3] = Time-》date.ucDay; //日
buf[4] = Time-》Week; //星期
buf[5] = Time-》date.ucMonth; //月
buf[6] = Time-》date.ucYear; //年
SM_Send (PCF8563_SUBADDR, buf, PCF8563_NUMB);
}
4 新华龙C8051F022的IIC驱动程序
//----------------------------------------------------------------------------- // Includes
//-----------------------------------------------------------------------------
#include 《c8051f020.h》 // SFR declarations #include 《stdio.h》
#include 《king.h》
#include 《DYSJ.h》
#include 《I2C.H》
#define SMB_FREQUENCY 10000L // Target SCL clock rate
/******************************************************************************
** 函数名称:void SPI0_Init()
** 功能描述:I2C初始化程序
** 说 明:
1. 置下降沿有效
2. 置工作时钟2MHz
3.
** 输 入:无
** 输 出:无
*******************************************************************************/
void I2C_Init() { SMB0CN = 0x44; // Enable SMBus with ACKs on acknowledge cycle
SMB0CR = -80; //257 - (SYSCLK / (2 * SMB_FREQUENCY));
EIE1 |= 2; // SMBus interrupt enable
// EA = 1; // Global interrupt enable
I2cSM_BUSY = 0; // Free SMBus for first transfer.
}
/******************************************************************************
** 函数名称:void SM_Send (Uint8 byte_address,Uint8 *SendBuf,Uint8 count)
** 功能描述:I2C写入程序
** 说 明:
1. 等待空闲
2. 写入数据
3. 等待结束
** 输 入:地址byte_address、写入数据缓冲区*SendBuf、数量count
** 输 出:无
*******************************************************************************/
void SM_Send (Uint8 byte_address,Uint8 *SendBuf,Uint8 count)
{
ET0 = 0; //禁止中断
ET2 = 0; //禁止中断
while (I2cSM_BUSY); // 等待空闲
I2cSM_BUSY = 1; // 置忙
SMB0CN = 0x44; // SMBus enabled, ACK on acknowledge cycle
I2cSendCount = count; // 置写入数量
I2cRecCount = 0; // 读出数量清零
I2cSendDPTR = SendBuf; // SMBus enabled, ACK on acknowledge cycle
I2CWRITE; // Chip select + WRITE
I2cMemAdd = byte_address;
STO = 0;
STA = 1; // 启动传输
FeedWatchdog(); while (I2cSM_BUSY); // 等待空闲
ET0 = 1; //允许中断
ET2 = 1; //允许中断
******************************************************************************
** 函数名称:void SM_Receive (Uint8 byte_address,Uint8 *ReadBuf,Uint8 count)
** 功能描述:I2C读取程序
** 说 明:
1. 等待空闲
2. 置地址
3. 读取数据
3. 等待结束
** 输 入:地址byte_address、读取数据缓冲区*SendBuf、数量count
** 输 出:无
*******************************************************************************
/
void SM_Receive (Uint8 byte_address,Uint8 *ReadBuf,Uint8 count)
{
ET0 = 0; //禁止中断
ET2 = 0; //禁止中断
while (I2cSM_BUSY); // 等待空闲
I2cSM_BUSY = 1; // 置忙
SMB0CN = 0x44; // SMBus enabled, ACK on acknowledge cycle
I2cSendCount = 0; // 置写入数量
I2CWRITE; // Chip select + WRITE
I2cMemAdd = byte_address; //值地址偏移
I2cRecCount = count; //要接收的数据个数
I2cRecDPTR = ReadBuf; //指向要接收的数据区
STO = 0;
STA = 1; // Start transfer
FeedWatchdog();
while (I2cSM_BUSY); // 等待空闲
ET0 = 1; //允许中断
ET2 = 1; //允许中断
}
/******************************************************************************
** 函数名称:void SMBUS_ISR (void) interrupt 7
** 功能描述:I2C中断服务程序
** 说 明:
1. 选择器件地址
2. 置读写地址
3. 读取或写入数据
3. 置结束标志
** 输 入:无
** 输 出:无
*******************************************************************************
/
void SMBUS_ISR (void) interrupt 7
{
switch (SMB0STA) // Status code for the SMBus (SMB0STA register)
{
// 主发送器/接收器:起始条件已发送
// 在该状态发送的COMMAND 字的R/W 位总是为0(W),
// 因为对于读和写操作来说都必须先写存储器地址。
case SMB_START:
SMB0DAT = I2cCOMMAND;
// 写入含读写指令的设备地址
STA = 0;
// 清除启动标志
break;
//主发送器/接收器:重复起始条件已发送。
// 该状态只应在读操作期间出现,在存储器地址已发送并得到确认之后
case SMB_RP_START:
I2CREAD; // 置设备读
SMB0DAT = I2cCOMMAND; // 写入含读写指令的设备地址
STA = 0;
break;
// 主发送器 设备地址+(W/R)已发出。收到ACK。
case SMB_MTADDACK:
SMB0DAT = I2cMemAdd; // 发送要写入的字节地址
break;
// 主发送器 从地址+W已发出。收到NACK。
case SMB_MTADDNACK:
/* if (I2cSendCount) // 传输结束
{
SMB0DAT = *I2cSendDPTR; //传送数据
I2cSendDPTR++;
I2cSendCount--;
}
else
{ if(I2cRecCount)
{
STO = 0;
STA = 1;
}
else
{
STO = 1
I2cSM_BUSY = 0; //发送停止,释放总线
}
}*/
STO = 1;
STA = 1;
break;
// 数据字节已经发出,收到ACK
case SMB_MTDBACK:
if (I2cSendCount) // 传输结束
{
SMB0DAT = *I2cSendDPTR; //传送数据
I2cSendDPTR++;
I2cSendCount--;
}
else
{
if(I2cRecCount)
{ STO = 0;
STA = 1;
}
else
{
STO = 1;
I2cSM_BUSY = 0; //发送停止,释放总线
} }
break;
// 数据字节已经发出,收到NACK
case SMB_MTDBNACK:
STO = 1;
STA = 1;
break;
// 主发送器 竞争失败
case SMB_MTARBLOST:
STO = 1;
STA = 1;
break;
// 从地址+R已经发出,收到ACK
case SMB_MRADDACK:
SysBuff[500]=8;
//if (counter == 1) //只接收一个字节时要设置接收后就NACK
//{
// AA = 0;
// NACK sent on acknowledge cycle.
//}
break;
// 从地址+R已经发出,收到NACK
case SMB_MRADDNACK:
STO = 0;
STA = 1;
break; // 数据字节收到,ACK已经发出
case SMB_MRDBACK:
if (I2cRecCount == 1)
{
AA = 0;
// 收到最后一个字节前准备设置最后一个字节不应答
}
I2cRecCount--;
*I2cRecDPTR = SMB0DAT;
I2cRecDPTR++;
break;
// 数据字节收到,NACK已经发出
case SMB_MRDBNACK:
*I2cRecDPTR = SMB0DAT;
STO = 1;
I2cSM_BUSY = 0; // Free SMBus
break;
// 未知状态或总线错误
default:
STO = 1; // Reset communication.
I2cSM_BUSY = 0;
break;
}
SI=0; // clear interrupt flag
}
全部0条评论
快来发表一下你的评论吧 !