⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcf8563t.c

📁 这个是我自己在别人的基础上修改的PCF8563的程序
💻 C
字号:
/*
***********************************************************
 HFUT-TI DSP 实验室
 hfut-crazy
 QQ:251759752
***********************************************************
*/

#include"includes.h"

extern INT8U TIMER_8563[10];
INT8U old_minute,new_minute;


/*
*********************************************** 
 *** This routine will send the I2C Start Bit ***
SCL:
 ---|
SDA:
---|
***********************************************
*/
void I2C_Start (void)         //I2C发送开始位
{
 DDRE |=((1<<PE4)|(1<<PE5)); //将PA0数据端口(SDA),PA1时钟端口(SCL)设为输出
 Delay_Us(0);
 DATE_CLK_set;               //将时钟端口(SCL)设为高 
 Delay_Us(DELAYCNT);
 
 DATE_DT_set;               //将时钟端口(SCL)设为高
 Delay_Us(DELAYCNT);
 
 DATE_DT_clr;                //将数据端口(SDA)设为高
 Delay_Us(DELAYCNT);  
 
 DATE_CLK_clr;                //将数据端口(SDA)设为高
 Delay_Us(DELAYCNT);
}

/*
*********************************************** 
 *** This routine will send the I2C Stop Bit ***
SCL:
 _|--
SDA:
|____|-
***********************************************
*/
void I2C_Stop (void)          //I2C发送停止位
{
 DDRE|=((1<<PE4)|(1<<PE5));    //将PA0数据端口(SDA),PA1时钟端口(SCL)设为输出
 Delay_Us(0);
 
 DATE_DT_clr;                 //将数据端口(SDA)设为低
 Delay_Us(DELAYCNT);
 
 DATE_CLK_set;
 Delay_Us(DELAYCNT);

 DATE_DT_set;                 //将数据端口(SDA)设为高
 Delay_Us(DELAYCNT);
}

/********************************************
内部函数,输出ACK ,每个字节传输完成,输出ack=0,结束读书据,ack=1;
********************************************/
INT8U WriteACK(void)
{
   INT8U ACK;
   DDRE|=((1<<PE4)|(1<<PE5));
   Delay_Us(0);
   
   DATE_DT_set;
   Delay_Us(DELAYCNT);
   
   DATE_CLK_set;
   Delay_Us(DELAYCNT);
   
   DDRE&=~(1<<PE5);
   Delay_Us(0);
   
   if(PINE&0x20)ACK = 1;
   else ACK = 0;
   
   DATE_CLK_clr;
   Delay_Us(DELAYCNT);
   return (ACK); 

}

// *********************************************************************** //
// *** 发送完毕检查校验位,有校验位返回1,无返回0 *** //
// *********************************************************************** //

unsigned char I2C_Ackn(void)
{
 unsigned char errtime=255;
 DDRE|=(1<<PE4);
 DDRE&=~(1<<PE5);               // 设置数据口(SDA)为输入 
 Delay_Us(0); 
 
 DATE_CLK_clr; 
 asm("nop");
 
 DATE_CLK_set;                 //将数据端口(SDA)设为高
 Delay_Us(DELAYCNT); 
 
 while(PINE&0x20)
 {
    errtime--;
    if (!errtime)      //errtime=0,没接收到
    {
      I2C_Stop();
      return 0x00;
    }
  } 
 DATE_CLK_clr;                // 将时钟端口(SCL)设为低
 Delay_Us(DELAYCNT);
 return 0x01;      //true 
}

// ******************************************************** //
// *** This routine will write a byte to the I2C device *** //
// ******************************************************** //

void Write_I2C_Byte(unsigned char byte)     //写一个字节到I2C设备
{
 unsigned char i;
 DDRE|=((1<<PE5)|(1<<PE4)); 
 Delay_Us(0);   
 
 for (i = 0; i < 8; i++)          //传送8位数据
     {    
  DATE_CLK_clr;                   //将时钟端口(SCL)设为低   
  Delay_Us(DELAYCNT);
  
  if((byte & 0x80)) DATE_DT_set;      // 设置 SDA 位
  else DATE_DT_clr;        // 清除 SDA 位
  Delay_Us(DELAYCNT);
  
  DATE_CLK_set;                   //将时钟端口(SCL)设为高
  Delay_Us(DELAYCNT);
  byte = byte << 1;  
 }
 DATE_CLK_clr;
 Delay_Us(DELAYCNT);
 I2C_Ackn();
 Delay_Us(DELAYCNT*10);
 return;

}

// ********************************************************* //
// *** This routine will read a byte from the I2C device *** //
// ********************************************************* //

