毕业设计之时钟模块设计DS1302

该模块使用的芯片是:DS1302芯片,DS1302芯片是一个自动计时的时钟模块,有6个时钟寄存器,秒,分,时,日,月,年(其实不止,其它的暂且不管了)
使用不同的命令字来控制相应的寄存器:
0x80 ~ 0x8c ,分别控制秒到年寄存器的读和写
0x80
上表中,如果想读当前是多少秒,直接将0x81给read_DS1302()函数作为参数,该函数返回值对应的就是当前的秒
unsigned int current_second = read_DS1302(0x81);current_second 就是返回的秒

DS1302和单片机通过I/0口进行连接:
具体实现两种通信:
单片机通过发送指令,让时钟寄存器获得初始化时间
单片机从DS1302芯片获取时钟信息

DS1302封装图:
在这里插入图片描述
下面介绍从DS1302读取时钟的过程:
首先请看时序图:
RST作为片选![在这里插入图片描述](https://img-blog.csdnimg.cn/20200418194710656.png

/*
	dat是需要读入命令字,函数返回该命令字要求返回的寄存器的数据
*/
u8 Read_DS1302(u8 dat) // 
{
	u8 i,temp,dat1,dat2;

	DS1302_CE   = 0;
	DS1302_SCLK = 0;
	DS1302_CE   = 1;

	for(i = 8;i>0;i--)	 //用8个上升沿把dat中的8位bit送到IO种选择读取的地址
	{
		DS1302_SCLK = 0; 
		temp  =  dat;
		DS1302_IO   =  (bit)(temp&0x01);// temp的最右边一位送到IO上
		dat >>=1;  //dat右移一位 
		DS1302_SCLK   = 1; //上升沿触发
	}

	for(i =8 ;i>0 ; i--)	   //采用先接收IO口数据,再用下降沿触发,循环结束后ACC获得读取数据
	{
		ACC_7   =   DS1302_IO;	//从最高位接收
		DS1302_SCLK  =  1;
		ACC >>= 1; //ACC为累加器
		DS1302_SCLK  =  0;
	}
	DS1302_SCLK  = 1;
	DS1302_CE    =  0;
	dat1 = ACC;
	dat2 = dat1 /16;
	dat1 = dat1 %16;
	dat1 = dat1+dat2*10;
	 
	return (dat1);
}

往DS1302写数据:
写时序如图:(RST = CE)
在这里插入图片描述

/*
addr写入命令字,dat根据写入的命令字把dat数据放入相应的寄存器
*/
void Write_DS1302(u8 addr,u8 dat)
{
	u8 i,temp;
	DS1302_CE   = 0;
	DS1302_SCLK = 0;
	
	DS1302_CE   = 1;
	for(i=8 ; i>0 ; i--)
	{
		DS1302_SCLK = 0;
		temp = addr;
		DS1302_IO = (bit)(temp&0x01);
		addr >>= 1;
		DS1302_SCLK = 1;
	}
	for(i=8;i>0;i--)
	{
		DS1302_SCLK = 0;
		temp  = dat;
		DS1302_IO = (bit)(temp&0x01);
		dat >>= 1;
		DS1302_SCLK = 1;
	}
	DS1302_SCLK = 1;	
	DS1302_CE   = 0;
}

下面是使用DS1302已经封装完成的头文件:
DS1302.h

#ifndef    _DS1302_H_
#define	   _DS1302_H_
#include   <reg52.h>

sbit DS1302_SCLK = P1^4;
sbit DS1302_IO   = P1^5;
sbit DS1302_CE   = P1^6;

#define WRITE_SECOND  0x80	   、
#define WRITE_MINUTE  0X82		
#define WRITE_HOUR    0X84		
#define WRITE_DATE    0X86	    
#define WRITE_MONTH   0X88	    
#define WRITE_WEEK    0X8A  	 
#define WRITE_YEAR    0X8C		 

#define  READ_SECOND  0X81		 //读秒
#define  READ_MINUTE  0X83		 //读分
#define  READ_HOUR    0X85		 //读时
#define  READ_DATE    0X87		 //读日
#define  READ_MONTH   0X89		 // 读月
#define  READ_WEEK    0X8B		 //	读星期
#define  READ_YEAR    0x8D		 //  读年

#define WRITE_PROTECT           0x8E

sbit     ACC_7 = ACC^7;

u8 Read_DS1302(u8 dat);
void Write_DS1302(u8 addr,u8 dat);
u8 data time[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00};//秒,分,时,日,月、星期、年

u8 Read_DS1302(u8 dat)
{
	u8 i,temp,dat1,dat2;

	DS1302_CE   = 0;
	DS1302_SCLK = 0;
	DS1302_CE   = 1;

	for(i = 8;i>0;i--)	 //写入需要读入数据对应的地址	采用先接受IO口数据,再用
	{
		DS1302_SCLK = 0;
		temp  =  dat;
		DS1302_IO   =  (bit)(temp&0x01);
		dat >>=1;
		DS1302_SCLK   = 1;
	}

	for(i =8 ;i>0 ; i--)	   //采用先接收IO口数据,再用下降沿触发
	{
		ACC_7   =   DS1302_IO;	
		DS1302_SCLK  =  1;
		ACC >>= 1;
		DS1302_SCLK  =  0;
	}
	DS1302_SCLK  = 1;
	DS1302_CE    =  0;
	dat1 = ACC;
	dat2 = dat1 /16;
	dat1 = dat1 %16;
	dat1 = dat1+dat2*10;
	 
	return (dat1);
}

void Write_DS1302(u8 addr,u8 dat)
{
	u8 i,temp;
	DS1302_CE   = 0;
	DS1302_SCLK = 0;
	DS1302_CE   = 1;
	for(i=8 ; i>0 ; i--) //这个循环用于向DS1302写入addr命令字
	{
		DS1302_SCLK = 0;
		temp = addr;
		DS1302_IO = (bit)(temp&0x01);
		addr >>= 1;
		DS1302_SCLK = 1;
	}
	for(i=8;i>0;i--)//这个循环用于向DS1302对应的命令字中写dat
	{
		DS1302_SCLK = 0;
		temp  = dat;
		DS1302_IO = (bit)(temp&0x01);
		dat >>= 1;
		DS1302_SCLK = 1;
	}
	DS1302_SCLK = 1;	
	DS1302_CE   = 0;
}
  void DS1302_init()	
//给DS1302初始化,其中0x46是当时做闭塞是当时做毕设的时间,DS1302内部接收的是16进制,所	  	//以直接输入16进制就好了,	 
 { 
	Write_DS1302(WRITE_MINUTE,0x46);
	Write_DS1302(WRITE_HOUR,0x18);
	Write_DS1302(WRITE_DATE,0x13);
	Write_DS1302(WRITE_MONTH,4);
	Write_DS1302(WRITE_YEAR,0x19);
	Write_DS1302(WRITE_WEEK,6);
	Write_DS1302(0x80,0);			
 }
void Read_time()
{
	time[0]  =  Read_DS1302(0x81);
	time[1]	 =  Read_DS1302(0x83);
	time[2]	 =  Read_DS1302(0x85);
	time[3]	 =  Read_DS1302(0x87);
	time[4]	 =  Read_DS1302(0x89);
	time[5]	 =  Read_DS1302(0x8b);
	time[6]	 =  Read_DS1302(0x8d);

}
#endif

基于单片机的智能窗帘控制系统的设计与实现
单片机各模块设计脑图
时钟模块设计
时钟模块设计详细设计
光照感应模块
光照感应模块详细设计

猜你喜欢

转载自blog.csdn.net/qq_38173631/article/details/105600451