用户工具

站点工具


侧边栏

抱歉,您没有权限增加页面
4.单片机入门教程:16.iic总线pcf8563时钟

单片机入门教程之PCF8563实时时钟芯片

一:实验原理
PCF8563是PHILPS公司推出的一款IIC总线接口的时钟/日历芯片,可以对年月日周时分秒计时。其他的开发板大多用的都是DS1302,我们用这个,不要问问什么,就是这么任性,喝酸奶只舔盖,益达三粒一起嚼,这两个芯片功能差不多,只是接口不一样。

有了这个芯片就你可以设计出一个电子时钟了,可以在数码管或者液晶上来显示时间。管脚图可以看到这个芯片是没有自定义地址脚的,1和2脚是32.768KHz晶振输入,3脚是中断输出,5和6脚是IIC接口,7脚为可编程时钟输出,4和8脚为电源(1.0-5.5V)。

原理图接法很简单,接上电源和晶振就能工作了,晶振由于温度影响一天可能会误差几秒,想要更准确的时间需要使用高精度的晶振加电容匹配。假如停电了你想要芯片里时间继续走,只要在VCC上接个3V的备用电池就行了,图上那两个二极管隔离就是为了断电后启用备用电池来维持时间继续走的。

二:实验现象与代码解释
IIC总线时序模拟,读写PCF8563时钟芯片,写入年月日时分秒,让时间运行,然后读出时间在5110液晶上显示时间。

由于在24C02那一节说过IIC通信时序了,这里就不提了,IIC通信函数可以直接拿来用的,我们只看PCF8563读写部分。IIC总线读写之前首先要知道读地址和写地址,24C02和PCF8563都是挂在IIC总线上的,这个地址就是用来区分它们的。地址在数据手册上可以找到:

下面来看向PCF8563写一个字节数据,写流程如下:

首先发开始信号,然后发送写地址,等待从机应答,再写入时间的寄存器地址,等待从机应答,下面就是写入时间数据了,等待从机应答,发送停止信号。

//向PCF8563写地址和数据
//Commdata:要写入的命令或数据  Address:寄存器地址
void PCF8563_Write_CMDdata(uchar Commdata,uchar Address)
{			
  IIC_Start();			   
  IIC_Write_Byte(Write);    //写
  IIC_SLave_ACK();
  IIC_Write_Byte(Address);  //写寄存器地址
  IIC_SLave_ACK();
  IIC_Write_Byte(Commdata);	 //写数据
  IIC_SLave_ACK();
  IIC_Stop(); 

}

下面来看按地址读一个字节数据,读流程如下:

首先发送开始信号,在发送写地址,等待应答,然后发送寄存器地址,等待应答。然后再发一次开始信号,发送读地址,接着就是读出的数据了,最后发送停止信号。

//向PCF8563读出此地址的数据
//Address:写寄存器地址,Readdata:返回的数据
uchar PCF8563_Address_Read(uchar Address)
{
  uchar Readdata;		
  IIC_Start();
  IIC_Write_Byte(Write);   //写
  IIC_SLave_ACK();
  IIC_Write_Byte(Address);//写寄存器地址
  IIC_SLave_ACK();

  IIC_Start();
  IIC_Write_Byte(Read);	 //读
  IIC_SLave_ACK();
  Readdata=IIC_Read_Byte();	//读数据
  IIC_Master_NOACK();
  IIC_Stop();
  return Readdata;
}

PCF8563不管读出时间还是写入时间,都要先指定寄存器地址,如果想读出小时寄存器的时间就要先写入小时寄存器地址通知8563,接着8563就会发出小时时间数据了。
读写函数都搞定了,接下来看时间寄存器,如下:

可以看到,除了星期以外,其他的时间在寄存器中存储的格式都是以BCD码存放的,什么是BCD码呢?百度百科上的答案是这样的,BCD码(Binary-Coded Decimal‎)亦称二进码十进数,用4位二进制数来表示1位十进制数中的0~9这10个数码。是一种二进制的数字编码形式。BCD码这种编码形式利用了四个位元来储存一个十进制的数码,使二进制和十进制之间的转换得以快捷的进行。

最常用的BCD码称为8421BCD码,8.4.2.1 分别是4位二进数的位取值。左图为十进制数和8421BCD编码的对应关系表。


比如0010 0001,用四位2进制数来表示1位十进制数就是21,如分钟寄存器这八位分别写入-010 0001,代表的时间就是21分。


对于时间,写入寄存器的格式要以BCD码的形式,读出的BCD码格式要转换成10进制数来显示。BCD码和十进制数互相转换的代码如下:

//PCF8563读出来的是BCD码,要转换为十进制
uchar BCDtoDEC(uchar BCD)  //BCD转十进制
{					   
   return ((BCD>>4)*10)+(BCD&0x0f);
}

