📄 pcf8563.c
字号:
/*---------------PCF8563修改历史----------------
2008.5.4 添加启动停止函数
2008.5.8 添加键值管理和识别函数
2008.5.8 添加时间显示函数year_display()等
2008.5.9 添加部分调节时间的代码
2008.5.11 添加闹钟显示部分
2008.5.14 添加时钟关闭程序
-----------------------------------------------*/
#include <reg52.h>
#include <intrins.h>
#include "lcd.h"
#include "IIC.h"
#include "common.h"
//开始PCF8563T驱动程序
/*--------------------------------------------------------------------------------
调用方式:void GetPCF8563(uchar firsttype,uchar count,uchar *buff) ﹫2001/08/0 7
函数说明:读取时钟芯片PCF8563的时间,设置要读的第一个时间类型firsttype,并设置读取
的字节数,则会一次把时间读取到buff中。顺序是:
0x02:秒/0x03:分/0x04:小时/0x05:日/0x06:星期/0x07:月(世纪)/0x08:年
---------------------------------------------------------------------------------*/
void GetPCF8563(uchar firsttype,uchar count,uchar *buff)
{
uchar i;
start();
sendbyte(0xA2);
WaitAck();
sendbyte(firsttype);
WaitAck();
start();
sendbyte(0xA3);
WaitAck();
for (i=0;i<count;i++)
{
buff[i]=receivebyte();
if (i!=count-1) ack();//除最后一个字节外,其他都要从MASTER发应答。
}
n_ack();
stop();
}
//---------------------------------------------------------------------------------
//调用方式:void SetPCF8563(uchar timetype,uchar value) ﹫2001/08/0 7
//函数说明:调整时钟。timetype是要改的时间类型,value是新设置的时间值(BCD格式)。
//0x02:秒/0x03:分/0x04:小时/0x05:日/0x06:星期/0x07:月(世纪)/0x08:年
//---------------------------------------------------------------------------------*/
void SetPCF8563(uchar timetype,uchar value)
{
start();
sendbyte(0xA2);
WaitAck();
sendbyte(timetype);
WaitAck();
sendbyte(value);
WaitAck();
stop();
}
//---------------------PCF8563启动停止函数------------------------------------------
void pcf8563start(void)
{
SetPCF8563(ctrl1,0x00);
}
void pcf8563stop(void)
{
SetPCF8563(ctrl1,0x20);
}
//---------------------PCF8563出始时间设定------------------------------------------
void setime(void)
{
/*SetPCF8563(year,0x08);
SetPCF8563(month,0x03);
SetPCF8563(week,0x01);
SetPCF8563(day,0x03);
SetPCF8563(hour,0x12);
SetPCF8563(minute,0x00);*/
GetPCF8563(minute,6,rbuf);
time_display(rbuf);
return;
}
/********************* 键盘识别程序 **********************/
uint getch(void)
{ uchar X,Y,Z;
uint k;
P1=0xff;
P1=0x0f; //先对P3置数 行扫描
if(P1!=0x0f) //判断是否有键按下
{delay(10); //延时,软件去干扰
if(P1!=0x0f) //确认按键按下X = P3;
{
X=P1; //保存行扫描时有键按下时状态
P1=0xf0; //列扫描
Y=P1; //保存列扫描时有键按下时状态
Z=X|Y; //取出键值
switch ( Z ) //判断键值(那一个键按下)
{
case 0xee: k=13; break; //对键值赋值
case 0xde: k=11; break;
case 0xbe: k=0; break;
case 0x7e: k=10; break;
case 0xed: k=12; break;
case 0xdd: k=9; break;
case 0xbd: k=8; break;
case 0x7d: k=7; break;
case 0xeb: k=14; break;
case 0xdb: k=6; break;
case 0xbb: k=5;break;
case 0x7b: k=4;break;
case 0xe7: k=15;break;
case 0xd7: k=3;break;
case 0xb7: k=2;break;
case 0x77: k=1;break;
default : k=16;break;
}
}
}
return k;
}
/********************* 键值判断程序**********************/
void keyscan(void)
{ uint key;
uchar gw,sw;
key=getch();
delay(50);
switch(key) //不同的键值做不同的处理
{case 15: count++; //mode 功能键
if((count>=1)&&(count<=6))
char_display(0x00,LabelCount++);
else
{count=0;
LabelCount=0x3e;
char_display(0x00,0x20);
}
break;
case 14: GetPCF8563(second,1,vbuf);
if(vbuf[0]&0x80)
{lcd_init();
lcd_display(0x41,battery_low);
delay(1500);
lcd_init();
vbuf[0]=vbuf[0]&0x7f;
SetPCF8563(second,vbuf[0]); count=0;
}
else
{lcd_init();
lcd_display(0x01,battery_ok);
delay(1500);
lcd_init();
}
count=0;
EnterCount=0;
AlarmCount=0;
DataCount=0;
LightCount=0;
break;
case 12: if(count==1) //相加键,递增键为1是调节年寄存器中的数值!
{
gw=rbuf[5]&0x0f; //年的个位十位分离
sw=(rbuf[5]>>4)&0x0f;
if(gw==0x09) //判断个位和十位是否为9
{
if(sw==0x09)
{gw=0;
sw=0;
}
else
{ gw=0;
sw+=1;
}
}
else
gw+=1;
rbuf[5]=(sw<<4)+gw;
SetPCF8563(year,rbuf[5]);
}
else if(count==2) //调节月寄存器中的数值!
{
rbuf[4]=rbuf[4]&0x1f;
if(rbuf[4]==0x09)
rbuf[4]=0x10;
else if(rbuf[4]==0x12)
rbuf[4]=0x01;
else
rbuf[4]+=1;
SetPCF8563(month,rbuf[4]);
}
else if(count==4)
{
rbuf[3]=rbuf[3]&0x07;
if(rbuf[3]==0x06)
rbuf[3]=0x00;
else
rbuf[3]=rbuf[3]+1;
SetPCF8563(week,rbuf[3]);
}
else if(count==3)
{
rbuf[2]=rbuf[2]&0x3f;
gw=rbuf[2]&0x0f;
sw=(rbuf[2]>>4)&0x0f;
if(rbuf[2]==0x31) //判断个位和十位是否为9
{gw=1;
sw=0;
}
else if(gw==0x09)
{gw=0;
sw+=1;
}
else
gw+=1;
rbuf[2]=(sw<<4)+gw;
SetPCF8563(day,rbuf[2]);
}
else if(count==5)
{
rbuf[1]=rbuf[1]&0x3f;
if(rbuf[1]==0x09)
rbuf[1]=0x10;
else if(rbuf[1]==0x19)
rbuf[1]=0x20;
else if(rbuf[1]==0x23)
rbuf[1]=0x0;
else
rbuf[1]+=1;
SetPCF8563(hour,rbuf[1]);
}
else if(count==6)
{
rbuf[0]=rbuf[0]&0x7f;
gw=rbuf[0]&0x0f;
sw=(rbuf[0]>>4)&0x0f;
if(gw==0x09)
{ if(sw==0x05)
{sw=0;
gw=0;
}
else
{gw=0;
sw+=1;
}
}
else
gw+=1;
rbuf[0]=(sw<<4)+gw;
SetPCF8563(minute,rbuf[0]);
}
else
break;
break;
case 13: if(count==1) //相减键,相减键为1是调节年寄存器中的数值!
{
gw=rbuf[5]&0x0f; //年的个位十位分离
sw=(rbuf[5]>>4)&0x0f;
if(gw==0x0) //判断个位和十位是否为0
{
if(sw==0x0)
{gw=9;
sw=9;
}
else
{ gw=9;
sw-=1;
}
}
else
gw-=1;
rbuf[5]=(sw<<4)+gw;
SetPCF8563(year,rbuf[5]);
}
else if(count==2) //调节月寄存器中的数值!
{
rbuf[4]=rbuf[4]&0x1f;
if(rbuf[4]==0x10)
rbuf[4]=0x9;
else if(rbuf[4]==0x01)
rbuf[4]=0x12;
else
rbuf[4]-=1;
SetPCF8563(month,rbuf[4]);
}
else if(count==4)
{
rbuf[3]=rbuf[3]&0x07;
if(rbuf[3]==0x0)
rbuf[3]=0x06;
else
rbuf[3]=rbuf[3]-1;
SetPCF8563(week,rbuf[3]);
}
else if(count==3)
{
rbuf[2]=rbuf[2]&0x3f;
gw=rbuf[2]&0x0f;
sw=(rbuf[2]>>4)&0x0f;
if(rbuf[2]==0x01) //判断个位和十位是否为1
{gw=1;
sw=3;
}
else if(gw==0x0)
{gw=9;
sw-=1;
}
else
gw-=1;
rbuf[2]=(sw<<4)+gw;
SetPCF8563(day,rbuf[2]);
}
else if(count==5)
{
rbuf[1]=rbuf[1]&0x3f;
if(rbuf[1]==0x10)
rbuf[1]=0x9;
else if(rbuf[1]==0x20)
rbuf[1]=0x19;
else if(rbuf[1]==0x0)
rbuf[1]=0x23;
else
rbuf[1]-=1;
SetPCF8563(hour,rbuf[1]);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -