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

📄 ds1302.c

📁 DS1302的驱动程序,基于AT91SAM7S64,已经过测试,可以对ds1302进行时间设置,时间读取
💻 C
字号:
// ******************************************************************************************
// 文件名称 :DS1302.C
// 模块名称 :实时时钟芯片DS1302设置及驱动函数
// author : steven
// time   :2009-1-9
// version:V0.0
//////////////////////////////////////////////////////////////////
#include	"DS1302.h"
#include	"PIOA.h"
RTC_STRUCT	RTCInfo;			// 实时时钟信息
RTC_STRUCT	rtcinfo;	
// 每月天数定义	   Null,    Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec
uchar const	RTC_Month[] = {Over, 0x31,  0x29, 0x31, 0x30, 0x31, 0x30,  0x31, 0x31, 0x30,  0x31, 0x30,  0x31};
uchar value;
uchar DS1302_temp[7];
// ================= ==   RTC 基本变量类型说用部分====================
//////////////////////////////////////////
//function name: uchar	RTC_check(RTC_STRUCT Dummy_RTC)
//author:steven
//time  :2009-1-9
//vesion:0.0
////////////////////////////////////////
uchar	RTC_Check(RTC_STRUCT Dummy_RTC)
{
	uchar	check_temp = Ok;
	// 年(含世纪位)合法性判断
	if  (Dummy_RTC.Date.Century != 0x20)
            check_temp = Error;
	// 月合法性判断
	if ( (Dummy_RTC.Date.Month == 0x00)|| (Dummy_RTC.Date.Month > 0x12) )
		check_temp = Error;
	// 日期合法性判断考虑闰年
	if ((Dummy_RTC.Date.Day == 0x00)|| (Dummy_RTC.Date.Day > (RTC_Month[BCD_To_Hex(Dummy_RTC.Date.Month)])))
		check_temp = Error;
	// 小时合法性判断
	if (Dummy_RTC.Time.Hour >= 0x24)
		check_temp = Error;
	// 分钟合法性判断
	if (Dummy_RTC.Time.Minute >= 0x60)
		check_temp = Error;
	// 秒合法性判断
	if  (Dummy_RTC.Time.Second >= 0x60) 
		check_temp = Error;
	return	(check_temp);
}
//////////////////////////////////////////
//function name: uchar	DS1302_modify(RTC_STRUCT Dummy_RTC)
//author:steven
//time  :2009-1-9
//vesion:0.0
////////////////////////////////////////
uchar	DS1302_modify(RTC_STRUCT Dummy_RTC)
{
 // 判断输入数据的合法性
  if (RTC_check(Dummy_RTC) != Ok)
      return	(Error);
  DS1302_write_bytes(DS1302_Control,0x00);//关闭写保护
   //写入年、月、日、周、时、分、秒(00)
    DS1302_write_bytes(DS1302_Year,Dummy_RTC.Date.Year);
     DS1302_write_bytes(DS1302_Week,Dummy_RTC.Date.week);
      DS1302_write_bytes(DS1302_Month,Dummy_RTC.Date.Month);
       DS1302_write_bytes(DS1302_Day,Dummy_RTC.Date.Day);
        DS1302_write_bytes(DS1302_Hour,Dummy_RTC.Time.Hour);//最高位为0,24小时模式
         DS1302_write_bytes(DS1302_Minute,Dummy_RTC.Time.Minute);
          DS1302_write_bytes(DS1302_Second,Dummy_RTC.Time.Second);//最高位为0,启动秒计数器
           //打开写保护
            DS1302_write_bytes(DS1302_Control,0x80); 
  return 0;
}
//////////////////////////////////////////
//function name: void DS1302_init(void)
//author:steven
//time  :2009-1-9
//vesion:0.0
////////////////////////////////////////
void DS1302_init(void)
{
 DS1302_write_bytes(DS1302_Control,0x00);//关闭写保护
  DS1302_write_bytes(DS1302_Second,0x80); //秒暂停
   DS1302_write_bytes(DS1302_Charger,0xa9);//浚流充电
   //写入年、月、日、周、时、分、秒(00)
    DS1302_write_bytes(DS1302_Year,0x09);
     DS1302_write_bytes(DS1302_Week,0x07);
      DS1302_write_bytes(DS1302_Month,0x01);
       DS1302_write_bytes(DS1302_Day,0x11);
        DS1302_write_bytes(DS1302_Hour,0x15);//最高位为0,24小时模式
         DS1302_write_bytes(DS1302_Minute,0x41);
          DS1302_write_bytes(DS1302_Second,0x00);//最高位为0,启动秒计数器
           //打开写保护
            DS1302_write_bytes(DS1302_Control,0x80); 

}
////////////////////////////////////////////////////////////////
//function name: uchar DS1302_write_bytes(uchar Addr,uchar value)
//author:steven
//time  :2009-1-9
//vesion:0.0
////////////////////////////////////////////////////////////////
uchar DS1302_write_bytes(uchar Addr,uchar value)
{
 uchar	I2C_Loop;
  //复位操作        
 AT91C_BASE_PIOA->PIO_CODR |=DS1302_RST;//将RST=0
  AT91C_BASE_PIOA->PIO_CODR |=DS1302_SCL;//将SCL=0
   AT91C_BASE_PIOA->PIO_SODR |=DS1302_RST;//将RST=1
    I2C_delay(40);
   // 按位发送地址数据
  for (I2C_Loop = 0; I2C_Loop < 8; I2C_Loop++)
  {
   if((Addr & 0x01) == 0x01)//查询最低位,端口为1置1,为0置0 
      AT91C_BASE_PIOA->PIO_SODR |=I2C_SDA;
    else 
      AT91C_BASE_PIOA->PIO_CODR |=I2C_SDA;
       I2C_delay(10); 
        AT91C_BASE_PIOA->PIO_SODR |=I2C_SCL;//将SCL = 1     __|``````|__
         AT91C_BASE_PIOA->PIO_CODR |=I2C_SCL;//将SCL = 0
          Addr=Addr>>1;//地址右移1位,要先发送低位
  }
  //在上升沿按位发送数据
  for(I2C_Loop = 0; I2C_Loop < 8; I2C_Loop++)
  {
   if((value & 0x01) == 0x01)
      AT91C_BASE_PIOA->PIO_SODR |=I2C_SDA;
      else 
        AT91C_BASE_PIOA->PIO_CODR |=I2C_SDA;
      I2C_delay(10);
         AT91C_BASE_PIOA->PIO_SODR |=I2C_SCL;//将SCL = 1     __|``````|__
          AT91C_BASE_PIOA->PIO_CODR |=I2C_SCL;//将SCL = 0
            value=value>>1;//地址左移1位
  }
  I2C_delay(100);
   AT91C_BASE_PIOA->PIO_SODR |=I2C_SCL;// SCL = High
    AT91C_BASE_PIOA->PIO_CODR |=DS1302_RST;//将RST=0
  return 0;
}
/////////////////////////////////////////////////////
//function name: uchar DS1302_read_bytes(uchar Addr)
//author:steven
//time  :2009-1-9
//vesion:0.0
/////////////////////////////////////////////////////
uchar DS1302_read_bytes(uchar Addr)
{
  uchar	I2C_Loop;
  uchar  value;
  //复位操作             
  AT91C_BASE_PIOA->PIO_CODR |=DS1302_RST;//将RST=0
   AT91C_BASE_PIOA->PIO_CODR |=DS1302_SCL;//将SCL=0
    I2C_delay(10);
     AT91C_BASE_PIOA->PIO_SODR |=DS1302_RST;//将RST=1
      I2C_delay(40);
  // 按位发送要读取的地址数据
  for (I2C_Loop = 0; I2C_Loop < 8; I2C_Loop++)
  {
   AT91C_BASE_PIOA->PIO_CODR |=I2C_SCL;//将SCL = 0
    if((Addr & 0x01) == 0x01)//查询最低位,端口为1置1,为0置0 
       AT91C_BASE_PIOA->PIO_SODR |=I2C_SDA;
     else 
      AT91C_BASE_PIOA->PIO_CODR |=I2C_SDA;
       I2C_delay(10);
        AT91C_BASE_PIOA->PIO_SODR |=I2C_SCL;//将SCL = 1 __|``````|__
         I2C_delay(10);
          Addr=Addr>>1;//地址左移1位
  }
  AT91C_BASE_PIOA->PIO_ODR|= I2C_SDA;//将I/O口改成输入口
  //在下降沿接收数据
  for(I2C_Loop = 0; I2C_Loop < 8; I2C_Loop++)
  {
   if(((AT91C_BASE_PIOA->PIO_PDSR) & I2C_SDA)==I2C_SDA)//读取引脚数据
      value |=0x80;//为1,置最高位为1
    else value &=0x7F;//为0,置最高位为0
     I2C_delay(10);
      AT91C_BASE_PIOA->PIO_SODR |=I2C_SCL;//将SCL = 1 
       I2C_delay(10);
        AT91C_BASE_PIOA->PIO_CODR |=I2C_SCL;//将SCL = 0,下降沿
         value=value>>1;//将数据右移一位
  }
  I2C_delay(100);
   AT91C_BASE_PIOA->PIO_OER|= I2C_SDA;//将I/O口改成输出口
    I2C_delay(10);
     AT91C_BASE_PIOA->PIO_CODR |=DS1302_RST;//将RST=0
      I2C_delay(10);
     return (value);  
}
////////////////////////////////////////////////////////////////////////////
//function name: RTC_STRUCT DS1302_read_bytes_continue(uchar Addr,uchar num)
//author:steven
//time  :2009-1-9
//vesion:0.0
////////////////////////////////////////////////////////////////////////////
RTC_STRUCT DS1302_read_bytes_continue(uchar Addr,uchar num)
{
  RTC_STRUCT	Dummy_RTC;
  uchar i;
  for(i=num;i>0;i--)
  {//读回来的是BCD码
    DS1302_temp[7-i]=DS1302_read_bytes(Addr);
      Addr=Addr+2;
  }
  Dummy_RTC.Time.Second = DS1302_temp[0];	// 读" 秒"
   Dummy_RTC.Time.Minute = DS1302_temp[1];	// 读" 分钟"
    Dummy_RTC.Time.Hour = DS1302_temp[2];	// 读" 小时"
     Dummy_RTC.Date.Day =  DS1302_temp[3];	// 读" 日期"
      Dummy_RTC.Date.Month = DS1302_temp[4];	// 读" 月份"
       Dummy_RTC.Date.week = DS1302_temp[5];    // 读“星期”
        Dummy_RTC.Date.Year = DS1302_temp[6];	// 读" 年份"
         Dummy_RTC.Date.Century = 0x20;	
 return(Dummy_RTC); 
}

/////////////////////end/////////////////////////////



⌨️ 快捷键说明

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