51单片机---DS1302时钟的使用(含源码)

19 篇文章 75 订阅
订阅专栏

   写在前面:本节我们学习了51单片机的DS1302的相关内容,包括原理,电路图,相关寄存器的设置以及时序;完成了利用LCD1602晶体管的结合,实现了时钟显示;如果只需代码,直接转至文末百度网盘

        在前面的定时器章节学习中,我们知道51单片机内部含有晶振,可以实现定时/计数功能,通过配置定时计数器的初值,可以实现时钟的功能;但是这种定时器计时存在一些缺陷,例如:精度不高、占用CPU时间,不能够掉电使用等等。本节我们学习51单片机开发的一个新模块--DS1302,利用DS1302实现多功能电子时钟,并将其显示在LCD1602以及晶体管表面。

   本节我们要实现的功能是:

1、LCD1602显示日期,时间;格式为:XX-XX-XX(年月日);XX:XX:XX(时分秒);

2、数码管上显示电子时钟时分秒,格式为 XX-XX-XX(时分秒)

一、DS1302时钟芯片 

1、 DS1302简介

         DS1302是一种低功耗实时时钟芯片,实时时钟计算年、月、日、时、分、秒、星期,直到 2100 年,并有闰年调节功能。每月的天数和闰年的天数可自动调整。时钟操作可通过 AM/PM 指示决定采用 24 或 12 小时格式。DS1302 与 单片机之间能简单地采用同步串行的方式进行通信,仅需用到三根通信线:1、CE使能线;2、I/O 数据线;3、SCLK 串行时钟线;

 上图为DS1302芯片的管脚定义,以及同CPU相连时的工作电路;其中管脚功能如下所示:

管脚名称功能
1VCC2双供电配置中的主电源供应管脚(单片机供电);
2X1DS1302 外部晶振引脚,通常需外接 32.768K 晶振;
3X2DS1302 外部晶振引脚,通常需外接 32.768K 晶振;
4GND电源地;
5CE使能引脚,也是复位引脚,CE信号在读写时必须保持高电平;
6I/O串行数据引脚,数据输出或者输入
7SCLK串行数据引脚
8VCC1备用电源

        在典型电路种,CPU与DS1302相连的为CE、SCLK以及I/O引脚;用于芯片的控制,X1\X2为外部 32.768kHz晶体.振荡电路工作时不需要任何外接的电阻或者电容。VCC1 连接备用电源,在VCC2连接主电源。 当 VCC2比 VCC1高 0.2V时,VCC2 给 DS1302供电.当 VCC1 比 VCC2高 时, VCC1给 DS1302供电.

2、DS1302使用

DS1302 有一个控制寄存器、12 个日历、时钟寄存器和 31 个 RAM。

2.1控制寄存器

        控制寄存器用于存放 DS1302 的控制命令字,DS1302 的CE引脚回到高电平后写入的第一个字节就为控制命令。它用于对 DS1302 读写过程进行控制,格式如下:

 上图是 DS1302 的寄存器样式,我们看到:

1、最高位一直为1;

2、第六位中,1表示RAM,寻址内部存储器;

                        0表示CK,寻址内部寄存器;

3、第五至第一位为RAM/CK相关的地址;

4、最低位,高电平1表示 RD,即下一步操作将要“读”;低电平0表示 W,即 下一步操作将要“写”。

2.2日历/时钟寄存器

下图为相关寄存器的读写地址,控制命令;即通过红色框中的地址,控制相关寄存器的读与写;

下图为相关寄存器的位说明: 

秒寄存器:低四位为秒的个位,高的次三位为秒的十位。最高位 CH 为 DS1302 的运行标志,当 CH=0 时,DS1302 内部时钟运行,反之 CH=1 时停止 ;

小时寄存器:时寄存器。最高位为 12/24 小时的格式选择位,该位为 1 时 表示 12 小时格式。当设置为 12 小时显示格式时,第 5 位的高电平表示下午 (PM);而当设置为 24 小时格式时,第 5 位位具体的时间数据;

写保护寄存器:当该寄存器最高位 WP 为 1 时,DS1302 只读不写,所以要在往 DS1302 写数据之前确保 WP 为0;

2.3BCD码

        在日历/时钟寄存器中都是以 BCD 码存放数据,那么 BCD 码是 什么呢?BCD 码是通过 4 位二进制码来表示 1 位十进制中的 0~9 这 10 个数码。 如下所示:

         所以,往相关寄存器中写入数据时先要转化为BCD码格式在进行写入;读取数据时,读到的是BCD码,使用时需要转化为相应的十进制或十六进制;

2.4读写时序

        我们前面说过,CPU与DS1302相连的线有三根,分别为:CE、SCLK以及I/O引脚;那么如何通过这三根线实现两者之间的数据转换呢?这就不得不提及到DS1302的三个时序:

            在控制指令字输入后的下一个 SCLK 时钟的上升沿时,数据被写入 DS1302,数据输入从低位(位 0)开始。同样,在紧跟 8 位的控制指令字后的下一个 SCLK 脉冲的下降沿读出 DS1302 的数据,读出数据时从低位 0 位到高位 7。完成单字节的读写;

