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

📄 ds1302.txt

📁 时钟芯片将给显示时间
💻 TXT
字号:
#include <iom16v.h>			//包含型号头文件
#include <macros.h>			//包含"位"操作头文件
#define uchar unsigned char
#define uint unsigned int

#define TRUE 1
#define FALSE 0
#include "xianshi.c"			//包含数码管函数

/******************RTC常量******************/
#define RTC_CLK   	PC7
#define RTC_DATA  	PC6
#define RTC_CS    	PC1
	//命令
#define RD	  	0x01
#define WR	  	0x00
#define C_SEC		0x80	//秒
#define C_MIN		0x82	//分
#define C_HR		0x84	//时
#define C_DAY		0x86	//日
#define C_MTH		0x88	//月
#define C_WK		0x8A	//星期 DATE
#define C_YR		0x8C	//年
#define C_WP		0x8E	//控制(写保护)
#define C_CHARGE	0x90	//涓流充电
#define C_BURST		0xBE	//时钟多字节
	//配置
#define CLK_HALT		0x80	//停止时钟控制位    SECOND	bit7
#define CLK_START		0x00	//启动时钟
#define M12_24			0x80	//12/24小时值选择位 HOUR		bit7 
#define PROTECT			0x80	//写保护控制位      CONTROL	bit7 
#define UPROTECT		0x00	//写保护控制位      CONTROL	bit7 
	//涓流充电控制常量
#define TC_D1R2			0xA5	//high 1 Diode +2K Resistors  
#define TC_D2R8			0xAB	//low  2 Diodes+8K Resistors  
#define TC_DISABLED		0x00	//Disabled(TCS<>1010 or DS=00 or RS=00)
	//RAM 命令
#define C_RAMBASE		0xC0	//RAM0~RAM30<<1 地址需左移一位 

void Delayus(uint US)		  
{
 uint i;
 US=US*5/4;		  	 //5/4是在8MHz晶振下,通过软件仿真反复实验得到的数值
 for( i=0;i<US;i++); 
}
void Delayms(uint MS)		  
{
 uint i,j;
 for( i=0;i<MS;i++)
 for(j=0;j<1141;j++);	//1141是在8MHz晶振下,通过软件仿真反复实验得到的数值
}



/*******************************************
函数名称: DS1302_init
功    能: 初始化DS1302的数据接口
参    数: 无
返回值  : 无
/********************************************/
void DS1302_portinit(void)		  
{
 DDRB|=BIT(RTC_CLK)|BIT(RTC_DATA)|BIT(RTC_CS);//将时钟端(RTC_CLK)数据端(RTC_DATA)片选端(RTC_CS)设置为输出
}
/*******************************************
函数名称: DS1302_writeB
功    能: 向DS1302写入一个字节数据(没有RST操作)
参    数: byte--要写入的数据
返回值  : 无
/********************************************/
void DS1302_writeB(uchar byte)
{
 uchar i;
 for(i=0;i<8;i++)		 	  //8位数据计数
 {
  PORTB&=~BIT(RTC_CLK);		  //拉低时钟端
  if(byte&0x01)				  //当前位是否是1
  {
   PORTB|=BIT(RTC_DATA);	  //当前位是1,拉高数据端
  }
  else						  
  {
   PORTB&=~BIT(RTC_DATA);	  //当前位是0,拉低数据端
  }  
  Delayus(10);				  //调整时钟和脉冲宽度
  PORTB|=BIT(RTC_CLK);		  //时钟上升沿(DS1302采样数据)
  byte>>=1;					  //数据右移1位,为送出新数据位做准备
 }
}
/*******************************************
函数名称: DS1302_readB
功    能: 从DS1302读出一个字节数据(没有RST操作)
参    数: 无
返回值  : byte--读出的数据
/********************************************/
uchar DS1302_readB(void)
{
 uchar i,byte=0;
 DDRB&=~BIT(RTC_DATA);		 //将数据端口设置为输入		  
 PORTB&=~BIT(RTC_DATA);		 //无上拉电阻
 for(i=0;i<8;i++)			 //8位数据计数
 {
  byte>>=1;  				 //保存读入的数据位
  PORTB|=BIT(RTC_CLK);		 //时钟上升沿
  Delayus(10);				 //延时,调整时钟脉冲宽度
  PORTB&=~BIT(RTC_CLK);		 //时钟下降沿,DS1302输出数据位
  Delayus(10);				 //等待数据变化(MEGA16太快,必须等待DS1302的数据位输出,否则不能正确读出)
  if(PINB&BIT(RTC_DATA))	 //当前位是否是高电平
  {
   byte|=BIT(PC7);			 //是高电平就将返回数据的当前位置1
  }
  else
  {
   byte&=~BIT(PC7);			 //是低电平就将返回数据的当前位置0
  }
 }
 DDRB|=BIT(RTC_DATA);		 //最后将数据端口设置为输出
 return byte;				 //返回读出的数据
}
/*******************************************
函数名称: DS1302_writeD
功    能: 向DS1302的某个地址写入一个字节数据
参    数: addr--地址值(寄存器或RAM)
	  	  data--要写入的地址
返回值  : 无
/********************************************/
void DS1302_writeD(uchar addr,uchar data)
{
 PORTC&=~BIT(RTC_CS);	 //拉低片选端
 PORTB&=~BIT(RTC_CLK);	 //拉低时钟端
 Delayus(10);
 PORTC|=BIT(RTC_CS);	 //拉高片选端
 Delayus(10); 			 //调整片选脉冲
 DS1302_writeB(addr);	 //写入操作命令(地址)
 Delayus(10);
 PORTB&=~BIT(RTC_CLK);	 //拉低时钟端
 Delayus(10);
 DS1302_writeB(data);	 //写入数据
 PORTB&=~BIT(RTC_CLK);	 //拉低时钟端
 Delayus(10);			 //调整片选脉冲
 PORTC&=~BIT(RTC_CS);	 //拉低片选端
}
/*******************************************
函数名称: DS1302_readD
功    能: 从DS1302的某个地址读出一个字节数据
参    数: addr--地址值(寄存器或RAM)
返回值  : data--读出的数据
/********************************************/
uchar DS1302_readD(uchar addr)
{
 uchar data;
 PORTC&=~BIT(RTC_CS);	 //拉低片选端
 PORTB&=~BIT(RTC_CLK);	 //拉低时钟端
 Delayus(10);
 PORTC|=BIT(RTC_CS);	 //拉高片选端
 Delayus(10); 			 //调整片选脉冲
 DS1302_writeB(addr);	 //写入操作命令(地址)
 Delayus(10);
 data=DS1302_readB();	 //读出数据
 Delayus(10);
 PORTB&=~BIT(RTC_CLK);	 //拉低时钟端
 PORTC&=~BIT(RTC_CS); 	 //拉低片选端
 return data;			 //返回读出的数据
}
/*******************************************
函数名称: DS1302_setT
功    能: 设置DS1302的时间
参    数: ptTimeD--设置时间数组指针
返回值  : 无
/********************************************/
void DS1302_setT(uchar ptTimeD[])
{
    uchar i;
    uchar addr = 0x80; 			 	  //写入地址从秒寄存器开始
    DS1302_writeD(C_WP|WR,UPROTECT); //控制命令,WP位为0,允许写操作
	Delayms(5);
    for(i=0;i<7;i++)
    {
        DS1302_writeD(addr|WR,ptTimeD[i]);   // 秒 分 时 日 月 星期 年         
        addr+=2;
		Delayms(1);
    }
    DS1302_writeD(C_WP|WR,PROTECT); 		//控制命令,WP位为1,不允许写操作
}
/*******************************************
函数名称: DS1302_getT
功    能: 读取DS1302的当前时间
参    数: time[]--读取的时间数组
返回值  : 无
/********************************************/
void DS1302_getT(uchar time[])
{
    uchar i;
////////下面的是单次读写//////////////////////////	
   /* uchar addr = 0x80; 			 	  		  //读取地址从秒寄存器开始 
    for(i=0;i<7;i++)
    {
        time[i]=DS1302_readD(addr|RD);    // 秒 分 时 日 月 星期 年        
        addr+=2;
    }*/
////////////////////////////////////////////////////	
	/////////下面是多字节读取/////////////// 
	 PORTC&=~BIT(RTC_CS);	 //拉低片选端
     Delayus(10);
     PORTC|=BIT(RTC_CS);	 //拉高片选端
     Delayus(10); 			 //调整片选脉冲
	 DS1302_writeB(0xbf);       // 0xbf:时钟多字节读取命令 
     for (i=0;i<8;i++)       //时间数据的存放格式是:
       {                        //秒,分,时,日,月,星期,年,控制
         time[i]=DS1302_readB(); //【7个数据(BCD格式)+1个控制】 
       }
				
     PORTC&=~BIT(RTC_CS); 	 //拉低片选端
 ///////////////////////////////////////////////
     PORTB&=~BIT(RTC_CLK);	 				  //拉低时钟端(时钟端在不操作时为低)
}
/*******************************************
函数名称: DS1302_check
功    能: 检测DS1302是否正常工作
参    数: 无
返回值  : exist--为TRUE为检测到DS1302,为FALSE为没检测到
/********************************************/
uchar DS1302_check(void)
{
	uchar exist;
    DS1302_writeD(C_WP|WR,UPROTECT);		  //写入写允许命令
    DS1302_writeD(C_RAMBASE|WR,0xA5);		  //RAM0写入0xA5
    exist=DS1302_readD(C_RAMBASE|RD);		  //读取RAM0
    if(exist==0xA5)	
	{
	 exist=TRUE;							  //如果读取值与写入值相等,返回TRUE
	}
    else 	
	{
	 exist=FALSE;							  //如果读取值与写入值不相等,返回FALSE
	}	
	return exist;
}
/*******************************************
函数名称: DS1302_init
功    能: 初始化DS1302
参    数: 无
返回值  : 无
/********************************************/
void DS1302_init(void)
{
 DS1302_writeD(C_WP|WR,UPROTECT);		  //写入写允许命令
 DS1302_writeD(C_SEC|WR,CLK_START);		//启动振荡器,DS1302开始工作
 DS1302_writeD(C_WP|WR,PROTECT); 		//控制命令,WP位为1,不允许写操作	  
}

