PCF8563C语言可调时钟日历
- 格式:doc
- 大小:55.00 KB
- 文档页数:12
广州周立功单片机发展有限公司 Tel: (020)38730976 38730977 Fax: 38730925 PCF8563实时时钟高精度调整方法一、概述PCF8563是PHILIPS公司设计生产的经典工业级实时时钟芯片(RTC),I2C总线接口,具有功耗低、精度高等特点,广泛应用于电表、水表、气表、电话等产品。
本文将介绍如何调整PCF8563时钟精度的方法。
二、电路原理图1 PCF8563高精度调整三、相关说明如图1所示,R3、R4为I2C总线上拉电阻,若总线速度高于100KHz,电阻阻值要更小。
由于PCF8563的中断输出及时钟输出均为开漏输出,所以要外接上拉电阻(如图1的R1、R2),若不使用这两个信号,对应的上拉电阻可以不用。
对于PCF8563芯片,需外接时钟晶振32768Hz(如图1的X1),推荐使用5ppm或更稳定的晶振。
PCF8563典型应用电路推荐使用15pF的晶振匹配电容,实际应用时可以作相应的调整,以使RTC获得更高精度的时钟源。
一般晶振匹配电容在15pF~21pF之间调整(相对于5ppm精度的32768Hz晶振),15pF电容时时钟频率略偏高,21pF电容时时钟频率略偏低。
四、操作方法1.设置PCF8563时钟输出有效(CLKOUT),输出频率为32.768KHz。
使用高精度频率计测量CLKOUT输出的频率。
2.根据测出的频率,对JC1、JC2、JC3作短接或断开调整。
频率比32768Hz偏高时, 3.加大电容值;频率比32768Hz偏低时,减小电容值。
说明:图1中的C1、C2、C3的值在1pF~5pF之间,根据实际情况确定组合方式,以便于快速调整。
推荐使用(3pF、3pF、3pF)、(1pF、2pF、3pF)、(2pF、3pF、4pF)。
- 1 -。
万年历是一种能够显示日期、星期和时间的工具,它不仅能够告诉我们当天是几号,还能显示星期几和当前时间。
在这个项目中,我们将使用PCF8563时钟芯片来制作一个基于PCF8563的万年历。
PCF8563是一种CMOS实时时钟和日历芯片,它可以提供年、月、日、星期和小时、分钟、秒的数据。
它具有电源管理功能,可以通过一个电源低于2V脉冲输入来切换系统电源供电方式。
为了制作这个基于PCF8563的万年历,我们需要以下材料和工具:1. Arduino主控板2.PCF8563时钟芯片3.16x2液晶显示屏4.面包板5.杜邦线6.10k电阻接下来,我们将按照以下步骤来制作基于PCF8563的万年历:第一步:连接电路首先,将Arduino主控板插入面包板。
接着,连接PCF8563时钟芯片到Arduino主控板上的I2C总线。
将SDA引脚连接到A4引脚,将SCL引脚连接到A5引脚。
此外,还需要使用10k电阻将VCC引脚连接到VCC引脚上。
接下来,将16x2液晶显示屏连接到面包板。
连接液晶屏的RS引脚到Arduino主控板的D12引脚,RW引脚到GND引脚,和E引脚到D11引脚。
将液晶屏的D4到D7引脚连接到Arduino主控板的D5到D2引脚。
第二步:编写代码打开Arduino IDE并创建一个新的项目。
然后,编写以下代码:#include <Wire.h>#include <LiquidCrystal_I2C.h>//定义PCF8563的地址#define PCF8563_ADDR 0x51//定义显示屏的尺寸#define LCD_COLUMNS 16#define LCD_ROWS 2LiquidCrystal_I2C lcd(0x27, LCD_COLUMNS, LCD_ROWS);void setup//初始化I2C总线Wire.begin(;//设置时钟芯片为24小时模式Wire.beginTransmission(PCF8563_ADDR);Wire.write(0x02);Wire.write(0x00);Wire.endTransmission(;//初始化液晶显示屏lcd.begin(LCD_COLUMNS, LCD_ROWS);lcd.setCursor(0, 0);lcd.print("Date: ");lcd.setCursor(0, 1);lcd.print("Time: ");void loop//读取PCF8563的日期和时间Wire.beginTransmission(PCF8563_ADDR); Wire.write(0x02);Wire.endTransmission(;Wire.requestFrom(PCF8563_ADDR, 7);int second = bcdToDec(Wire.read( & 0x7F); int minute = bcdToDec(Wire.read();int hour = bcdToDec(Wire.read( & 0x3F); int dayOfWeek = bcdToDec(Wire.read();int dayOfMonth = bcdToDec(Wire.read();int month = bcdToDec(Wire.read( & 0x1F); int year = bcdToDec(Wire.read();//显示日期和时间lcd.setCursor(6, 0); printWithLeadingZero(dayOfMonth);lcd.print("/");printWithLeadingZero(month);lcd.print("/");lcd.print(2000 + year);lcd.setCursor(6, 1); printWithLeadingZero(hour);lcd.print(":");printWithLeadingZero(minute);lcd.print(":");printWithLeadingZero(second);delay(1000);//将BCD码转换为十进制int bcdToDec(int bcd)return (bcd / 16 * 10) + (bcd % 16);//打印带有前导零的数字void printWithLeadingZero(int number)if (number < 10)lcd.print('0');}lcd.print(number);第三步:上传代码将Arduino主控板连接到电脑,并根据需要选择正确的端口和板类型。
PCF8563 I 2C 实时时钟/日历芯片1.概述PCF8563是低功耗的CMOS 实时时钟/日历芯片,它提供一个可编程时钟输出,一个中断输出和掉电检测器,所有的地址和数据通过I 2C 总线接口串行传递。
最大总线速度为400Kbits/s ,每次读写数据后,内嵌的字地址寄存器会自动产生增量。
2.特性* 低工作电流:典型值为0.25μA (VDD=3.0V ,Tamb=25℃时)。
* 世纪标志* 大工作电压范围:1.0~5.5* 低休眠电流;典型值为0.25μA(V DD =3.0V,T amb =25℃)* 400KHz 的I 2C 总线接口(VDD=1.8~5.5V 时)。
* 可编程时钟输出频率为:32.768KHz ,1024Hz ,32Hz ,1Hz 。
* 报警和定时器。
* 掉电检测器。
* 内部集成的振荡器电容。
* 片内电源复位功能。
* I 2C 总线从地址:读,0A3H ;写,0A2H 。
* 开漏中断引脚。
3.应用z 移动电话 z 便携仪器 z 传真机z 电池电源产品4.简明参考数据表1 简明参考数据符号 描 述条 件 最小值最大值 单 位 I 2C 总线无效; T amb =25℃ 1.0 5.5 VV DD 工作电压I 2C 总线有效; fSCL=400kHz T amb =-40~+85℃ 1.8 5.5 V fSCL=400kHz - 800 μA fSCL=100kHz - 200 μA fSCL=0Hz; T amb =25℃ V DD =5V - 550 nA I DD工作电流; 定时器和CLKOUT 失效 V DD =2V-450nAT amb 工作温度范围-40 +85 ℃ T stg储存温度-65 +150 ℃5.订单信息表2 订定单信息包 装型 号名称 描 述版本 PCF8563P DIP8 塑料双列直插式封装;8脚(300mil) SOT97-1 PCF8563T SO8 小塑料封装;8脚;宽3.9mm SOT96-1 PCF8563TS TSSOP8 小塑料薄型封装;8脚;宽3.0mmSOT505-16.方框图图1 方框图7.管脚配置7.1管脚12348765PCF8563P PCF8563TPCF8563TS V DDCLKOUT OSCO SCLSDAV SSOSCI图2 管脚配置SDASCLCLKOUTV DD图3 二极管保护图7.2管脚描述表3管脚描述符号管脚号描述OSCI 1 振荡器输入OSCO 2 振荡器输出/INT 3 中断输出(开漏;低电平有效)V SS 4 地SDA 5 串行数据I/OSCL 6 串行时钟输入CLKOUT 7 时钟输出(开漏)V DD8 正电源8. 功能描述PCF8563有16个8位寄存器:一个可自动增量的地址寄存器,一个内置32.768KHz的振荡器(带有一个内部集成的电容),一个分频器(用于给实时时钟RTC提供源时钟),一个可编程时钟输出,一个定时器,一个报警器,一个掉电检测器和一个400KHz I2C 总线接口。
PCF8563日历时钟芯片原理及应用设计PCF8563是一款实时时钟芯片,用于保存日期、时间和闹钟功能,并在需要时提供准确的时间。
它集成有时钟芯片、电历寄存器和电压降器,可以通过I2C总线进行控制和通信。
下面将详细介绍PCF8563的原理以及应用设计。
一、PCF8563的工作原理二、PCF8563的应用设计1.实时时钟系统:PCF8563广泛应用于各种实时时钟系统,例如电子钟、温度计、保险柜等。
它可以提供准确的时间,并可以进行一定的时钟校准,以确保时间的准确性。
2.日历显示:PCF8563可以与液晶显示器或LED显示器等进行连接,实现日期和时间的显示。
通过读取芯片中的日期和时间寄存器,可以将日期和时间信息显示在屏幕上。
3.闹钟功能:PCF8563内置有闹钟功能,可以设置闹钟时间和日期,并在闹钟触发时发出中断信号。
通过与外部蜂鸣器或报警器等连接,可以实现闹铃功能。
4.计时器功能:PCF8563可以用作计时器,例如测量一些过程的时间。
通过读取和记录时钟寄存器中的时间值,可以实现计时功能,并根据需要进行时钟校准。
5.电池电量监测:PCF8563可以监测电池电量,并在电池电量低于一定阈值时发出警告信号。
这对于需要长时间运行的系统非常有用,可以在电池电量低时及时更换电池。
三、总结PCF8563是一款功能强大的实时时钟芯片,可以提供准确的日期和时间,并具有闹钟和计时功能等。
它可以与各种外部设备进行通信,实现多种应用设计。
无论是日历显示系统还是闹钟功能系统,PCF8563都能够提供稳定和准确的时间支持。
PCF8563实时时钟/日历第11版——2015年10月26日产品数据手册1. 简介PCF8563是一款低功耗的CMOS1实时时钟/日历芯片,支持可编程时钟输出、中断输出和低压检测。
所有地址和数据通过双线双向I2C总线串联传输,最高速率:400 kbps。
每次读写数据字节后,寄存器地址自动累加。
2. 特性和优势◼基于32.768kHz的晶振,提供年、月、日、星期、时、分和秒计时◼Century flag◼时钟工作电压:1.0 - 5.5 V(室温)◼低备用电流;典型值为0.25 μA(V DD = 3.0 V,T amb =25 °C)◼400 kHz 双线I2C总线接口(V DD = 1.8 - 5.5 V)◼可编程时钟输出(32.768 kHz、1.024 kHz、32 Hz和1Hz)◼报警和定时器功能◼集成晶振电容器◼内部上电复位(POR)◼I2C总线从机地址:读:A3h;写:A2h◼开漏中断管脚3. 应用◼移动电话◼便携式仪器◼电子计量◼电池驱动产品1. 有关本资料表所使用的缩略语及首字母缩略语的定义,请参考第18节。
4. 订购信息表1. 订购信息[1] 不推荐用于新产品设计。
替代零件为PCF8563T/5。
[2] 不推荐用于新产品设计。
替代零件为PCF8563TS/5。
5. 标示表2. 标记代码6. 功能框图图1. PCF8563功能框图7. 引脚配置信息7.1 引脚配置图2. HVSON10的引脚配置(PCF8563BS) 图3. SO8的引脚配置(PCF8563T)图4. TSSOP8的引脚配置(PCF8563TS)7.2 引脚说明表3. 引脚说明[1] 晶粒芯片焊盘(外露式焊盘)通过高电阻(非导电的)芯片附着连接到VSS,并应进行电气隔离。
将外露式焊盘焊接到电气隔离的PCB铜焊盘上,以获得更好的传热效果,这是一种较好的工程实践,但由于RTC不会消耗太多功率,因此并不需要这样做。
PCF8563时钟芯片驱动详解1概述PCF8563是PHILIPS公司推出的一款工业级含I2C总线接口功能的具有极低功耗的多功能时钟/日历芯片。
PCF8563的多种报警功能、定时器功能、时钟输出功能以及中断输出功能能完成各种复杂的定时服务,甚至可为单片机提供看门狗功能。
部时钟电路、部振荡电路、部低电压检测电路(1.0V)以及两线制I2C 总线通讯方式,不但使外围电路及其简洁,而且也增加了芯片的可靠性。
同时每次读写数据后,嵌的字地址寄存器会自动产生增量。
当然作为时钟芯片,PCF8563亦解决了2000年问题。
因而,PCF8563是一款性价比极高的时钟芯片,它已被广泛用于电表、水表、气表、、传真机、便携式仪器以及电池供电的仪器仪表等产品领域。
2原理图3 8563源代码//******************************************************//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)** 功能描述: 延时函数** 输入:延时毫秒数** 输出:无********************************************************///延时函数单位msvoid 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. 置工作时钟2MHz3.** 输入:无** 输出:无******************************************************************************* /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 enableI2cSM_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 + WRITEI2cMemAdd = 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 + WRITEI2cMemAdd = byte_address; //值地址偏移I2cRecCount = count; //要接收的数据个数I2cRecDPTR = ReadBuf; //指向要接收的数据区STO = 0;STA = 1; // Start transferFeedWatchdog();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),// 因为对于读和写操作来说都必须先写存储器地址。
用PCF8563做实时时钟的C源程序#include<reg51.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intsbit pcf8563_scl=P0^4;sbit pcf8563_sda=P0^3;ucharnum[10]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0 x37,0x38,0x39}; //数字表sbit clk=P2^0;sbit dio=P2^1;sbit cfd=P2^2; //充放电开关,sbit en=P2^3;sbit rw=P2^4;sbit rs=P2^5;sbit deng=P2^6; //测试灯sbit adcs=P2^7;bit busy=0;uchar sg;uchar sd;uchar fg;uchar fd;uchar mg;uchar md;uchar hou=0;uchar min=0;uchar sec=0;uchar subadd;uchar dat;uchar number;void start_pcf8563();void send_pcf8563_byte();void LcdIni(void);void WrOp(uchar dat);void WrDat(uchar dat);void ChkBusy(void);void display0(void);void display1(void);void stop_pcf8563();void receive_pcf8563_byte();void spit_time();void LcdIni()//初始化LCD{WrOp(0x01);WrOp(0x38);WrOp(0x0c);WrOp(0x06);} void WrOp(uchar dat)//写LCD显示地址{P1 =dat;rs=0;rw=0;en=0;ChkBusy();en=1;}void WrDat(uchar dat)//写LCD显示数据{P1=dat;rs=1;rw=0;en=0;ChkBusy();en=1;}void ChkBusy() //检查LCD是否忙{P1=0xff;rs=0;rw=1;en=0;_nop_();en=1;while(P1&0x80);}void display0() //显示必要的背景{WrOp(0x80);WrDat('T');WrOp(0x81);WrDat(':');WrOp(0x84);WrDat(':');WrOp(0x87);WrDat(':');}void spit_time(){sg=(int)hou/10;sd=(int)hou%10;fg=(int)min/10;fd=(int)min%10;mg=(int)sec/10;md=(int)sec%10;}void display1()//显示时间六位{uchar temp6;uchar temp5;uchar temp4;uchar teMP3;uchar temp2;uchar temp1;WrOp(0x82);temp6=num[sg];WrDat(temp6);WrOp(0x83);temp5=num[sd];WrDat(temp5);WrOp(0x85);temp4=num[fg];WrDat(temp4);WrOp(0x86);teMP3=num[fd];WrDat(teMP3);WrOp(0x88);temp2=num[mg];WrDat(temp2);WrOp(0x89);temp1=num[md];WrDat(temp1);}void Send_pcf8563_byte(uchar bb) //向PCF8563发送一个字节{uchar aa;pcf8563_scl=0;for(aa=0;aa<8;aa++){if((bb&0x80)==0x80){pcf8563_sda=1;}else{pcf8563_sda=0;}pcf8563_scl=1;pcf8563_scl=0;bb=bb<<1;}_nop_();_nop_();pcf8563_sda=1;pcf8563_scl=1;busy=0;if(pcf8563_sda){busy=1;}else{_nop_();_nop_();pcf8563_scl=0;busy=0;}}void write_pcf8563(uchar subadd,uchar dat)// 向PCF8563对应地址写数据{start_pcf8563();Send_pcf8563_byte(0xa2);if(!busy){Send_pcf8563_byte(subadd);if(!busy){Send_pcf8563_byte(dat);}}stop_pcf8563();}void read_pcf8563() //读当时的时,分,钞{start_pcf8563();Send_pcf8563_byte(0xa2);if(!busy){Send_pcf8563_byte(0x02);if(!busy){start_pcf8563();Send_pcf8563_byte(0xa3);receive_pcf8563_byte();sec=number&0x7f;start_pcf8563();Send_pcf8563_byte(0xa3);receive_pcf8563_byte();min=number&0x7f;start_pcf8563();Send_pcf8563_byte(0xa3);receive_pcf8563_byte();hou=number&0x3f;}}stop_pcf8563();}void receive_pcf8563_byte() //从PCF8563接受一个字节{uchar CC;pcf8563_sda=1;number=0;for(CC=0;cc<8;cc++){number<<=1;pcf8563_scl=0;pcf8563_scl=1;_nop_();_nop_();number= number|pcf8563_sda;}pcf8563_scl=0;_nop_();_nop_();}void start_pcf8563() //开启PCF8563IIC {pcf8563_sda=1;pcf8563_scl=1;pcf8563_sda=0;//SCL为低,SDA执行一个上跳pcf8563_scl=0;//SCL为低,嵌住数据线}void stop_pcf8563() //关闭PCF8563IIC {pcf8563_sda=0;pcf8563_scl=1;pcf8563_sda=1;//SCL为高,SDA执行一个上跳pcf8563_scl=0;//SCL为低,嵌住数据线}void main(void){LcdIni(); //初始化屏display0(); //显示必要的背影write_pcf8563(0x02,sec); //写钞write_pcf8563(0x03,min); //写分write_pcf8563(0x04,hou); //写时while(1){read_pcf8563();//读当前时间spit_time(); //切害时间,为显示做准备display1(); //显示当前时间}}。
PCF8563实时时钟⽇历芯⽚详细资料(中⽂版——权威)PCF8563 实时时钟⽇历芯⽚选型指南1. 概述PCF8563是低功耗的CMOS实时时钟⽇历芯⽚。
它提供⼀个可编程时钟输出⼀个中断输出和掉电检测器所有的地址和数据,通过I2C总线接⼝串⾏传递最⼤总线速度为400Kbits/s,每次读写数据后内嵌的字地址寄存器会⾃动产⽣增量。
2. 特性低⼯作电流典型值:0.25 A,VDD=3.0V Tamb=25 时;世纪标志;⼤⼯作电压范围:1.0V--5.5V;低休眠电流典型值为:0.25 A(VDD=3.0V,Tamb=25 );400KHz 的I2C 总线接⼝:VDD=1.8 5.5V 时;可编程时钟输出频率为:32.768KHz、1024Hz、32Hz、1Hz;报警和定时器;内部集成的振荡器电容⽚内电源复位功能掉电检测器;I2C 总线从地址:读0A3H 写0A2H;开漏中断引脚。
3. 应⽤复费率电度表IC、卡⽔表IC、卡煤⽓表便携仪器传真机移动电话电池电源产品4.简明参考数据8.功能描述PCF8563内有16个8位的地址递增寄存器,⼀个32.768 kHz⽚上集成电容振荡器,⼀个实时时钟源(RTC)的分频器,可编程的时钟输出,⼀个定时器,报警器,⼀个低压检测器和400KHz的I2C接⼝。
所有16个寄存器被设计成可寻址的8位并⾏寄存器,虽然不是所有的位都有效。
前两个寄存器(内存地址00H和01H),⽤于控制与/或状态寄存器。
内存地址02H⾄08H是时钟功能的计数器,⽤于(秒、分、时、⽇、⽉、年计数器)。
内存地址09H⾄0CH包含定义报警的条件的报警寄存器。
内存地址0DH控制CLKOUT的输出频率。
0EH和0FH分别是定时控制器和定时器。
秒、分钟、⼩时、天、⽉、年、以及每分钟报警、⼩时报警、⽇报警寄存器都以BCD 格式编码。
平⽇和星期报警寄存器不以BCD格式编码。
当⼀个RTC寄存器被读取,所有的寄存器的内容被冻结。
敬告:没有51单片机基础的人请慎重下载高质量实用性51单片机STC15W系列程序(3),STC8A系列可参考STC15单片机PCF8563时钟芯片LCD1602显示4×4键盘设置时间程序/**************************************************/ main主函数程序:#include "Library.h"unsigned char code orgval[7]={0x00,0x00,0x00,0x20,0x01,0x04,0x20,};unsigned char set_buf[13]={0,0,0,0,0,0,1,0,0,0,0,0,0,}; unsigned char t_buf[7];unsigned char t_rec[7];unsigned char time_buf[15];unsigned char x_value;unsigned char y_value;bit enter_flag;bit tmr200ms_flag=0;void Write_original(unsigned char *originalval);void Timer0_config(unsigned int ms);void Display_time(unsigned char *tm_buf);void main(){unsigned char sec_bkp;unsigned char testbuf[7];P1M1 &= 0x3F; P1M0 &= 0x3F;P2M1 &= 0x3F; P2M0 &= 0x3F;P5M1 &= 0xF3; P5M0 &= 0xF3;P4M1 &= 0x0F; P4M0 &= 0x0F;P2M1 &= 0xE5; P2M0 &= 0xE5;P0M1 = 0x00; P0M0 = 0x00;Timer0_config(1);LCD1602_init();EA = 1;//F0 = 0;//LCD1602_wbyte(0,0,"hi",sizeof("hi")-1);//test LCD1602//P0 = 0xFF;Read_time(0x02,testbuf);if(testbuf[0]&0x80){Write_original(orgval);}while(1){Key_driver();if(tmr200ms_flag){tmr200ms_flag=0;Read_time(0x02,t_rec);//Display_time(t_buf);//test}if(enter_flag==0){if(sec_bkp!=t_rec[0]){sec_bkp = t_rec[0];Display_time(t_rec);}}}}void Display_time(unsigned char *tm_buf){time_buf[0] = ((tm_buf[2])>>4)+'0';time_buf[1] = ((tm_buf[2])&0x0F)+'0';time_buf[2] = ':';time_buf[3] = ((tm_buf[1])>>4)+'0';time_buf[4] = ((tm_buf[1])&0x0F)+'0';time_buf[5] = ':';time_buf[6] = ((tm_buf[0])>>4)+'0';time_buf[7] = ((tm_buf[0])&0x0F)+'0';LCD1602_wbyte(0,0,time_buf,8);time_buf[0] = 0x02 + '0';time_buf[1] = 0x00 + '0';time_buf[2] = (tm_buf[6]>>4)+'0';time_buf[3] = (tm_buf[6]&0x0F)+'0';time_buf[4]= '-';time_buf[5] = (tm_buf[5]>>4)+'0';time_buf[6] = (tm_buf[5]&0x0F)+'0';time_buf[7]= '-';time_buf[8] = (tm_buf[3]>>4)+'0';time_buf[9] = (tm_buf[3]&0x0F)+'0';LCD1602_wbyte(0,1,time_buf,10);time_buf[0] = (tm_buf[4]&0x0F)+'0';LCD1602_wbyte(10,0,time_buf,1);}void Write_original(unsigned char *originalval) {Display_time(originalval);Write_time(0x02,originalval);}void KeyAction(unsigned char kc){unsigned int tmp;if(kc==0x26)//up{}else if(kc==0x28)//down{}else if(kc==0x25)//left:set x,y{if(enter_flag){if(y_value==0){if(x_value<10){x_value++;if(x_value==7){x_value = 10;}}else{x_value = 0;y_value = 1;}}else if(y_value==1){if(x_value<9){x_value++;}else{x_value = 0;y_value = 0;}}Setcursor(x_value,y_value);}}else if(kc==0x27)//right:set value{if(enter_flag){if(y_value==0){if(x_value==0||x_value==1){if(x_value==0){if(set_buf[0]<2){set_buf[0]++;}else{set_buf[0]=0;}}else if(x_value==1){if(set_buf[1]<9){set_buf[1]++;}else{set_buf[1]=0;}}if((set_buf[0]==2)&&(set_buf[1]>3)){set_buf[1] = 0;}t_buf[2] =( set_buf[0]<<4) |( set_buf[1]&0x0F);}else if(x_value==3||x_value==4){if(x_value==3){if(set_buf[2]<5){set_buf[2]++;}else{set_buf[2]=0;}}else if(x_value==4){if(set_buf[3]<9){set_buf[3]++;}else{set_buf[3]=0;}}t_buf[1] =(set_buf[2]<<4 )|( set_buf[3]&0x0F);}else if(x_value==6||x_value==7){if(x_value==6){if(set_buf[4]<5){set_buf[4]++;}else{set_buf[4]=0;}}else if(x_value==7){if(set_buf[5]<9){set_buf[5]++;}else{set_buf[5]=0;}}t_buf[0] = (set_buf[4]<<4 )|( set_buf[5]&0x0F);}else if(x_value==10){if(set_buf[6]<7){set_buf[6]++;}else{set_buf[6] = 0x01;}t_buf[4] = set_buf[6]&0x0F; }}else if(y_value==1){if(x_value==2||x_value==3){if(x_value==2){if(set_buf[7]<9){set_buf[7]++;else{set_buf[7]=0;}}else if(x_value==3){if(set_buf[8]<9){set_buf[8]++;}else{set_buf[8]=0;}}t_buf[6] = (set_buf[7]<<4)|( set_buf[8]);}else if(x_value==5||x_value==6){if(x_value==5){if(set_buf[9]<1){set_buf[9]++;else{set_buf[9]=0;}}else if(x_value==6){if(set_buf[10]<9){set_buf[10]++;}else{set_buf[10]=0;}if((set_buf[9]==1)&&(set_buf[10]>2)){set_buf[10] = 0;}}t_buf[5] = (set_buf[9]<<4)| set_buf[10];}else if(x_value==8||x_value==9){if(x_value==8){if(set_buf[11]<3){set_buf[11]++;}else{set_buf[11]=0;}}else if(x_value==9){if(set_buf[12]<9){set_buf[12]++;}else{set_buf[12]=0;}if((set_buf[11]==3)&&(set_buf[12]>0)&&((t_buf[5]==0x04)| |(t_buf[5]==0x06)||(t_buf[5]==0x09)||(t_buf[5]==0x11))){set_buf[12] = 0;}elseif((set_buf[11]==3)&&(set_buf[12]>1)){set_buf[12] = 0;}}t_buf[3] = (set_buf[11]<<4)|set_buf[12];}if((t_buf[5]==0x02)&&(t_buf[3]>=0x29)){tmp = set_buf[7]*10 + set_buf[8];tmp = tmp + 2000;if((tmp%4==0)&&(tmp%100!=0)){t_buf[3] = 0x29;}else{t_buf[3] = 0x28;}}if(((t_buf[5]==0x04)||(t_buf[5]==0x06)||(t_buf[5]==0x09) ||(t_buf[5]==0x11))&&(t_buf[3]==0x31)){t_buf[3]=0x30;}}Display_time(t_buf);}}else if(kc==0xC0)//esc{OffCursor();Setcursor(0,0);enter_flag = 0;}else if(kc==0x0D)//enter{if(enter_flag==0){enter_flag = 1;OnCursor();Setcursor(0,0);}else{enter_flag = 0;OffCursor();Setcursor(0,0);Write_time(0x02,t_buf); }}else{}}void Timer0_config(unsigned int ms){unsigned long tmp;tmp = (MAIN_Fosc*ms)/1000;tmp = 65536 - tmp;TL0 = (unsigned char)tmp;TH0 = (unsigned char)(tmp>>8);TMOD &= 0xF0;AUXR |= 0x80;ET0 = 1;TR0 = 1;}void Timer0_interrupt() interrupt 1{static unsigned int tmr200ms=0;Key_scan();tmr200ms++;if(tmr200ms>500){tmr200ms = 0;tmr200ms_flag=1; }}/**************************************************/ PCF8563程序及简要说明:/*****************************1.IIC-bus slave address:read A3h and write A2h2.16 8-bit registers3.Binary coded Decimal->BCD4.registers describe1>Control_status_1 address 00h-> 0000 00002>Control_status_2 address 01h-> 0000 00003>VL_seconds address 02h-> VL 000(5) 0000(9)defualt VL = 14>Minutes address 03h-> x 000(5) 0000(9)5>Hours address 04h-> xx 00(2) 0000(9)6>Days address 05h-> xx 00(3) 0000(9)7>Weekdays address 06h-> xxxx x000(6):000->sunday 110->saturday8>Century_months address 07h-> 0xx 0(1) 0000(9)9>Years address 08h-> 0000(9) 0000(9)->99Access time for read/write operations->start->slave address->data/data...->stop->10>~13> alarm registers omitted:default value,min_alarm->0b1000 0000, hour_alarm->0b1000 0000,day_alarm->0b1000 0000,week_alarm->0b1000 0000,14> clkout control register omitted:default value,0b1000 0000,15>Timer_control address 0Eh->default value,0b0000 0000,16>Tiemr address 0Fh->default value,0b0000 0000*******************************/ #include "Library.h"//struct t_truct//{// unsigned char sec;// unsigned char min;// unsigned char hor;// unsigned char day;// unsigned char mon;// unsigned int year;// unsigned char week;//};void Delay1us() //@11.0592MHz {unsigned char i;_nop_();_nop_();i = 8;while (--i);}void IIC_start(){SDA = 1;SCL = 1;Delay1us();SDA = 0;Delay1us();SCL = 0;}void IIC_stop(){SCL = 0;SDA = 0;Delay1us();SCL = 1;Delay1us();SDA = 1;Delay1us();}unsigned char IIC_readAck(){unsigned char val;unsigned char mask;SDA = 1;for(mask=0x80;mask!=0;mask>>=1) {Delay1us();SCL = 1;if(SDA)val |= mask;elseval &= ~mask;Delay1us();SCL = 0;}SDA = 0;Delay1us();SCL = 1;Delay1us();SCL= 0;return val;}unsigned char IIC_readNack(){unsigned char val;unsigned char mask;SDA = 1;for(mask=0x80;mask!=0;mask>>=1) {SCL = 1;Delay1us();if(SDA)val |= mask;elseval &= ~mask;SCL = 0;Delay1us();}SDA = 1;Delay1us();SCL = 1;Delay1us();SCL= 0;return val;}bit IIC_write(unsigned char dat) {unsigned char mask;bit ack;for(mask=0x80;mask!=0;mask>>=1) {//Delay1us();if((dat&mask)==0)SDA = 0;elseSDA = 1;Delay1us();SCL = 1;Delay1us();SCL = 0; ////////}SDA = 1;Delay1us();//SCL = 0;SCL = 1;ack = SDA;Delay1us();// SCL = 1;// Delay1us();SCL = 0;return ~ack;}void Read_time(unsigned char addr,unsigned char *tm_buf) { do{IIC_start();if(IIC_write(0xA2))break;IIC_stop();}while(1);IIC_write(addr);IIC_start();//or IIC_stop()IIC_write(0xA3);tm_buf[0] = IIC_readAck();tm_buf[1] = IIC_readAck();tm_buf[2] = IIC_readAck();tm_buf[3] = IIC_readAck();tm_buf[4] = IIC_readAck();tm_buf[5] = IIC_readAck();tm_buf[6] = IIC_readNack();IIC_stop();}void Write_time(unsigned char addr,unsigned char *tm_buf) {do{IIC_start();if(IIC_write(0xA2))break;IIC_stop();}while(1);IIC_write(addr);IIC_write(tm_buf[0]);IIC_write(tm_buf[1]);IIC_write(tm_buf[2]);IIC_write(tm_buf[3]);IIC_write(tm_buf[4]);IIC_write(tm_buf[5]);IIC_write(tm_buf[6]);IIC_stop(); }/**************************************************/4×4键盘程序:#include "Library.h"/**********************************if enter key down 3second ,into time setting mode,else calculator mode**********************************/unsigned char code keycode[4][4]={{0x31,0x32,0x33,0x26},//up{0x34,0x35,0x36,0x28},//down{0x37,0x38,0x39,0x25},//left{0x30,0xC0,0x0D,0x27},//right};unsigned char keysta[4][4]={{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1},};//bit enter3s;//down 3svoid Key_scan(){static unsigned char keyout = 0;static unsigned char keybuf[4][4]={{0x0F,0x0F,0x0F,0x0F},{0x0F,0x0F,0x0F,0x0F},{0x0F,0x0F,0x0F,0x0F},{0x0F,0x0F,0x0F,0x0F},};unsigned char i;keybuf[keyout][0]=(keybuf[keyout][0]<<1)|keyin_1;keybuf[keyout][1]=(keybuf[keyout][1]<<1)|keyin_2;keybuf[keyout][2]=(keybuf[keyout][2]<<1)|keyin_3;keybuf[keyout][3]=(keybuf[keyout][3]<<1)|keyin_4;for(i=0;i<4;i++){if((keybuf[keyout][i]&0x0F)==0x00){keysta[keyout][i] = 1;}else if((keybuf[keyout][i]&0x0F)==0x0F){keysta[keyout][i] = 0;}}keyout++;keyout &= 0x03;switch(keyout){case 0:keyout_4=1;keyout_1=0;break;case 1:keyout_1=1;keyout_2=0;break;case 2:keyout_2=1;keyout_3=0;break;case 3:keyout_3=1;keyout_4=0;break;default:break;}}void Key_driver(){unsigned char i,j;static unsigned char stabkp[4][4]={{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1},};for(i=0;i<4;i++){for(j=0;j<4;j++){if(stabkp[i][j]!=keysta[i][j]){if(stabkp[i][j]==0){KeyAction(keycode[i][j]); }}stabkp[i][j] = keysta[i][j]; }}}/**************************************************/ LCD1602程序:#include "Library.h"void LCD1602_rsta(){unsigned char tmp;P0 = 0xFF;//this is a mustrs = 0;rw = 1;do{en = 1;//Delay1us();tmp = P0;//Delay1us();en = 0;}while(tmp&0x80);}void LCD1602_wdat(unsigned char dat){LCD1602_rsta();rs=1;rw=0;P0 = dat;en = 1;//Delay1us();en = 0;}void LCD1602_wcmd(unsigned char cmd){LCD1602_rsta();rs=0;rw=0;P0 = cmd;en = 1;//Delay1us();en = 0;}void Setcursor(unsigned char x,unsigned char y){if(y==0)x = x + 0x00;else if(y==1)x = x + 0x40;LCD1602_wcmd(x|0x80);}void LCD1602_wbyte(unsigned char x,unsigned char y,unsigned char *buf,unsigned char buf_len){Setcursor(x,y);while(buf_len>0){LCD1602_wdat(*buf++); buf_len--;}}void OnCursor(){LCD1602_wcmd(0x0F);}void OffCursor(){LCD1602_wcmd(0x0C);}void LCD1602_init(){// Delay15ms();// LCD1602_wcmd(0x38);// Delay5ms();LCD1602_wcmd(0x38);// LCD1602_wcmd(0x08);LCD1602_wcmd(0x06);LCD1602_wcmd(0x0C);LCD1602_wcmd(0x01);}/**************************************************/Library.h#ifndef _Library_H#define _Library_H#include "STC15.h"#include "intrins.h"#define MAIN_Fosc 11059200L//PCF8563sbit SCL = P1^6;sbit SDA = P1^7;//sbit SDA = P5^3;//sbit SCL = P5^2;void Read_time(unsigned char addr,unsigned char *tm_buf); void Write_time(unsigned char addr,unsigned char *tm_buf); void Delay1us();//4x4Keysbit keyin_1 = P2^7;sbit keyin_2 = P2^6;sbit keyin_3 = P5^3;sbit keyin_4 = P5^2;sbit keyout_1 = P4^7;sbit keyout_2 = P4^6;sbit keyout_3 = P4^5;sbit keyout_4 = P4^4;void Key_driver();void Key_scan();void KeyAction(unsigned char kc);//LCD1602sbit rs = P2^4;sbit rw = P2^3;sbit en = P2^1;void LCD1602_init();void LCD1602_wbyte(unsigned char x,unsigned char y,unsigned char *buf,unsigned char buf_len);void OnCursor();void OffCursor();void Setcursor(unsigned char x,unsigned char y);void LCD1602_wdat(unsigned char dat);#endif。
PCF8563时钟芯片驱动详解1概述PCF8563是PHILIPS公司推出的一款工业级内含I2C总线接口功能的具有极低功耗的多功能时钟/日历芯片。
PCF8563的多种报警功能、定时器功能、时钟输出功能以及中断输出功能能完成各种复杂的定时服务,甚至可为单片机提供看门狗功能。
内部时钟电路、内部振荡电路、内部低电压检测电路(1.0V)以及两线制I2C总线通讯方式,不但使外围电路及其简洁,而且也增加了芯片的可靠性。
同时每次读写数据后,内嵌的字地址寄存器会自动产生增量。
当然作为时钟芯片,PCF8563亦解决了2000年问题。
因而,PCF8563是一款性价比极高的时钟芯片,它已被广泛用于电表、水表、气表、电话、传真机、便携式仪器以及电池供电的仪器仪表等产品领域。
2原理图3 8563源代码//******************************************************//define//*****************************************************#define PCF8563_ADDR0xa2// PCF8563设备地址#define PCF8563_ENABLE0x00// 设置#define PCF8563_SUBADDR0x02// 时间地址#define PCF8563_NUMB0x07// 时间个数#define PCF8563_LOOPTIME0x02// 循环次数#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)** 功能描述: 延时函数** 输入:延时毫秒数** 输出:无********************************************************///延时函数单位msvoid 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. 置工作时钟2MHz3.** 输入:无** 输出:无******************************************************************************* /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 enableI2cSM_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 cycleI2cSendCount = count;// 置写入数量I2cRecCount = 0;// 读出数量清零I2cSendDPTR = SendBuf;// SMBus enabled, ACK on acknowledge cycleI2CWRITE;// Chip select + WRITEI2cMemAdd = 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 cycleI2cSendCount = 0;// 置写入数量I2CWRITE;// Chip select + WRITEI2cMemAdd = byte_address;//值地址偏移I2cRecCount = count;//要接收的数据个数I2cRecDPTR = ReadBuf;//指向要接收的数据区STO = 0;STA = 1;// Start transferFeedWatchdog();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),// 因为对于读和写操作来说都必须先写存储器地址。