- #include <reg51.h>
- #include <absacc.h>
- #include <intrins.h>
- #define uchar unsigned char
- sbit SDA=P1^4;
- sbit SCL=P1^5;
- uchar g8563_Store[6]={0x23,0x12,0x31,0x23,0x59,0x40}; /*时间交换区,全局变量声明*/
- uchar code c8563_Store[6]={0x13,0x09,0x22,0x10,0x40,0x00}; /*写入时间初值:星期一 07:59:00*/
- /********************************************
- 内部函数,延时1
- ********************************************/
- void Delay()
- {
- _nop_();_nop_(); _nop_();_nop_();_nop_();_nop_();/*根据晶振频率制定延时时间*/
- }
- /********************************************
- 内部函数,I2C开始
- ********************************************/
- void Start()
- {
- SDA=1;
- SCL=1;
- Delay();
- SDA=0;
- Delay();
- SCL=0;
- }
- /********************************************
- 内部函数,I2C结束
- ********************************************/
- void Stop()
- {
- SDA=0;
- SCL=0;
- Delay();
- SCL=1;
- Delay();
- SDA=1;
- Delay();
- }
- /********************************************
- 内部函数,输出ACK ,每个字节传输完成,输出ack=0,结束读书据,ack=1;
- ********************************************/
- void WriteACK(uchar ack)
- {
- SDA=ack;
- Delay();
- SCL=1;
- Delay();
- SCL=0;
- }
- /********************************************
- 内部函数,等待ACK
- ********************************************/
- void WaitACK()
- {
- uchar errtime=20;
- SDA=1;
- Delay(); /*读ACK*/
- SCL=1;
- Delay();
- while(SDA)
- {
- errtime--;
- if(!errtime)
- Stop();
- }
- SCL=0;
- Delay();
- }
- /********************************************
- 内部函数.输出数据字节
- 入口:B=数据
- ********************************************/
- void writebyte(uchar wdata)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- if(wdata&0x80)
- SDA=1;
- else
- SDA=0;
- wdata<<=1;
- SCL=1;
- Delay();
- SCL=0;
- }
- WaitACK(); //I2C器件或通讯出错,将会退出I2C通讯
- }
- /********************************************
- 内部函数.输入数据
- 出口:B
- ********************************************/
- uchar Readbyte()
- {
- uchar i,bytedata;
- SDA=1;
- for(i=0;i<8;i++)
- {
- SCL=1;
- bytedata<<=1;
- bytedata|=SDA;
- SCL=0;
- Delay();
- }
- return(bytedata);
- }
- /********************************************
- 输出数据->pcf8563
- ********************************************/
- void writeData(uchar address,uchar mdata)
- {
- Start();
- writebyte(0xa2); /*写命令*/
- writebyte(address); /*写地址*/
- writebyte(mdata); /*写数据*/
- Stop();
- }
- /********************************************
- 输入数据<-pcf8563
- ********************************************/
- /*uchar ReadData(uchar address) //单字节
- {
- uchar rdata;
- Start();
- writebyte(0xa2); //写命令
- writebyte(address); //写地址
- Start();
- writebyte(0xa3); //读命令
- rdata=Readbyte();
- WriteACK(1);
- Stop();
- return(rdata);
- } */
- void ReadData1(uchar address,uchar count,uchar * buff) /*多字节*/
- {
- uchar i;
- Start();
- writebyte(0xa2); /*写命令*/
- writebyte(address); /*写地址*/
- Start();
- writebyte(0xa3); /*读命令*/
- for(i=0;i<count;i++)
- {
- buff[i]=Readbyte();
- if(i<count-1)
- WriteACK(0);
- }
- WriteACK(1);
- Stop();
- }
- /********************************************
- 内部函数,读入时间到内部缓冲区
- ********************************************/
- void P8563_Read()
- {
- uchar time[7];
- ReadData1(0x02,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[4]=time[5]&0x1f; /*月 */
- g8563_Store[5]=time[6]; /*年 */
-
- }
- /********************************************
- 读入时间到内部缓冲区----外部调用
- ********************************************/
- void P8563_gettime()
- {
- P8563_Read();
- if(g8563_Store[0]==0)
- P8563_Read(); /*如果为秒=0,为防止时间变化,再读一次*/
- }
- /********************************************
- 写时间修改值
- ********************************************/
- void P8563_settime()
- {
- //uchar i;
- writeData(8,g8563_Store[0]); //年
- writeData(7,g8563_Store[1]); //月
- writeData(5,g8563_Store[2]); //日
- writeData(4,g8563_Store[3]); //时
- writeData(3,g8563_Store[4]); //分
- writeData(2,g8563_Store[5]); //秒
- }
- /********************************************
- P8563的初始化-----外部调用
- ********************************************/
- void P8563_init()
- {
- uchar i;
- // P8563_settime();
- //for(i=0;i<=5;i++) g8563_Store[i]=c8563_Store[i]; /*初始化时间*/
- P8563_settime();
- // if((ReadData(0x0a)&0x3f)!=0x08) /*检查是否第一次启动,是则初始化时间*/
- // {
- // P3_4 = 0;
- // for(i=0;i<=3;i++) g8563_Store[i]=c8563_Store[i]; /*初始化时间*/
- // P8563_settime();
- // writeData(0x0,0x00);
- // writeData(0xa,0x8); /*8:00报警*/
- // writeData(0x1,0x12); /*报警有效*/
- // writeData(0xd,0xf0); //编程输出32.768K的频率
- // }
- }
主程序
- #include<reg51.h >
- #include"OLED.H"
- extern unsigned char g8563_Store[6];
- extern void P8563_init();
- extern void P8563_gettime();
- void main(void)
- {
- int i;
- unsigned char shi,ge;
- LCD_Init();
- LCD_CLS();
- LCD_P8x16Str(20,4,(u8*)"20 - - ");
- LCD_P6x8Str(20,6,(u8*)" : : ");
- P8563_init();
- //Draw_BMP(0,0,100,3,(u8*)Dot);
- while(1)
- {
- P8563_gettime();
- shi=(g8563_Store[0]>>4)+0x30;
- ge=(g8563_Store[0]&0x0f)+0x30;
- LCD_P8x16Char(68,6,shi);
- LCD_P8x16Char(76,6,ge);
- shi=(g8563_Store[1]>>4)+0x30;
- ge=(g8563_Store[1]&0x0f)+0x30;
- LCD_P8x16Char(44,6,shi);
- LCD_P8x16Char(52,6,ge);
- shi=(g8563_Store[2]>>4)+0x30;
- ge=(g8563_Store[2]&0x0f)+0x30;
- LCD_P8x16Char(20,6,shi);
- LCD_P8x16Char(28,6,ge);
- shi=(g8563_Store[3]>>4)+0x30;
- ge=(g8563_Store[3]&0x0f)+0x30;
- LCD_P8x16Char(68,4,shi);
- LCD_P8x16Char(76,4,ge);
- shi=(g8563_Store[4]>>4)+0x30;
- ge=(g8563_Store[4]&0x0f)+0x30;
- LCD_P8x16Char(44,4,shi);
- LCD_P8x16Char(52,4,ge);
- shi=(g8563_Store[5]>>4)+0x30;
- ge=(g8563_Store[5]&0x0f)+0x30;
- LCD_P8x16Char(20,4,shi);
- LCD_P8x16Char(28,4,ge);
- for(i=0;i<20000;i++);
- }
- }
效果图: