基于I2C总线的时钟电路总结.docx
- 文档编号:11608845
- 上传时间:2023-03-28
- 格式:DOCX
- 页数:30
- 大小:226.48KB
基于I2C总线的时钟电路总结.docx
《基于I2C总线的时钟电路总结.docx》由会员分享,可在线阅读,更多相关《基于I2C总线的时钟电路总结.docx(30页珍藏版)》请在冰豆网上搜索。
基于I2C总线的时钟电路总结
基于
C总线的时钟电路总结
C总线
1.1、概述
C总线是由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备。
是微电子通信控制领域广泛采用的一种总线标准。
它是同步通信的一种特殊形式,具有接口线少,控制方式简单,器件封装形式小,通信速率较高等优点。
C总线只有两根双向信号线,一根是数据线SDA,一根是时钟线SCL。
C总线通过上拉电阻接正电源。
当总线空闲时,两根线均为高电平。
连到总线上的任一器件输出的低电平,都将使总线的信号变低,机各器件的SDA及SCL都是线“与”关系。
1.2、起始和终止信号
SCL线为高电平期间,SDA线由高电平向低电平的变化表示起始信号;SCL线为高电平期间,SDA线由低电平向高电平的变化表示终止信号。
时序图如图1-1所示。
起始和终止信号都是由主机发出的,在起始信号产生后,总线就处于被占用的状态;在终止信号产生后,总线就处于空闲状态。
图1-1起始和终止信号
1.3、数据位的有效性规定
C总线进行数据传送时,SDA线必须在时钟的高电平周期保持稳定,SDA的高或低电平状态只有在SCL线的时钟信号是低电平时才能改变。
如图1-2所示。
图1-2数据位的有效变化
1.4、数据传送格式
1.4.1字节传送与应答
发送到SDA线上的每个字节必须为8位,每次传输可以发送的字节数量不受限制。
首先传输的是数据的最高位(MSB),每个字节后必须跟随一位应答位(即一帧共有九位),如图1-3所示。
图1-3发送字节
1.4.2数据帧格式
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;
④低休眠电流:
典型值为0.25uA(
=3.0V,
=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
#include
#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_();_nop_();_nop_();};
unsignedcharg8563_Store[7];/*时间交换区,全局变量声明*/
bitbdataSystemError=0;//从机错误标志位
voidiic_start(void)
{
EA=0;//时钟保持高,数据线从高到低一次跳变,I2C通信开始
SDA=1;
SCL=1;
delayNOP();//延时5us
SDA=0;
delayNOP();
SCL=0;
}
voidiic_stop(void)
{
SDA=0;//时钟保持高,数据线从低到高一次跳变,I2C通信停止
SCL=1;
delayNOP();
SDA=1;
delayNOP();
SCL=0;
}
voidslave_ACK(void)
{
SDA=0;
SCL=1;
delayNOP();
SCL=0;
delayNOP();
SDA=1;
}
voidslave_NOACK(void)
{
SDA=1;
SCL=1;
delayNOP();
SCL=0;
SDA=0;
}
//--------------------------------------------------------------------------------------------------
//函数名称:
check_ACK
//函数功能:
主机应答位检查子程序,迫使数据传输过程结束
//--------------------------------------------------------------------------------------------------
voidcheck_ACK(void)
{
SDA=1;//将p1.7设置成输入,必须先向端口写1
SCL=1;
delayNOP();
yu=0;
if(SDA==1)//若SDA=1表明非应答,置位非应答标志F0
yu=1;
SCL=0;
}
//--------------------------------------------------------------------------------------------------
//函数名称:
IICSendByte
//入口参数:
ch
//函数功能:
发送一个字节
//--------------------------------------------------------------------------------------------------
voidIICSendByte(unsignedcharch)
{
unsignedcharidatan=8;//向SDA上发送一位数据字节,共八位
while(n--)
{
if((ch&0x80)==0x80)//若要发送的数据最高位为1则发送位1
{
SDA=1;//传送位1
SCL=1;
delayNOP();
SCL=0;
SDA=0;
}
else
{
SDA=0;//否则传送位0
SCL=1;
delayNOP();
SCL=0;
}
ch=ch<<1;//数据左移一位
}
}
//--------------------------------------------------------------------------------------------------
//函数名称:
IICreceiveByte
//返回接收的数据
//函数功能:
接收一字节子程序
//--------------------------------------------------------------------------------------------------
unsignedcharIICreceiveByte(void)
{
unsignedcharidatan=8;//从SDA线上读取一上数据字节,共八位
unsignedchartdata;
while(n--)
{
SDA=1;
SCL=1;
tdata=tdata<<1;//左移一位,或_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);//发送寄存器地址
check_ACK();//检查应答位
if(yu==1)
{
SystemError=1;
return;//若非应答表明器件错误或已坏,置错误标志位SystemError
}
IICSendByte(CFG_data);//发送寄存器数据
check_ACK();//检查应答位
if(yu==1)
{
SystemError=1;
return;//若非应答表明器件错误或已坏,置错误标志位SystemError
}
iic_stop();//全部发完则停止
}
//--------------------------------------------------------------------------------------------------
//用户调用子程序
//函数名称:
receiveNbyte
//入口参数:
CFG_add寄存器地址地址
//出口参数:
receive_da
//函数功能:
接收某个寄存器数据子程序
//--------------------------------------------------------------------------------------------------
unsignedcharreceive_CFGbyte(unsignedcharidataCFG_add)
{
unsignedcharidatareceive_da;
iic_start();
IICSendByte(write_ADD);//器件写地址
check_ACK();
if(yu==1)
{
SystemError=1;
return(0);
}
IICSendByte(CFG_add);//寄存器地址
check_ACK();
if(yu==1)
{
SystemError=1;
return(0);
}
iic_start();
IICSendByte(read_ADD);//器件读地址
check_ACK();
if(yu==1)
{
SystemError=1;
return(0);
}
receive_da=IICreceiveByte();
slave_NOACK();//收到最后一个字节后发送一个非应答位
iic_stop();
return(receive_da);
}
//--------------------------------------------------------------------------------------------------
//用户调用函数
//函数名称:
receive_CFGNbyte
//入口参数:
CFG_add寄存器地址地址,n连续读数位,*buff存储区地址
//函数功能:
接收n个寄存器数据子程序
//--------------------------------------------------------------------------------------------------
voidreceive_CFGNbyte(unsignedcharCFG_add,unsignedcharn,unsignedchar*buff)
{
unsignedcharreceive_da,i=0;
iic_start();
IICSendByte(write_ADD);//器件写地址
check_ACK();
if(yu==1)
{
yu=1;//调试用
SystemError=1;
return;
}
IICSendByte(CFG_add);//寄存器地址
check_ACK();
if(yu==1)
{
SystemError=1;
return;
}
iic_start();
IICSendByte(read_ADD);//器件读地址
check_ACK();
if(yu==1)
{
SystemError=1;
return;
}
while(n--)
{
receive_da=IICreceiveByte();
buff[i++]=receive_da;
if(n!
=0)
{
slave_ACK();//收到一个字节后发送一个应答位
}
else
{
slave_NOACK();//收到最后一个字节后发送一个非应答位
}
}
iic_stop();
}
//--------------------------------------------------------------------------------------------------
//用户调用函数
//函数名称:
P8563_Readtime
//函数功能:
读出时间信息
//--------------------------------------------------------------------------------------------------
voidP8563_Readtime()
{unsignedchartime[7];
receive_CFGNbyte(SEC,0x07,time);
g8563_Store[0]=time[0]&0x7f;/*秒*/
g8563_Store[1]=time[1]&0x7f;/*分*/
g8563_Store[2]=time[2]&0x3f;/*小时*/
g8563_Store[3]=time[3]&0x3f;/*日*/
g8563_Store[5]=time[5]&0x3f;
g8563_Store[6]=time[6]&0x7f;
}
//--------------------------------------------------------------------------------------------------
//用户调用函数
//函数名称:
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
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 I2C 总线 时钟 电路 总结