1、CE:初始化后为低电平, 在整个读写器件,要保持高电平,一次字节读写完毕之后,在进行置低电平

2、单字节写入:在CE为高电平后,SCLK会输出周期脉冲,每一个上升沿,IO线的数据就会进入控制寄存器,当控制寄存器配置完成(为写入数据,并且地址已给),紧接着的脉冲IO线的数据就会在上升沿进入对应地址的寄存器;

3、单字节读出:在CE为高电平后,SCLK会输出周期脉冲,每一个上升沿,IO线的数据就会进入控制寄存器,当控制寄存器配置完成(为读出数据,并且地址已给),紧接着对应地址的寄存器的数据就会在下升沿进入IO线;

注: 要记得在操作 DS1302 之前关闭写保护;不然指令是无法进入控制寄存器的;

二、硬件设计

本次所涉及的硬件如下:

1、DS1302;2、LCD1602;3、动态数码管;

1、DS1302电路图

开发板上 DS1302 时钟模块电路图为:

从上图中可知,DS1302 芯片的控制管脚接至单片机 P3.4-P3.6;X1、X2 管脚处外接了一个 32.768KHZ 晶振,为时钟运行提供一个稳定的时钟频率,C2 和 C3 为旁路电容,目的是消除晶振起振时产生的电感干扰。对于本开发 板无外接备用电池,如果需要可自行将外部备用电源接入第 8 脚 VCC1。

2、LCD1602电路图

开发板上LCD1602 模块电路图为:

        LCD1602的管脚说明以及相关的使用方法在之前的博客中已经说明,如果需要学习了解的可以看看下面这篇博客!

CSDN

 3、晶体数码管电路图

开发板上晶体数码管模块电路图为:

        晶体数码管的管脚说明以及相关的使用方法在之前的博客中已经说明,如果需要学习了解的可以看看下面这篇博客! 

CSDN

 三者在开发板上的位置:

三、软件设计

1、LCD1602显示日期

功能描述:LCD1602显示日期,时间;格式为:XX-XX-XX(年月日);XX:XX:XX(时分秒);

源码

main.c

#include <REGX52.H>
#include "lcd1602.h"//包含LCD1602头文件
#include  "DS1302.h"//包含DS1302头文件
void main ()//定义主函数
{
	
		LCD_Init();	//LCD1602初始化
		DS1302_Init();//DS1302初始化
		LCD_ShowString(1,1,"  -  -  ");//设置年月日格式
		LCD_ShowString(2,1,"  :  :  ");//设置时分秒格式
		DS1302_SetTime();//设置时间,通过数组进行设置
	
		while(1)
		{
		  		DS1302_ReadTime();//读取内部时间
					LCD_ShowNumber(1,1,DS1302_Time[0],2);//显示年
					LCD_ShowNumber(1,4,DS1302_Time[1],2);//显示月
					LCD_ShowNumber(1,7,DS1302_Time[2],2);//显示日
					LCD_ShowNumber(2,1,DS1302_Time[3],2);//显示时
					LCD_ShowNumber(2,4,DS1302_Time[4],2);//显示分
					LCD_ShowNumber(2,7,DS1302_Time[5],2);//显示秒
					LCD_ShowNumber(2,13,DS1302_Time[6], 1);//显示星期
    	}
}

DS1302.h

#include  "DS1302.c"

extern unsigned char DS1302_Time[];//声明设置时间的数组
void  DS1302_Init();//声明初始化函数
void  DS1302_WriteBety(unsigned char command,Data);//声明单字节写入函数
unsigned char   DS1302_ReadBety(unsigned char command);//声明单字节读出函数
void DS1302_SetTime();//声明设置内部时间函数
void DS1302_ReadTime();//声明读取内部时间函数

 DS1302.c

#include <REGX52.H>

//引脚定义;
sbit  DS1302_SCLK=P3^6;
sbit  DS1302_IO=P3^4;
sbit  DS1302_CE=P3^5;

//对应寄存器位置定义
#define  DS1302_SECOND		0X80
#define  DS1302_MINUTE  	0X82
#define  DS1302_HOUR		0X84
#define  DS1302_DATE        0X86
#define  DS1302_MONTH		0X88
#define  DS1302_DAY         0X8A
#define  DS1302_YEAR        0X8C
#define  DS1302_WP          0X8E 

//定义数组,用于存放设定的时间,年月日时分秒星期
unsigned char DS1302_Time[]={23,10, 28,19,00,59,6};//顺序:年月日时分秒星期
/**
   *@breaf DS1302初始化
   *@param无
   *@retval无
   */
void  DS1302_Init()
{
	DS1302_CE=0;//将使能位置0,低电平;
	DS1302_SCLK=0;//将时钟位置0,低电平;
}

/**
   *@breaf DS1302单字节写入函数
   *@param command:写入控制指令的指令,包含要写入寄存器的地址;
	 *@param Data:将要写入的数据内容;
   *@retval 无
   */