/*********************************
函数名称:Disp_time
功能:在数码管上显示分钟和秒
参数:gettime
/**********************************
void Disp_time(gettime)
{ uint dm[4],i;
  a=gettime[0];
  b=gettime[1];
  while(1)
   { for(i=0;i<2;i++)
      { dm[4-i]=a%10;
         a=a/10;
       }
     for(i=2;i<4;i++)
      { dm[4-i]=b%10;
        b=b/10;
       }
    for(i=0;i<4;i++)
      { show(dm[i],i+2);
        delay(2);
       }
    }
  
  
}
/*******************************************
函数名称: main
功    能: 1. 在1602液晶上显示当前时间 2.可以设置时间(M1-M9为数字0-9,M13为设置模式和显示模式选择,M14为当前设置位选择)
参    数: 无
返回值  : 无
/********************************************/
void main(void)
{
 	
	
	uchar setadd,setdat,shift;	  //setadd指定将当前数值送入DS1302的哪个寄存器
 	   						  //setdat是当前设置的数值,即被送入DS1302指定寄存器的数
							  //shift来实现十位和各位的设置相互独立(因为十位和个位是在一个寄存器里的)
 uchar dis_x,dis_y;			  //存储1602液晶当前光标的位置
 uchar settime[7]={0x50,0x59,0x23,0x01,0x01,0x06,0x07};//设置的秒,分,时,日,月,星期,年
 uchar gettime[7]={0x00,0x00,0x00,0x00,0x00,0x00,0x00};//保存当前时间的数组
 LCD1602_initial(); 		//初始化1602液晶
 DS1302_portinit();			//初始化DS1302的三根数据线
 DS1302_init();				//启动振荡器,DS1302开始工作 
 DS1302_setT(settime);		//设置初始时间
 while(1)					//以下程序完成显示和设置时间
 {
   DS1302_getT(gettime);	//获得当前时间
   
   Disp_time(gettime);		//显示当前时间
 }
}

⌨️ 快捷键说明

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