#include
#include
#include
#include "pcf8563.h"
#include "lcd.h"
#include "keyboard.h"
//时钟芯片数据接口PA0
#define DATE_DT_set asm("sbi 0x1B,0")
#define DATE_DT_clr asm("cbi 0x1B,0")
//时钟芯片时钟接口PA1
#define DATE_CLK_set asm("sbi 0x1B,1")
#define DATE_CLK_clr asm("cbi 0x1B,1")
unsigned char old_minute,new_minute;
unsigned char number1[13]=
{
0x30, //0
0x31, //1
0x32, //2
0x33, //3
0x34, //4
0x35, //5
0x36, //6
0x37, //7
0x38, //8
0x39, //9
0x20, //空格
0x2E, //.
0x3A //:
};
void delayus(unsigned char i)
{
while(i)
i--;
}
// ************************************************ //
// *** This routine will send the I2C Start Bit *** //
// ************************************************ //
void I2C_Start (void) //I2C发送开始位
{
DDRA|=0x03; //将PA0数据端口(SDA),PA1时钟端口(SCL)设为输出
DATE_CLK_set; //将时钟端口(SCL)设为高
DATE_DT_set; //将数据端口(SDA)设为高
delayus(2);
DATE_DT_clr; //将数据端口(SDA)设为低
delayus(2);
DATE_DT_set;
}
// *********************************************** //
// *** This routine will send the I2C Stop Bit *** //
// *********************************************** //
void I2C_Stop (void) //I2C发送停止位
{
DDRA|=0x03; //将PA0数据端口(SDA),PA1时钟端口(SCL)设为输出
DATE_DT_clr; //将数据端口(SDA)设为低
DATE_CLK_set; //将时钟端口(SCL)设为高
delayus(2);
DATE_DT_set; //将数据端口(SDA)设为高
delayus(2);
}
// *********************************************************************** //
// *** 发送完毕检查校验位,有校验位返回1,无返回0 *** //
// *********************************************************************** //
unsigned char I2C_Ackn(void)
{
unsigned char errtime=255;
//DATE_CLK_clr; // 将时钟端口(SCL)设为低
DDRA|=0x02;
DDRA&=0xFE; // 设置数据口(SDA)为输入
delayus(2);
while(PINA&0x01)
{
errtime--;
if (!errtime) //errtime=0,没接收到
{
I2C_Stop();
return 0x00;
}
}
DATE_CLK_set;
delayus(2);
DATE_CLK_clr; // 将时钟端口(SCL)设为低
delayus(2);
return 0x01; //true
}
// ******************************************************** //
// *** This routine will write a byte to the I2C device *** //
// ******************************************************** //
void Write_I2C_Byte(unsigned char byte) //写一个字节到I2C设备
{
unsigned char i;
DDRA|=0x03; //将PA0数据端口(SDA)设为输出
for (i = 0; i < 8; i++) //传送8位数据
{
DATE_CLK_clr; //将时钟端口(SCL)设为低
if((byte & 0x80)) DATE_DT_set; // 设置 SDA 位
else DATE_DT_clr; // 清除 SDA 位
delayus(2);
DATE_CLK_set; //将时钟端口(SCL)设为高
asm("nop");
byte = byte << 1; //将输出数据左移一位
}
DATE_CLK_clr; // 校验标志位 (每传送8位,有一校验位)
if (I2C_Ackn()==0) // Check for acknowledge from I2C device
yonghudenglu();
//DATE_CLK_clr;
}
// ********************************************************* //
// *** This routine will read a byte from the I2C device *** //
// ********************************************************* //
unsigned char Read_I2C_Byte(void) //读取I2C设备的数据
{
unsigned char i,buff = 0;
delayus(2);
DDRA|=0x02; //PA1为时钟,输出
DDRA&=0xfe; //设置数据口(SDA)为输入
for (i = 0; i < 8; i++)
{
DATE_CLK_clr; // 将时钟端口(SCL)设为低
delayus(2);
DATE_CLK_set; //将时钟端口(SCL)设为高
delayus(2);
// 在 SDA 位上读取数据
if ( PINA&=0x01 )
buff++;
buff = (buff << 1);
delayus(2);
}
DDRA|=0x03; //设为输出,发送校验位
DATE_DT_clr;
delayus(2);
DATE_CLK_set;
delayus(2);
DATE_CLK_clr; //将时钟端口(SCL)设为高
//DATE_DT_clr;
return buff; // 返回读取值
}
//读8563寄存器
unsigned char rtc_read(unsigned char address)
{
unsigned char d;
I2C_Start();
Write_I2C_Byte(0xa2);
Write_I2C_Byte(address);
I2C_Start();
Write_I2C_Byte(0xa3);
d=Read_I2C_Byte();
d=d>>1;
I2C_Stop();
//for(;;){}
return d;
}
////////////////////////////////////////////////////////////////////////////////
//写8563寄存器
void rtc_write(unsigned char address,unsigned char data1)
{
I2C_Start();
Write_I2C_Byte(0xa2);
Write_I2C_Byte(address);
Write_I2C_Byte(data1);
I2C_Stop();
}
////////////////////////////////////////////////////////////////////////////////
void rtc_start(void)
{
rtc_write(0,0);
}
////////////////////////////////////////////////////////////////////////////////
void rtc_stop(void)
{
rtc_write(0,0x20);
}
void GetPCF8563(unsigned char *time)
{
CLI();
*time=(rtc_read(2)&0x7f); //寄存器0x02为秒寄存器
*(time+1)=(rtc_read(3)&0x7f); //寄存器0x03为分寄存器
*(time+2)=(rtc_read(4)&0x3f); //寄存器0x04为时寄存器
*(time+3)=(rtc_read(5)&0x3f); //寄存器0x05为天寄存器
*(time+4)=(rtc_read(7)&0x1f); //寄存器0x07为月寄存器
*(time+5)=(rtc_read(8)); //寄存器0x08为年寄存器
SEI();
}
unsigned char get_second(void) //获得当前秒数
{
unsigned i,j;
i=(rtc_read(2)&0x7f); //寄存器0x02为秒寄存器
j=(i&0x0f)+(i>>4)*10;
return j;
}
////////////////////////////////////////////////////////////////////////////////
void SetPCF8563(unsigned char adds,unsigned char data)
{
CLI();
rtc_stop();
rtc_write(adds,data);
rtc_start();
SEI();
}
//设置时间 (**年/**月/**日 **时:**分)
void set8563(void)
{
unsigned char maini=0,mainj=0,numb[12],newkey;
unsigned char sign=0;
unsigned char *time;
unsigned char displayn[12];
time=numb;
while((mainj<10)||(sign==0))
{
if(kbscan()!=0x20)
{
maini=kbscan();
while(kbscan()==maini)
asm("nop");
if(maini<10)
{
numb[mainj]=maini;
displayn[mainj]=number1[maini];
mainj++;
}
else if(maini==12)
{
if(mainj>0)
mainj--;
numb[mainj]=number1[10];
displayn[mainj]=number1[10];
}
else if((mainj>=10)&&(maini==13))
{
sign=1;
}
display(0x80,displayn[0],displayn[1]);
display(0x81,0x2f,displayn[2]);
display(0x82,displayn[3],0x2f);
display(0x83,displayn[4],displayn[5]);
display(0x84,0x20,0x20);
display(0x85,displayn[6],displayn[7]);
display(0x86,0x3a,displayn[8]);
display(0x87,displayn[9],0x20);
}
}
numb[0]=(numb[0]<<4)+(numb[1]&0x0F); //年
numb[2]=(numb[2]<<4)+(numb[3]&0x0F); //月
numb[4]=(numb[4]<<4)+(numb[5]&0x0F); //日
numb[6]=(numb[6]<<4)+(numb[7]&0x0F); //时
numb[8]=(numb[8]<<4)+(numb[9]&0x0F); //分
SetPCF8563(8,numb[0]); //设置年
SetPCF8563(7,numb[2]); //设置月
SetPCF8563(5,numb[4]); //设置日
SetPCF8563(4,numb[6]); //设置时
SetPCF8563(3,numb[8]); //设置分
}
//显示时间函数,屏幕第一行显示
void displaytime(unsigned char *time)
{
GetPCF8563(time);
new_minute=*(time+1);
if(new_minute!=old_minute)
{
display(0x80,0x30+(*(time+5)>>4),0x30+(*(time+5)&0x0F));
display(0x81,0x2f,0x30+(*(time+4)>>4));
display(0x82,0x30+(*(time+4)&0x0F),0x2f);
display(0x83,0x30+(*(time+3)>>4),0x30+(*(time+3)&0x0F));
display(0x84,0x20,0x20);
display(0x85,0x30+(*(time+2)>>4),0x30+(*(time+2)&0x0F));
display(0x86,0x3a,0x30+(*(time+1)>>4));
display(0x87,0x30+(*(time+1)&0x0F),0x20);
old_minute=new_minute;
}
//display(0x98,0x30+(*time>>4),0x30+(*time&0x0F));
}
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』