void  DS1302_WriteBety(unsigned char command,Data)
{
			unsigned char i;
			DS1302_CE=1;//使能位置高电平;
			for(i=0;i<8;i++)//控制寄存器数据需要通过IO线一个一个写入控制寄存器;低位先写入
		{
				DS1302_IO=command&(0x01<<i);//相当于把第1--7位置0,只留第0位,如果第0位是0,则为0;反之则为1;
				DS1302_SCLK=1;
				DS1302_SCLK=0;
		}
		
				for(i=0;i<8;i++)//数据写入
		{
				DS1302_IO=Data&(0x01<<i);//相当于把第1--7位置0,只留第0位,如果第0位是0,则为0;反之则为1;
				DS1302_SCLK=1;
				DS1302_SCLK=0;
		}
			DS1302_CE=0;	
}

/**
   *@breaf  DS1302单字节读出函数
   *@param command:写入控制指令的指令,包含要读出寄存器的地址;
   *@retval Data:读出的数据;
   */
unsigned char   DS1302_ReadBety(unsigned char command)
{
	unsigned i,Data=0X00;
	    command|=0X01;//写入指令与读出指令只在最后一位相差1,故在此利用或运算消除;
			DS1302_CE=1;//使能位置高电平;
		for(i=0;i<8;i++)//控制寄存器数据需要通过IO线一个一个写入控制寄存器;低位先写入
		{
				DS1302_IO=command&(0x01<<i);//相当于把第1--7位置0,只留第0位,如果第0位是0,则为0;反之则为1;
				DS1302_SCLK=0;	
				DS1302_SCLK=1;
		}
				DS1302_IO=0;
			for(i=0;i<8;i++)//数据读出
		{
					DS1302_SCLK=1;
					DS1302_SCLK=0;			
					if(DS1302_IO)  
					{Data |=(0X01<<i);}
		}
		DS1302_CE=0;
		return Data;
}


/**
   *@breaf 向DS1302内设定时间
   *@param无
   *@retval无
   */
void DS1302_SetTime()
{
		DS1302_WriteBety(DS1302_WP,0x00);//操作 DS1302 之前,关闭写保护,不然指令无法进入控制寄存器;
		DS1302_WriteBety(DS1302_YEAR, DS1302_Time[0]/10*16+DS1302_Time[0]%10);//写入年,并将10进制转化BCD码;
		DS1302_WriteBety(DS1302_MONTH, DS1302_Time[1]/10*16+DS1302_Time[1]%10);//写入月,并将10进制转化BCD码;
		DS1302_WriteBety(DS1302_DATE, DS1302_Time[2]/10*16+DS1302_Time[2]%10);//写入日,并将10进制转化BCD码;
		DS1302_WriteBety(DS1302_HOUR, DS1302_Time[3]/10*16+DS1302_Time[3]%10);//写入时,并将10进制转化BCD码;
		DS1302_WriteBety(DS1302_MINUTE, DS1302_Time[4]/10*16+DS1302_Time[4]%10);//写入分,并将10进制转化BCD码;
		DS1302_WriteBety(DS1302_SECOND, DS1302_Time[5]/10*16+DS1302_Time[5]%10);//写入秒,并将10进制转化BCD码;
		DS1302_WriteBety(DS1302_DAY, DS1302_Time[6]/10*16+DS1302_Time[6]%10);//写入星期,并将10进制转化BCD码;
		DS1302_WriteBety( DS1302_WP,0x80);//写入结束,开启写保护;
}

/**
*@breaf 读取DS1302内时间
*@param无
*@retval无
*/
void DS1302_ReadTime()	
{
	unsigned char Temp;//定义变量,用于暂时存储BCD码
    Temp=DS1302_ReadBety(DS1302_YEAR);//读取年BCD码;
		DS1302_Time[0]=Temp/16*10+Temp%16;//BCD码转十进制;
	 Temp=DS1302_ReadBety(DS1302_MONTH);//读取月BCD码;
		DS1302_Time[1]=Temp/16*10+Temp%16;//BCD码转十进制;
	 Temp=DS1302_ReadBety(DS1302_DATE);//读取日BCD码;
		DS1302_Time[2]=Temp/16*10+Temp%16;//BCD码转十进制;
	 Temp=DS1302_ReadBety(DS1302_HOUR);//读取小时BCD码;
		DS1302_Time[3]=Temp/16*10+Temp%16;//BCD码转十进制;
	 Temp=DS1302_ReadBety(DS1302_MINUTE);//读取分钟BCD码;
		DS1302_Time[4]=Temp/16*10+Temp%16;//BCD码转十进制;
	 Temp=DS1302_ReadBety(DS1302_SECOND);//读取秒BCD码;
		DS1302_Time[5]=Temp/16*10+Temp%16;//BCD码转十进制;
	 Temp=DS1302_ReadBety(DS1302_DAY);//读取星期BCD码;
		DS1302_Time[6]=Temp/16*10+Temp%16;//BCD码转十进制;
}

LCD1602.h

#include "LCD1602.c" 

void LCD_Init();//声明初始化函数	
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String);//声明显示字符串函数
void LCD_ShowNumber(unsigned char Line,unsigned char Column,unsigned int  number,unsigned char length);//声明显示数字函数

LCD1602.c 

 #include <REGX52.H>	
	
		  //引脚配置:
sbit LCD_RS=P2^6;	//   RS引脚为数据/指令选择   1为数据,0为指令
sbit LCD_RW=P2^5;	//   RW引脚为读/写选择       1为读,0为写
sbit LCD_EN=P2^7;	//   EN引脚为使能            1为数据有效,下降沿执行命令
#define LCD_DataPort P0	 //定义P0引脚为数据端口



 //延迟函数的定义;LCD1602延时函数,12MHz调用可延时xms;
void LCD_Delay(unsigned int xms)		//@12.000MHz
{
	unsigned char i, j;

   while(xms--)
   {
	i = 2;
	j = 239;
	do
	{
		while (--j);
	} while (--i);
	}
}


//写指令函数定义:  LCD1602写指令函数
void LCD_WriteCommand(unsigned char Command)
{
	LCD_RS=0;//选择为指令,1为数据,0为指令
	LCD_RW=0;//选择为写, 1为读,0为写
	LCD_DataPort=Command;//写入指令的内容
	LCD_EN=1;	  //使能脚E先上升沿写入
	LCD_Delay(1);
	LCD_EN=0;	 //使能脚E后负跳变完成写入
	LCD_Delay(1);
}



// 写数据函数定义:  LCD1602写数据函数
void LCD_WriteData(unsigned char Data)
{
	LCD_RS=1; //选择为数据,1为数据,0为指令
	LCD_RW=0; //选择为写, 1为读,0为写
	LCD_DataPort=Data;//写入指数据的内容
	LCD_EN=1;	 //使能脚E先上升沿写入
	LCD_Delay(1);
	LCD_EN=0;  	 //使能脚E后负跳变完成写入
	LCD_Delay(1);
}


 //初始化函数定义:	LCD1602屏幕初始化
void LCD_Init()
{
	LCD_WriteCommand(0x38);//八位数据接口,两行显示,5*7点阵
	LCD_WriteCommand(0x0c);//显示开,光标关,闪烁关
	LCD_WriteCommand(0x06);//数据读写操作后,光标自动加一,画面不动
	LCD_WriteCommand(0x01);//光标复位,清屏
}


 //LCD1602 进行清屏
 void LCD_clear()
 {
 		LCD_WriteCommand(0x01);
 }
 
//设置光标位置
void LCD_SetCursor(unsigned char Line,unsigned char Column)//(行数1-2,列数1-16)
{
	if(Line==1)
	{
		LCD_WriteCommand(0x80|(Column-1));
	}
	else if(Line==2)
	{
		LCD_WriteCommand(0x80|(Column-1+0x40));
	}
}



 //  字符串函数定义:   LCD1602显示字符串
  void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)//(行数1-2,列数1-16)

{
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=0;String[i]!='\0';i++)
	{
		LCD_WriteData(String[i]);

	}
}



//  字符数字函数定义:   LCD1602显示数字


int Pow(int x,int y)
{
	unsigned char i;
	int result = 1;
	for(i = 0; i < y; i++)
	{
		result *= x;
	}
	return result;
}

  void LCD_ShowNumber(unsigned char Line,unsigned char Column,unsigned int  number,unsigned char length)
{
	unsigned char i;
	unsigned char temp;
	LCD_SetCursor(Line,Column);
	for(i =length ; i > 0 ; i--)
	{
		temp = number/Pow(10,i-1)%10 + '0';	//循环将每一位都提取出来并转换为字符
		LCD_WriteData(temp);
	}
}

实验现象

DS1302利用LCD1602显示时钟

2、数码管上显示时分秒

功能说明:数码管上显示电子时钟时分秒,格式为 XX-XX-XX(时分秒);

源码

main.c

#include <REGX52.H>
#include  "DS1302.h"
#include <intrins.h>
unsigned char time[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//定义数码管上0-f  16位数字的段选码
 unsigned char time_buf[7]={0};//定义数码管对应位
 /**
 *@breaf 延时函数/@11.0592MHz  1ms为单位
 *@para   t 延时时间设置
 *@retval无
 */
void Delay1ms(unsigned char t)		//@11.0592MHz
{
	unsigned char i, j;
while(t--)
	{
	_nop_();
	i = 2;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
}
}
/**
*@breaf 数码管显示函数
*@para  显示的段选数据 数组
*@retval无
*/
void smg_display(unsigned char dat[])
{
	unsigned char i=0;
	for(i=0;i<8;i++)//扫描
	{
	   	switch(i)//位选
		{
		case 0:	P2_4=1;	P2_3=1;	P2_2=1;break;
		case 1:	P2_4=1;	P2_3=1;	P2_2=0;break;
		case 2:	P2_4=1;	P2_3=0;	P2_2=1;break;
		case 3:	P2_4=1;	P2_3=0;	P2_2=0;break;
		case 4:	P2_4=0;	P2_3=1;	P2_2=1;break;
		case 5:	P2_4=0;	P2_3=1;	P2_2=0;break;
		case 6:	P2_4=0;	P2_3=0;	P2_2=1;break;
		case 7:	P2_4=0;	P2_3=0;	P2_2=0;break; 
		}
			P0=dat[i];//传送段选数据
		Delay1ms(1)	;//延时一段时间,等待显示稳定
		P0=0x00;//消音
	}
}


void main ()
{	
		DS1302_Init();//DS1302初始化
		DS1302_SetTime();//	DS1302设置时间
		while(1)
		{
		  		DS1302_ReadTime();//DS1302读取时间,读取值为BCD码
					time_buf[0]= time[DS1302_Time[3]/16];//将BCD码转为十进制,并且在数组中找到对应十进制的段选码;小时第一位;
					time_buf[1]= time[DS1302_Time[3]&0x0f];//将BCD码转为十进制,并且在数组中找到对应十进制的段选码;小时的第二位;
					time_buf[2]=0x40;//格式控制-;
					time_buf[3]= time[DS1302_Time[4]/16];//将BCD码转为十进制,并且在数组中找到对应十进制的段选码;分钟的第一位;
					time_buf[4]= time[DS1302_Time[4]&0x0f];//将BCD码转为十进制,并且在数组中找到对应十进制的段选码;分钟的第二位;
					time_buf[5]=0x40;//格式控制-;
					time_buf[6]= time[DS1302_Time[5]/16];//将BCD码转为十进制,并且在数组中找到对应十进制的段选码;秒的第一位;
					time_buf[7]= time[DS1302_Time[5]&0x0f];//将BCD码转为十进制,并且在数组中找到对应十进制的段选码;秒的第二位;
						smg_display(time_buf);//将时间信息传递给数码管显示函数
    	}
}

	
	
	

DS1302.c

#include <REGX52.H>

//引脚定义;
sbit  DS1302_SCLK=P3^6;
sbit  DS1302_IO=P3^4;
sbit  DS1302_CE=P3^5;

//对应寄存器位置定义
#define  DS1302_SECOND		0X80
#define  DS1302_MINUTE  	0X82
#define  DS1302_HOUR	    0X84
#define  DS1302_DATE	    0X86
#define  DS1302_MONTH       0X88
#define  DS1302_DAY         0X8A
#define  DS1302_YEAR        0X8C
#define  DS1302_WP          0X8E 

//定义数组,用于存放设定的时间,年月日时分秒星期
unsigned char DS1302_Time[]={23,10,28,19,01,55,6};//顺序:年月日时分秒星期
/**
*@breaf DS1302初始化
*@param无
*@retval无
*/
void  DS1302_Init()
{
	DS1302_CE = 0; // 将使能位置0,低电平;
	DS1302_SCLK=0;//将时钟位置0,低电平;
}


/**
*@breaf DS1302单字节写入函数
*@param command:写入控制指令的指令,包含要写入寄存器的地址;
*@param Data:将要写入的数据内容;
*@retval 无
*/
void  DS1302_WriteBety(unsigned char command, Data)
{
	unsigned char i;
	DS1302_CE = 1;//使能位置高电平;
	for (i = 0; i<8; i++)//控制寄存器数据需要通过IO线一个一个写入控制寄存器;低位先写入
	{
		DS1302_IO = command&(0x01 << i);//相当于把第1--7位置0,只留第0位,如果第0位是0,则为0;反之则为1;
		DS1302_SCLK = 1;
		DS1302_SCLK = 0;
	}

	for (i = 0; i<8; i++)//数据写入
	{
		DS1302_IO = Data&(0x01 << i);//相当于把第1--7位置0,只留第0位,如果第0位是0,则为0;反之则为1;
		DS1302_SCLK = 1;
		DS1302_SCLK = 0;
	}
	DS1302_CE = 0;
}

/**
*@breaf  DS1302单字节读出函数
*@param command:写入控制指令的指令,包含要读出寄存器的地址;
*@retval Data:读出的数据;
*/
unsigned char   DS1302_ReadBety(unsigned char command)
{
	unsigned i, Data = 0X00;
	command |= 0X01;//写入指令与读出指令只在最后一位相差1,故在此利用或运算消除;
	DS1302_CE = 1;//使能位置高电平;
	for (i = 0; i<8; i++)//控制寄存器数据需要通过IO线一个一个写入控制寄存器;低位先写入
	{
		DS1302_IO = command&(0x01 << i);//相当于把第1--7位置0,只留第0位,如果第0位是0,则为0;反之则为1;
		DS1302_SCLK = 0;
		DS1302_SCLK = 1;
	}
	DS1302_IO = 0;
	for (i = 0; i<8; i++)//数据读出
	{
		DS1302_SCLK = 1;
		DS1302_SCLK = 0;
		if (DS1302_IO)
		{
			Data |= (0X01 << i);
		}
	}
	DS1302_CE = 0;
	return Data;
}



/**
*@breaf 向DS1302内设定时间
*@param无
*@retval无
*/
void DS1302_SetTime()
{
	DS1302_WriteBety(DS1302_WP, 0x00);//操作 DS1302 之前,关闭写保护,不然指令无法进入控制寄存器;
	DS1302_WriteBety(DS1302_YEAR, DS1302_Time[0] / 10 * 16 + DS1302_Time[0] % 10);//写入年,并将10进制转化BCD码;
	DS1302_WriteBety(DS1302_MONTH, DS1302_Time[1] / 10 * 16 + DS1302_Time[1] % 10);//写入月,并将10进制转化BCD码;
	DS1302_WriteBety(DS1302_DATE, DS1302_Time[2] / 10 * 16 + DS1302_Time[2] % 10);//写入日,并将10进制转化BCD码;
	DS1302_WriteBety(DS1302_HOUR, DS1302_Time[3] / 10 * 16 + DS1302_Time[3] % 10);//写入时,并将10进制转化BCD码;
	DS1302_WriteBety(DS1302_MINUTE, DS1302_Time[4] / 10 * 16 + DS1302_Time[4] % 10);//写入分,并将10进制转化BCD码;
	DS1302_WriteBety(DS1302_SECOND, DS1302_Time[5] / 10 * 16 + DS1302_Time[5] % 10);//写入秒,并将10进制转化BCD码;
	DS1302_WriteBety(DS1302_DAY, DS1302_Time[6] / 10 * 16 + DS1302_Time[6] % 10);//写入星期,并将10进制转化BCD码;
	DS1302_WriteBety(DS1302_WP, 0x80);//写入结束,开启写保护;
}

/**
*@breaf 读取DS1302内时间
*@param无
*@retval无
*/void DS1302_ReadTime()
{
 
		DS1302_Time[3] = DS1302_ReadBety(DS1302_HOUR);//读取小时BCD码;
		DS1302_Time[4]=DS1302_ReadBety(DS1302_MINUTE);//读取分钟BCD码;
		DS1302_Time[5]=DS1302_ReadBety(DS1302_SECOND);//读取秒BCD码;
	 
}

DS1302.h

#include  "DS1302.c"

extern unsigned char DS1302_Time[];//声明设置时间的数组
void  DS1302_Init();//声明初始化函数
void  DS1302_WriteBety(unsigned char command, Data);//声明单字节写入函数
unsigned char   DS1302_ReadBety(unsigned char command);//声明单字节读出函数
void DS1302_SetTime();//声明设置内部时间函数
void DS1302_ReadTime();//声明读取内部时间函数

实验现象:

DS1302利用晶体管显示时间

链接:https://pan.baidu.com/s/1Nt9IB02q5x_c25f7aXXTCg 
提取码:1022

总结:本节我们学习了51单片机的DS1302的相关内容,包括原理,电路图,相关寄存器的设置以及时序;完成了利用LCD1602与晶体管的结合,实现了时钟显示;读者看完后一定一定要多加练习,才能更好的掌握;

创作不易,还请大家多多点赞支持!!!

51单片机DS1302实时时钟驱动程序
Line
12-12 2万+
低功耗实时时钟芯片,它可以对年、月、日、周、时、分、秒进行计时,且具有闰年补偿等多种功能。 主要特点是采用串行数据传输,可为掉电保护电源提供可编程的充电功能,并且可以关闭充电功能。
DS1302时钟芯片介绍及使用教程
m0_60790717的博客
08-09 6343
DS1302 涓流充电计时芯片包一个实时时钟/日历和 31 字节的静态 RAM.通过简单的串行接口与微处理器通讯.这个实时时钟/日历提供年月日,时分秒信息.对于少于 31 天的月份月末会自动调整,还有闰年校正.由于有一个 AM/PM 指示器,时钟可以工作在 12 小时制或者24小时制。......
RTC实时时钟DS1302Z读写实验例程 cyclone2 FPGA实验Verilog源码Quartus9.0工程
04-19
RTC实时时钟[DS1302Z]读写实验例程 cyclone2 FPGA实验Verilog源码Quartus9.0工程文件 DS1302_APP I_DS1302_APP ( .RST_B (RST_B ), .SYSCLK (SYSCLK ), .RTC_RST (RTC_RST ), .RTC_CLK (RTC_CLK ), .RTC_IO (RTC_IO ), .TUBE_SEL (TUBE_SEL ), .TUBE_DATA (TUBE_DATA ) ); //Clock always #10 SYSCLK = ~ SYSCLK; initial begin #0 SYSCLK = 0; RST_B = 0; #35 RST_B = 1; end endmodule
51单片机DS1302时钟完整源程序
02-07
51单片机DS1302时钟完整源程序,给需要的人参考一下哈,好的话多多支持哈
DS1302时钟芯片全解析——概况,性能,MCU连接,样例代码
最新发布
Dunkle.T的博客
07-29 1651
DS1302时钟芯片全解析——概况,性能,MCU连接,样例代码
51单片机系列】DS1302时钟模块
sinat_41752325的博客
12-26 2285
DS1302是DALLAS公司推出的涓流充电时钟芯片,内部有一个实时时钟/日历和31字节静态RAM,通过简单的串行接口与单片机进行通信。该芯片是3线SPI接口。实时时钟/日历电路提供秒、分、时、日、周、月、年的信息,每月的天数和闰年的天数可以自动调整。时钟操作通过AM/PM只是决定采用24或12小时格式。DS1302单片机之间能简单地采用同步串行的方式进行通信,仅需要用到三根通信线:① RES复位;② I/O数据线;③ SCLK串行时钟
DS1302实时时钟芯片完整使用介绍(配合51单片机)
06-19 1284
DS1302是一款由美国DALLAS Semiconductor公司(现已被Maxim Integrated公司收购)设计的高性能、低功耗的实时时钟集成电路。这款芯片因其简单易用的接口和丰富的功能,在嵌入式系统、消费电子、工业控制等多个领域得到广泛应用。
51单片机--DS1302时钟
m0_74068921的博客
07-16 2973
这是51单片机上的DS1302芯片;左上图是两种不同的封装工艺方式,DIP封装也叫双列直插式封装技术,是一种最简单的封装方式;SOP封装是一种元件封装形式,一般封装材料较多样:塑料、陶瓷、玻璃、金属等;现在普遍使用塑料封装;主要应用于各种集成电路中。在我们的STC89C52单片机上就是用SOP的封装方式;它在单片机上有8个引脚VCC为电源,其中VCC1为备用电池,也就是主电源断电时,由备用电池供电,但需要注意的是,在该款单片机上并没有备用电池;且VCC2才是主电源,不能于备用电池弄反了;
51单片机DS1302
weixin_69561921的博客
07-04 1795
DS1302是一种RTC(Real Time Clock)实时时钟芯片,由美国DALLAS公司推出的具有涓细电流充电能力的低功耗实时时钟芯片。它可以对年、月、日、周、时、分、秒进行计时,且具有闰年补偿等多种功能。数字信号可以分配格式地输出显示到LCD1602上。
DS1302时钟模块
hushichuanren的博客
01-13 3696
需要注意的是数据字节为两位BDS编码(两位BDS编码说明DS1302只能输出两位数,最大为99,若要显示年份只能显示后两位),八个字节被分为前后各四个,前四个表示十位,后四个表示个位,当个位二进制对应的值等于10时需要向前四位进1,例如 当 0000 1001(十进制为9)加一后变为 0001 0000,0001 0000 在十进制中表示16,但在BDS码中其表示10。左列自上往下对应的分别对应秒、分、时、日、月、星期、年和读保护,其对应的模式为从DS1302中读出相应数据并送至IO口。
51单片机DS1302数字时钟
weixin_34306446的博客
03-21 389
2019独角兽企业重金招聘Python工程师标准>>> ...
51单片机时钟小程序
09-13
51单片机时钟程序代码,内51单片机时钟程序代码
51单片机源码程序-DS1302时钟串口自动更新时间.zip
05-11
51单片机源码程序
基于ds130251单片机电子时钟
05-22
基于ds1302的记忆时钟,具有闹钟功能,同时可改成控制继电器,同时配有proteus电路图
基于51单片机-实时时钟芯片DS1302软件程序源码+Proteus仿真实例+文档资料.zip
05-05
基于51单片机-实时时钟芯片DS1302软件程序源码+Proteus仿真实例+文档资料 void get_time()//获取1302的时间数据(时、分、秒),存入time1数组中 { uchar d;//变量 d=read1302(0x81);//从1302的秒的地址储存器(0x...
单片机源码-VB上位机程序控制DS1302时钟系统(proteus仿真文件+程序).zip
07-28
在这个项目中,可能使用的是一款常见的8位或16位单片机,如8051系列或其他兼容型号,用于实现DS1302时钟的控制逻辑。 2. **DS1302时钟芯片**:DS1302是一款实时时钟(RTC)芯片,能够保持精确的时间,即使在主电源...
单片机-DS1302时钟源码
01-04
总的来说,"单片机-DS1302时钟源码"涉及的知识点包括:DS1302的硬件特性、SPI通信协议、单片机的IO操作、BCD编码、时序控制、异常处理和电源管理。了解并掌握这些知识点,能帮助开发者在单片机项目中实现精准的时间...
单片机源码学习参考-1602液晶显示DS1302时钟.zip
03-22
在这个“单片机源码学习参考-1602液晶显示DS1302时钟.zip”压缩包中,我们可以看到一个实例项目,它将1602液晶显示器与DS1302实时时钟芯片相结合,为初学者提供了一个很好的实践平台。下面我们将详细探讨这个项目中...
DS1302时钟 ---- 自学笔记
RONG_YAO的博客
05-16 5142
一、什么是DS1302时钟 具有实时时钟计算能力,能计算2100年之前的秒、分、时、日、日期、星期、月、年及闰年调整能力。 内部有31个字节静态RAM,可提供用户访问。 采用串行数据传送方式,使得管脚数量最少,简单SPI3线接口。 工作电压范围宽:2.0~5.5V。 工作电流:2.0v时,小于300NA。 时钟或RAM数据的读/写有两种传送方式:单字节传送和多字节传送方式 采用8脚DIP封装或SOIC封装。 与TTL兼容,Vcc=5v 可选工业级温度范围:-40摄氏度~+85摄氏度 具
105-1602液晶显示ds1302时钟单片机课程设计
12-07
105-1602液晶显示DS1302时钟单片机课程设计是一个关于数码时钟的项目。该项目使用105-1602液晶显示屏和DS1302时钟芯片,结合单片机进行设计。 这个课程设计旨在让学生通过实际操作了解液晶显示和时钟芯片的原理及应用。在课程设计中,学生需要学习并理解液晶显示屏的工作原理和驱动方式,以及DS1302时钟芯片的基本功能与接口。 在设计过程中,学生需要先通过单片机控制液晶显示屏,实现基本的字符显示和显示信息刷新。接着,学生需要将DS1302时钟芯片与单片机相连,实现对时钟芯片的初始化和读取实时时钟的功能。 除了基本的时间显示功能外,学生还可以进行课程设计的扩展。例如,学生可以添加设置时间的功能,让用户可以通过按键来设置时间。另外,还可以添加闹钟、定时功能等,使得时钟的功能更加实用和多样化。 通过这个课程设计,学生不仅可以提高对液晶显示和时钟芯片的理论理解,还能通过实际操作培养动手能力和解决问题的能力。此外,学生还可以通过设计时钟的外壳和装饰,体验到工程设计的乐趣。 总而言之,105-1602液晶显示DS1302时钟单片机课程设计提供了一个综合运用液晶显示和时钟芯片的机会,让学生通过实际操作加深理解,并提高相关技能。这个课程设计不仅有助于学生的学习,还能培养学生的创新意识和实践能力。
写文章

热门文章

  • WiFi模块ESP8266(超详细)---(含固件库、AP、STA、原子云使用) 97685
  • STM32--中断使用(超详细!) 43332
  • 51单片机---DS1302时钟的使用(含源码) 35160
  • 51单片机---超声波测距(HC-SR04) 21241
  • STM32--GPIO点亮LED灯(手把手,超详细) 19560

分类专栏

  • STM32 21篇
  • 数据结构与算法 7篇
  • 51单片机 19篇
  • Linux应用 12篇
  • RT-Thread 2篇
  • C语言 9篇
  • 问题汇总 1篇
  • 汇编语言 1篇

最新评论

  • WiFi模块ESP8266(超详细)---(含固件库、AP、STA、原子云使用)

    xixixixi1723: 解决啦博主,真的很感激您的分享!

  • 代码随想录算法训练营第七天|LeetCode 334.反转字符串、541反转字符串II、151反转字符串中的单词

    King~30+: 入门算法难,进门后就不知道了。

  • WiFi模块ESP8266(超详细)---(含固件库、AP、STA、原子云使用)

    xixixixi1723: 博主您好,想问一下“flash_download_tool”软件上面读取不到端口是啥情况啊表情包

  • 代码随想录算法训练营第七天|LeetCode 334.反转字符串、541反转字符串II、151反转字符串中的单词

    念兮兮: 算法难学,还是单片机难学表情包

  • 51单片机---红外遥控(含源码)

    清华预备役大学生: 太棒了 感谢感谢

最新文章

  • 代码随想录算法训练营第七天|LeetCode 334.反转字符串、541反转字符串II、151反转字符串中的单词
  • 代码随想录算法训练营第一天|LeetCode 704. 二分查找、 27. 移除元素、977.有序数组的平方
  • 代码随想录算法训练营第三天|LeetCode 203.移除链表元素、707.设计链表、206.反转链表
2024年35篇
2023年43篇

目录

目录

评论 41
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

玻璃钢生产厂家玻璃钢雕塑坏了可以修吗山东特色玻璃钢雕塑图片贵州商场美陈制作商场玻璃钢雕塑施工方案浙江特色商场美陈销售丽水玻璃钢海豚雕塑玻璃钢骆驼雕塑联系方式小熊猫玻璃钢卡通雕塑现货灵璧县玻璃钢小品雕塑商场美陈节点玻璃钢雕塑一平方用多少材料日照玻璃钢雕塑联系方式吉林环保玻璃钢雕塑上海知名玻璃钢雕塑推荐厂家河北玻璃钢卡通雕塑厂家供应玻璃钢苹果雕塑江西酒店玻璃钢造型景观雕塑制作北京供应玻璃钢造型雕塑玻璃钢日漫形象雕塑陕西景区玻璃钢雕塑联系方式河源玻璃钢马雕塑漳州玻璃钢仿铜雕塑定制天水抽象人物玻璃钢雕塑订做敦化玻璃钢雕塑制作延边雕塑玻璃钢卡通通州玻璃钢雕塑厂商销售铜陵玻璃钢花盆花器平顶山玻璃钢现代雕塑岑溪玻璃钢长颈雕塑蚌埠玻璃钢雕塑价格香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化