unsigned char Read_I2C_Byte(void)   //读取I2C设备的数据
{ 
 unsigned char i,buff = 0;
 //Delay_Us(2);
 DDRE|=(1<<PE4);                   //PA1为时钟,输出
 DDRE&=~(1<<PE5);    
 Delay_Us(0);    
 
 for (i = 0; i < 8; i++)
    {
  DATE_CLK_clr;                 //将时钟端口(SCL)设为高
  Delay_Us(DELAYCNT);
  
  DATE_CLK_set;                 //将时钟端口(SCL)设为高
  Delay_Us(DELAYCNT);
  buff = (buff << 1);
  if ( PINE& 0x20 )buff|=0x01;
  

   }  
 DDRE|=((1<<PE5)|(1<<PE4));//读完毕过后应答一个高电平
 Delay_Us(0);
 DATE_CLK_clr;
 Delay_Us(DELAYCNT*2);
 DATE_DT_set;
 Delay_Us(DELAYCNT);
 DATE_CLK_set;                     //将时钟端口(SCL)设为高 
 //DATE_DT_clr;  
 Delay_Us(DELAYCNT*10);     
 return buff;          // 返回读取值
 
 /*
 unsigned char a;
unsigned char b=0;
for(a=0;a<8;a++)
{
SCL = 1;
b=b<<1;
if (SDA==1)
b=b|0x01; //按位或
SCL = 0;
}
return (b);
 */
}

//读8563寄存器
unsigned char rtc_read(INT8U devRaddr,INT8U devWaddr,unsigned char address)
{
unsigned char d;
I2C_Start();
Write_I2C_Byte(devWaddr);
Write_I2C_Byte(address);
I2C_Start();
Write_I2C_Byte(devRaddr);
d=Read_I2C_Byte();
//d>>=1;
I2C_Stop();
Delay_Us(DELAYCNT*150);
return d;
}

////////////////////////////////////////////////////////////////////////////////
//写8563寄存器
void rtc_write(unsigned char devaddr,unsigned char address,unsigned char data)
{
I2C_Start();
Write_I2C_Byte(devaddr);
Write_I2C_Byte(address);
Write_I2C_Byte(data);
I2C_Stop();
Delay_Us(DELAYCNT*150);
return;
}

////////////////////////////////////////////////////////////////////////////////

void rtc_start(void)
{
rtc_write(PCF8563WADDR,0,0);
}

////////////////////////////////////////////////////////////////////////////////

void rtc_stop(void)
{
rtc_write(PCF8563WADDR,0,0x20);
}

void GetPCF8563(unsigned char *TIMER_8563)
{
  CLI();
  * TIMER_8563   =(rtc_read(PCF8563RADDR,PCF8563WADDR,2)&0x7f);       //寄存器0x02为秒寄存器
  *(TIMER_8563+1)=(rtc_read(PCF8563RADDR,PCF8563WADDR,3)&0x7f);       //寄存器0x03为分寄存器
  *(TIMER_8563+2)=(rtc_read(PCF8563RADDR,PCF8563WADDR,4)&0x3f);       //寄存器0x04为时寄存器
  *(TIMER_8563+3)=(rtc_read(PCF8563RADDR,PCF8563WADDR,5)&0x3f);       //寄存器0x05为天寄存器
  *(TIMER_8563+4)=(rtc_read(PCF8563RADDR,PCF8563WADDR,7)&0x1f);       //寄存器0x07为月寄存器
  *(TIMER_8563+5)=(rtc_read(PCF8563RADDR,PCF8563WADDR,8));            //寄存器0x08为年寄存器
  SEI();
//  return TIMER_8563;
}

unsigned char get_second(void)      //获得当前秒数
{
  unsigned i,j;
  i=(rtc_read(PCF8563RADDR,PCF8563WADDR,2)&0x7f);         //寄存器0x02为秒寄存器
  j=(i&0x0f)+(i>>4)*10;
  return j;
}

////////////////////////////////////////////////////////////////////////////////
void SetPCF8563(unsigned char adds,unsigned char data)
{
 CLI();
 rtc_stop();
 rtc_write(PCF8563WADDR,adds,data);
 rtc_start();
 SEI();
}

//设置时间  (**年/**月/**日  **时:**分)
void set8563(void)
{
  SetPCF8563(8,0x08);     //设置年
  SetPCF8563(7,0x07);     //设置月
  SetPCF8563(5,0x06);     //设置日
  SetPCF8563(4,0x06);     //设置时
  SetPCF8563(3,0x06);     //设置分
  
  rtc_write(PCF8563WADDR,0x0d,0xf2);
  rtc_write(PCF8563WADDR,0x00,0x00);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -