基于I2C总线的时钟电路总结Word格式文档下载.docx
《基于I2C总线的时钟电路总结Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《基于I2C总线的时钟电路总结Word格式文档下载.docx(30页珍藏版)》请在冰点文库上搜索。
C总线上传送的数据信号是广义的,既包括地址,又包括地址信号,又包括真正的数据信号。
在起始信号后必须传送一个从机的地址(7位),第8位是数据的传送方向位(R/),用“0”表示主机发送数据(T),“1”表示主机接收数据(R)。
每次数据传送总是由主机产生的终止信号结束。
但是,若主机希望继续占有总线进行新的数据传送,则可以不产生终止信号,马上再次发出起始信号对另一从机进行寻址。
1.5、总线的寻址
C总线协议有明确的规定:
采用7位的寻址字节(寻址字节是起始信号后的第一个字节)。
如图1-4所示。
图1-4寻址字节
D7~D1位组成从机的地址。
D0位是数据传送方向位,为“0”时表示主机向从机写数据,为“1”时表示主机由从机读数据。
二、PCF8563芯片
2.1、概述
PCF8563是低功耗的CMOS实时时钟日历芯片。
它提供一个可编程时钟输出,一个中断输出和掉电检测器,所有的地址和数据通过
C总线接口串行传递,最大总线速度为400Kbit/s,每次读写数据后,内嵌的字地址寄存器会自动产生增量。
2.2、特性
①低工作电流:
典型值为0.25uA(
=3.0V,
=25℃时);
②世纪标志;
③大工作电压范围:
1.0~5.5V;
④低休眠电流:
=25℃);
⑤400KHz的
C总线接口(
=1.8~5.5V时);
⑥可编程时钟输出频率为:
32.768KHz,1024Hz,32Hz,1Hz;
⑦报警和定时器;
⑧内部集成的振荡器电容、片内电源复位功能、掉电检测等;
⑨
C总线从地址:
读,0A3H;
写,0A2H;
⑩开漏中断引脚。
2.3、功能描述
PCF8563内有16个8位的地址递增寄存器,一个32.768KHz片上集成电容振荡器,一个实时时钟源(RTC)的分频器,可编程的时钟输出,一个定时器,一个报警器,一个低压检测器和400KHz的
C接口。
所有16个寄存器被设计成可寻址的8位并行寄存器,虽然不是所有位都有效。
前两个寄存器(内存地址00H和01H),用于控制与/或状态寄存器。
内存地址02H至08H是时钟功能的计数器,用于(秒、分、时、日、月、年计数器)。
内存地址09H至0CH包含定义报警的条件的报警寄存器。
内存地址0DH控制CLKOUT的输出频率。
0EH和0FH分别是定时控制器和定时器。
秒、分钟、小时、天、月、年以及每分钟报警、小时报警、日报警寄存器都以BCD格式编码。
平日和星期报警寄存器不以BCD格式编码。
当一个RTC寄存器被读取,所有的寄存器的内容被冻结。
因此可以避免在读指令跳转期间,读取时钟/日历时发生错误。
三、硬件仿真实现
硬件电路设计包括PCF8563时钟芯片,日历器件与89C51单片机的接口电路,LMO44L液晶显示电路。
总体原理图见附录一。
3.1、单片机型号的选择
通过对多种单片机性能的分析,最终认为89C51是最理想的电子时钟开发芯片。
89C51是一种带4K字节闪烁可编程可擦除只读存储器的低电压,高性能CMOS8位微处理器,器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。
3.2、使用的PCF8563芯片
PCF8563芯片与单片机连接的原理图如图3-1所示:
图3-1PCF8563原理图
其中,需要注意的是数据线SDA和时钟线SCL必须接上拉电阻。
3.3、显示电路
LMO44L液晶显示屏与单片机连接的原理图如图3-2所示:
图3-2LCD显示电路
3.4、Protues使用
Protues软件是英国Labcenterelectronics公司出版的EDA工具软件(该软件中国总代理为广州风标电子技术有限公司)。
它不仅具有其它EDA工具软件的仿真功能,还能仿真单片机及外围器件。
它是目前最好的仿真单片机及外围器件的工具。
本程序通过Keil单片机开发平台实现程序的编译,链接,生成HEX文件。
通过Keil和硬件仿真平台Protues的联合,可以将运行效果仿真出来,根据效果,有目的的改变设计,优化程序。
仿真软件Protues功能强大,是一个很方便的软件,可以运行HEX文件,不用每次都下载到实物中测试。
用Protue画好电路图后,双击单片机,将事先生成的HEX文件(HEX文件在Keil软件中生成)添加到“ProgramFile”一栏中,如图3-3所示,点确定,这样所编的程序就加载到了单片机中,然后点左下角的三角形开始按钮,就可以看到仿真结果,如图所示。
图3-3加载HEX文件
图3-4仿真结果
四、程序说明
4.1流程图
图4-1系统流程图
4.2、主程序设计
主程序设计思路为:
先对系统进行初始化,如:
对LCD初始化,PCF8563初始化等,然后才能进入现实模块,即可在LCD上看到相应的信息。
对于LCD的初始化,主要是对开启显示屏,清屏,设置显示初始行等操作。
PCF8563初始化,主要是写入一个初始值。
五、运行效果展现
本程序通过Keil单片机开发平台实现程序的编译,连接,生成HEX文件。
通过Keil和硬件仿真平台Proteus的联合,可以将设计效果仿真出来,根据效果,有目的的改变设计,优化程序。
利用Proteus仿真实验过程截图:
普通时间显示模式仿真图,表示:
2014年11月20日15点50分21秒。
图5-1仿真图
附录一总原理图
附录二源程序
#include<
reg51.h>
intrins.h>
#defineucharunsignedchar
#defineuintunsignedint
ucharcodetable1[]="
Time:
00-00-00"
;
ucharcodetable2[]="
Date:
00/00/00"
charp0,z0,p1,z1,p2,z2,p3,z3,p4,z4,p5,z5;
ucharmodstate;
//模式状态
bityu=0;
sbitSDA=P1^7;
//将p1.7口模拟数据口
sbitSCL=P1^6;
//将p1.6口模拟时钟口
sbitrs=P2^0;
sbitrw=P2^1;
sbiten=P2^2;
#defineSEC0x02//秒寄存器
#defineMIN0x03//分寄存器
#defineHOUR0x04//时寄存器
#defineDAY0x05//日寄存器
#defineWEEK0x06//周寄存器
#defineMONTH0x07//月寄存器
#defineYEAR0x08//年寄存器
#defineread_ADD0xA3//读器件地址
#definewrite_ADD0xA2//写器件地址
#definedelayNOP();
{_nop_();
_nop_();
};
unsignedcharg8563_Store[7];
/*时间交换区,全局变量声明*/
bitbdataSystemError=0;
//从机错误标志位
voidiic_start(void)
{
EA=0;
//时钟保持高,数据线从高到低一次跳变,I2C通信开始
SDA=1;
SCL=1;
delayNOP();
//延时5us
SDA=0;
SCL=0;
}
voidiic_stop(void)
{
//时钟保持高,数据线从低到高一次跳变,I2C通信停止
voidslave_ACK(void)
voidslave_NOACK(void)
//--------------------------------------------------------------------------------------------------
//函数名称:
check_ACK
//函数功能:
主机应答位检查子程序,迫使数据传输过程结束
voidcheck_ACK(void)
//将p1.7设置成输入,必须先向端口写1
yu=0;
if(SDA==1)//若SDA=1表明非应答,置位非应答标志F0
yu=1;
IICSendByte
//入口参数:
ch
发送一个字节
voidIICSendByte(unsignedcharch)
unsignedcharidatan=8;
//向SDA上发送一位数据字节,共八位
while(n--)
{
if((ch&
0x80)==0x80)//若要发送的数据最高位为1则发送位1
{
//传送位1
SDA=0;
}
else
//否则传送位0
ch=ch<
<
1;
//数据左移一位
IICreceiveByte
//返回接收的数据
接收一字节子程序
unsignedcharIICreceiveByte(void)
//从SDA线上读取一上数据字节,共八位
unsignedchartdata;
tdata=tdata<
//左移一位,或_crol_(temp,1)
if(SDA==1)
tdata=tdata|0x01;
//若接收到的位为1,则数据的最后一位置1
else
tdata=tdata&
0xfe;
//否则数据的最后一位置0
SCL=0;
return(tdata);
//用户调用子程序
write_CFGbyte
CFG_add寄存器地址,CFG_data要写入寄存器的数值
发送n位数据子程序
voidwrite_CFGbyte(unsignedcharCFG_add,unsignedcharCFG_data)
iic_start();
//启动I2C
IICSendByte(write_ADD);
//发送器件写地址
check_ACK();
//检查应答位
if(yu==1)
{
SystemError=1;
return;
//若非应答表明器件错误或已坏,置错误标志位SystemError
IICSendByte(CFG_add);
//发送寄存器地址
IICSendByte(CFG_data);
//发送寄存器数据
iic_stop();
//全部发完则停止
receiveNbyte
CFG_add寄存器地址地址
//出口参数:
receive_da
接收某个寄存器数据子程序
unsignedcharreceive_CFGbyte(unsignedcharidataCFG_add)
unsignedcharidatareceive_da;
//器件写地址
return(0);
//寄存器地址
IICSendByte(read_ADD);
//器件读地址
receive_da=IICreceiveByte();
slave_NOACK();
//收到最后一个字节后发送一个非应答位
return(receive_da);
//用户调用函数
receive_CFGNbyte
CFG_add寄存器地址地址,n连续读数位,*buff存储区地址
接收n个寄存器数据子程序
voidreceive_CFGNbyte(unsignedcharCFG_add,unsignedcharn,unsignedchar*buff)
unsignedcharreceive_da,i=0;
//调试用
}
buff[i++]=receive_da;
if(n!
=0)
slave_ACK();
//收到一个字节后发送一个应答位
P8563_Readtime
读出时间信息
voidP8563_Readtime()
{unsignedchartime[7];
receive_CFGNbyte(SEC,0x07,time);
g8563_Store[0]=time[0]&
0x7f;
/*秒*/
g8563_Store[1]=time[1]&
/*分*/
g8563_Store[2]=time[2]&
0x3f;
/*小时*/
g8563_Store[3]=time[3]&
/*日*/
g8563_Store[5]=time[5]&
g8563_Store[6]=time[6]&
P8563_settime
写时间修改值
voidP8563_settime()
unsignedchari;
for(i=2;
i<
=8;
i++)
write_CFGbyte(i,g8563_Store[i-2]);
}
//write_CFGbyte(6,g8563_Store[3]);
P8563_init
初始设置
voidP8563_init()
write_CFGbyte(0x02,0x12);
write_CFGbyte(0x03,0x50);
write_CFGbyte(0x04,0x15);
write_CFGbyte(0x05,0x20);
write_CFGbyte(0x07,0x11);
write_CFGbyte(0x08,0x14);
voiddelay(uintn)
uintx,y;
for(x