//十进制时间写到PCF8563要转换为BCD写进去
uchar DECtoBCD(uchar DEC) //十进制转BCD
{
  return ((DEC/10)<<4)+(DEC%10);
}

PCF8563还有1个控制寄存器,这个寄存器二进制的,用来控制时钟的运行与停止

//时钟运行
void PCF8563_Run()
{
  PCF8563_Write_CMDdata(0x00,0x00); 
}

//时钟停止
void PCF8563_Stop()
{
  PCF8563_Write_CMDdata(0x20,0x00); 
}

该做的都做完了,接下来就可以读写时间了,先来写入一个初始时间。

//初始化写入时间,把年月日时分秒写到PCF8563 按当前时间运行
void PCF8563_Init()
{

  PCF8563_Stop();	//见英文手册第六页寄存器相关

  PCF8563_Write_CMDdata(DECtoBCD(0),0x02); //秒钟
  PCF8563_Write_CMDdata(DECtoBCD(0),0x03); //分钟
  PCF8563_Write_CMDdata(DECtoBCD(12),0x04); //小时

  PCF8563_Write_CMDdata(DECtoBCD(11),0x05); //日
  PCF8563_Write_CMDdata(DECtoBCD(1),0x06); //周
  PCF8563_Write_CMDdata(DECtoBCD(11),0x07); //月
  PCF8563_Write_CMDdata(DECtoBCD(11),0x08); //年

  PCF8563_Run();
}

然后把时间读出来在液晶上显示,时间会接着这个初始时间继续运行。

void main(void)
{

  P4SW=0x70; //P4口打开 默认是关闭的
  P4M1=0xff;
  P4M0=0xff; // 设置为普通IO
  P0=0;//关掉LED
  LEDK=0;//打开液晶背光
  Nokia_5110_Init();
  PCF8563_Init(); //写入时间 11年11月11日1周12:00:00
  Clear_Screen();  //清屏 
  delay_ms(200);
  while(1)
  {	  
	 
	 nian=BCDtoDEC(PCF8563_Address_Read(0x08));
	 yue=BCDtoDEC(PCF8563_Address_Read(0x07)&0x1f);
	 ri=BCDtoDEC(PCF8563_Address_Read(0x05)&0x3f);
	 zhou=BCDtoDEC(PCF8563_Address_Read(0x06)&0x07);
	 shi=BCDtoDEC(PCF8563_Address_Read(0x04)&0x3f);
	 fen=BCDtoDEC(PCF8563_Address_Read(0x03)&0x7f);
	 miao=BCDtoDEC(PCF8563_Address_Read(0x02)&0x7f); //读出时间

	 Ascii_8X16_Font(0,0,Font_8X16[nian/10]);  //液晶显示时间
	 Ascii_8X16_Font(8,0,Font_8X16[nian%10]);
	 Ch_16X16_Font(16,0,Font_16X16[0]);	 //年

	 Ascii_8X16_Font(32,0,Font_8X16[yue/10]);  
	 Ascii_8X16_Font(40,0,Font_8X16[yue%10]);
	 Ch_16X16_Font(48,0,Font_16X16[1]);	 //月

	 Ascii_8X16_Font(0,2,Font_8X16[ri/10]);  
	 Ascii_8X16_Font(8,2,Font_8X16[ri%10]);
	 Ch_16X16_Font(16,2,Font_16X16[2]);	 //日
 
	 Ch_16X16_Font(32,2,Font_16X16[3]);	 //周
	 Ascii_8X16_Font(48,2,Font_8X16[zhou]);

	 Ascii_8X16_Font(0,4,Font_8X16[shi/10]);  
	 Ascii_8X16_Font(8,4,Font_8X16[shi%10]);
	 Ascii_8X16_Font(16,4,Font_8X16[10]);  //时
	
	 Ascii_8X16_Font(24,4,Font_8X16[fen/10]);  
	 Ascii_8X16_Font(32,4,Font_8X16[fen%10]);
	 Ascii_8X16_Font(40,4,Font_8X16[10]);  //分

	 Ascii_8X16_Font(48,4,Font_8X16[miao/10]);  
	 Ascii_8X16_Font(56,4,Font_8X16[miao%10]);

  }

}
本完整工程在stc51 discovery开发板【实验例程】【进阶实验】【实验四十四】

OK了,这里只是个PCF8563的读写测试,自己把加按键加上去做个电子时钟玩玩吧,想要校时,就是先把时钟停止,然后把按键设定的值写进去就行了。

4.单片机入门教程/16.iic总线pcf8563时钟.txt · 最后更改: 2017/03/08 16:19 由 wawooo